摘要:前言為了鞏固開發(fā)的流程,我們再拿一個客戶關(guān)系管理系統(tǒng)來練手成果圖我們完成的就是下面的項(xiàng)目搭建配置環(huán)境配置導(dǎo)入開發(fā)包建立開發(fā)用到的程序包在數(shù)據(jù)庫創(chuàng)建相對應(yīng)的表開發(fā)實(shí)體開發(fā)實(shí)體十分簡單,對照著數(shù)據(jù)庫的表就行了各種開發(fā)獲取數(shù)據(jù)庫連接池的導(dǎo)入配置文
前言
為了鞏固開發(fā)的流程,我們再拿一個客戶關(guān)系管理系統(tǒng)來練手...!成果圖
我們完成的就是下面的項(xiàng)目!
搭建配置環(huán)境配置Tomcat
導(dǎo)入開發(fā)包
建立開發(fā)用到的程序包
在數(shù)據(jù)庫創(chuàng)建相對應(yīng)的表
CREATE TABLE customer ( id VARCHAR(40) PRIMARY KEY, name VARCHAR(20) NOT NULL, gender VARCHAR(10) NOT NULL, birthday DATE, cellphone VARCHAR(30) NOT NULL, email VARCHAR(30), preference VARCHAR(200), type VARCHAR(20), description VARCHAR(255) );開發(fā)實(shí)體
開發(fā)實(shí)體十分簡單,對照著數(shù)據(jù)庫的表就行了!
private String id; private String name ; private String gender ; private Date birthday ; private String cellphone ; private String eamil ; private String preference ; private String type ; private String description; //....各種setter、getter開發(fā)獲取數(shù)據(jù)庫連接池的Utils 導(dǎo)入配置文件
開發(fā)提供數(shù)據(jù)連接池的工具類com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/zhongfucheng root root 5 10 5 20 com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/zhongfucheng root root 5 10 5 20 oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@//localhost:1521/事例名... 用戶名 密碼 5 10 5 20
public class Utils2DB { private static ComboPooledDataSource comboPooledDataSource = null; static { //它會自動尋找配置文件,節(jié)點(diǎn)為mysql的數(shù)據(jù)庫(默認(rèn)就是Mysql) comboPooledDataSource = new ComboPooledDataSource(); } public static DataSource getDataSource() { return comboPooledDataSource ; } public static Connection connection() { try { return comboPooledDataSource.getConnection(); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException("數(shù)據(jù)庫初始化失敗了!"); } } }開發(fā)UUID工具類
public class WebUtils { public static String makeId() { return UUID.randomUUID().toString(); } }開發(fā)DAO
DAO應(yīng)該提供增加客戶和查詢用戶的功能
增加用戶public void addCustomer(Customer customer) { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "INSERT INTO customer (id,name, gender, birthday, cellphone, preference, type, description) VALUES (?, ?, ?, ?, ?, ?, ?, ?,?)"; //得到用戶傳遞進(jìn)來的數(shù)據(jù) String id = customer.getId(); String name = customer.getName(); String gender = customer.getGender(); String cellphone = customer.getCellphone(); String email = customer.getEmail(); String preference = customer.getPreference(); String type = customer.getType(); String description = customer.getDescription(); //對于日期,要轉(zhuǎn)換一下 Date date = customer.getBirthday(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); String birthday = simpleDateFormat.format(date); try { //向數(shù)據(jù)庫插入數(shù)據(jù) queryRunner.update(sql, new Object[]{id, name, gender, birthday, cellphone, email, preference, type, description}); //插入記錄成功! } catch (SQLException e) { //如果出現(xiàn)了異常,就拋出Dao異常吧(自定義的異常) e.printStackTrace(); throw new DaoException("添加用戶出錯了!"); } }測試增加用戶
寫完一個功能,不要急著去寫其他的功能,先測試一下!
@Test public void add() { //為了測試的方便,直接使用構(gòu)造函數(shù)了! Customer customer = new Customer("1", "zhongfucheng", "男", new Date(), "1234", "[email protected]", "打代碼", "高貴的用戶", "我是個好人"); CustomerDao customerDao = new CustomerDao(); customerDao.addCustomer(customer); }
好的,沒有報錯!再看看數(shù)據(jù)庫-----------只要是中文的數(shù)據(jù),都亂碼了!
解決的辦法,看我另外一篇博文:https://zhongfucheng.bitcron....
查詢用戶將所有的客戶查詢出來就行了!
//得到所有的用戶 public List測試查詢用戶getAll() { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "SELECT * FROM customer"; try { List customers = (List ) queryRunner.query(sql, new BeanListHandler(Customer.class)); //如果集合大于個數(shù)大于0,就返回集合,不大于0,就返回null return customers.size() > 0 ? customers : null; } catch (SQLException e) { e.printStackTrace(); throw new DaoException("獲取所有的用戶出錯了!"); } }
@Test public void find() { CustomerDao customerDao = new CustomerDao(); List修改用戶信息customers = customerDao.getAll(); for (Customer customer : customers) { System.out.println(customer.getName()); } }
修改用戶信息首先要知道用戶的信息,在web端,只有id能唯一標(biāo)識用戶,我們需要通過id,獲取用戶全部信息(也就是Customer對象)
public Customer find(String id) { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "SELECT * FROM customer WHERE id = ?"; try { Customer customer = (Customer) queryRunner.query(sql, new BeanHandler(Customer.class), new Object[]{id}); return customer; } catch (SQLException e) { e.printStackTrace(); throw new DaoException("查找用戶失敗了"); } }
修改用戶都是外邊傳遞個對象進(jìn)來,Dao層取出對象的數(shù)據(jù),從而對數(shù)據(jù)庫的數(shù)據(jù)進(jìn)行修改!
public void update(Customer customer) { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "UPDATE customer set name=?,gender=?,birthday=?,cellphone=?,email=?,preference=?,type=?,description=? WHERE id = ?"; try { queryRunner.update(sql, new Object[]{customer.getName(), customer.getGender(), customer.getBirthday(),customer.getCellphone(), customer.getEmail(), customer.getPreference(), customer.getType(), customer.getDescription(), customer.getId()}); } catch (SQLException e) { e.printStackTrace(); throw new DaoException("更新失敗"); } }測試修改用戶
@Test public void update() { CustomerDao customerDao = new CustomerDao(); //我們已經(jīng)知道了某id,通過id獲取得到用戶信息(Customer) String id = "043f7cce-c6f1-4155-b688-ba386cae1636"; Customer customer = customerDao.find(id); //修改用戶信息 customer.setName("看完博客要點(diǎn)贊"); customerDao.update(customer); }
原來該用戶的名字是d
測試完之后:
刪除用戶通過外界傳遞進(jìn)來的id,就可以刪除數(shù)據(jù)庫表中的記錄了
public void delete(String id) { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "DELETE from customer WHERE id = ?"; try { queryRunner.update(sql, new Object[]{id}); } catch (SQLException e) { e.printStackTrace(); throw new DaoException("刪除用戶失敗了"); } }測試刪除用戶
@Test public void delete() { CustomerDao customerDao = new CustomerDao(); //我們已經(jīng)知道了某id,通過id刪除數(shù)據(jù)庫中的記錄 String id = "043f7cce-c6f1-4155-b688-ba386cae1636"; customerDao.delete(id); }
數(shù)據(jù)庫已經(jīng)查詢不到id為043f7cce-c6f1-4155-b688-ba386cae1636的記錄了!
開發(fā)servicepublic class BusinessService { CustomerDao customerDao = new CustomerDao(); public List開發(fā)web 的增加和查詢 提供UI,增加客戶的ServletgetAll() { return customerDao.getAll(); } public void addCustomer(Customer customer) { customerDao.addCustomer(customer); } public void deleteCustomer(String id) { customerDao.delete(id); } public void updateCustomer(Customer customer) { customerDao.update(customer); } public Customer findCustomer(String id) { return customerDao.find(id); } }
//直接跳轉(zhuǎn)到顯示增加用戶頁面的jsp request.getRequestDispatcher("/WEB-INF/addCustomer.jsp").forward(request, response);開發(fā)顯示添加客戶頁面
效果是這樣子的
我們發(fā)現(xiàn),在日期的下拉框中,只有一個數(shù)據(jù)(因?yàn)槲覀冊趘alue中只寫了一個數(shù)據(jù))
要想在下拉框中可以選擇很多的數(shù)據(jù),那么value的值就不能單單只有一個。當(dāng)然了,也不可能在JSP頁面中寫下面的代碼
我們用javaScript生成下拉框的數(shù)據(jù)就行了??!
獲取年份!
function makeYear() { //得到下拉框的控件 var year = document.getElementById("year"); //要想下拉框有更多的數(shù)據(jù),就需要有更多的option控件 //js獲取得到年份是getFullYear(),單單的getYear()只是獲取兩位數(shù) for (var i=1901; i<= new Date().getFullYear(); i++) { //生成option控件 var option = document.createElement("option"); //option控件的值和文本內(nèi)容為循環(huán)生成的年分! option.value = i; option.innerText = i; //將生成option控件綁定到select控件上 year.appendChild(option); } }
獲取月份和日也類似
function makeMonth() { var month = document.getElementById("month"); for (var i = 2; i <= 12; i++) { var option = document.createElement("option"); if (i < 10) { option.value = "0" + i; option.innerText = "0" + i; } else { option.value = i; option.innerText = i; } month.appendChild(option); } } function makeDay() { var day = document.getElementById("day"); for(var i=2;i<=12;i++) { var option = document.createElement("option"); if(i<10) { option.value = "0" + i; option.innerText = "0" + i; }else{ option.value = i; option.innerText = i; } day.appendChild(option); } }
在JSP頁面中導(dǎo)入javascript文件
注意:javasrcipt文件不能放在WEB-INF下面?。。?!否則是獲取不到的?。?!
這三個函數(shù)都是在頁面加載時就應(yīng)該被初始化了,所以在body上綁定onload時間即可??!
function pageInit() { makeYear(); makeMonth(); makeDay(); }
效果:
JavaScript拼湊數(shù)據(jù)表單的數(shù)據(jù)非常多,毫無疑問,我們會使用BeanUtils來將數(shù)據(jù)封裝到Bean對象中!
對于表單的數(shù)據(jù),還是有些雜亂的。表單中日期的年月日是分開的,我們要么在客戶端將年月日的數(shù)據(jù)拼湊起來,要么在服務(wù)器端將年月日拼湊起來!同理,客戶的喜好可能不單單有一個,但在Customer對象中,喜好單單用一個String類型來表示的。我們也要把客戶的喜好拼湊起來。
顯然,在客戶端用javaScript做拼湊是非常方便的!
function makeBirthday() { //獲取下拉框的數(shù)據(jù),把數(shù)據(jù)拼湊成日期字符串 var year = document.getElementById("year"); var month = document.getElementById("month"); var day = document.getElementById("day"); var birthday = year + "-" + month + "-" + day; //想要將拼湊完的字符串提交給服務(wù)器,用隱藏域就行了 var input = document.createElement("input"); input.type = "hidden"; input.value = birthday; input.name = "birthday"; //將隱藏域綁定在form下【為了方便,在form中設(shè)置id,id名字為form】 document.getElementById("form").appendChild(input); } function makePreference() { //獲取喜好的控件 var hobbies = document.getElementsByName("hobbies"); //定義變量,記住用戶選中的選項(xiàng) var preference = ""; //遍歷喜好的控件,看用戶選上了什么! for (var i = 0; i < hobbies.length; i++) { if (hobbies[i].checked == true) { preference += hobbies[i].value + ","; } } //剛才拼湊的時候,最后一個逗號是多余的,我們要把它去掉 preference = preference.substr(0, preference.length - 1); //也是用隱藏域?qū)?shù)據(jù)帶過去給服務(wù)器 var input = document.createElement("input"); input.type = "hidden"; input.value = preference; input.name = "preference"; //將隱藏域綁定到form表單上 document.getElementById("form").appendChild(input); }
當(dāng)表單提交的時候,觸發(fā)上面兩個函數(shù)就行了!所以在form表單上綁定onsumit事件!
function makeForm() { makeBirthday(); makePreference(); return true; }
效果:
處理修改表單數(shù)據(jù)的Servlet//將數(shù)據(jù)封裝到Bean中 Customer customer = WebUtils.request2Bean(request, Customer.class); //將id封裝到Customer對象中?。?!不要忘了id?。。≡诒韱沃蝎@取到的數(shù)據(jù)是沒有id的?。。。?!記得?。。。? customer.setId(request.getParameter("id")); //調(diào)用Service層的方法,實(shí)現(xiàn)修改 BusinessService businessService = new BusinessService(); businessService.updateCustomer(customer); //修改成功就跳回查看客戶界面 request.getRequestDispatcher("/LookCustomer").forward(request, response);
效果:
總結(jié)在dao層中,我們有添加客戶、通過id查找用戶、刪除用戶、修改用戶信息的方法。
日期我們一般用下拉框來給用戶選取,要想下拉框的信息有足夠多的數(shù)據(jù),我們需要用到JavaScript【DOM編程動態(tài)增加和修改數(shù)據(jù)】
javasrcipt文件不能放在WEB-INF目錄下面
日期的數(shù)據(jù)通過下拉框選取,年、月、日是分散的,我們需要把他們拼接,于是我們也用JavaScript來拼接【減低服務(wù)器端的壓力】
開發(fā)工具方法request2Bean,主要用到了BeanUtils框架,這樣就不用在Servlet一個一個封裝了。
在JSP判斷集合是否有元素時,我們可以用EL表達(dá)式${empty(集合)}。
如果記錄數(shù)有很多,我們應(yīng)該使用分頁技術(shù),一般地,我們使用Page類來封裝分頁的數(shù)據(jù)
要使用分頁技術(shù),就必須在數(shù)據(jù)庫用查詢總記錄數(shù),通過總記錄數(shù),就可以算出總頁數(shù)了【每頁顯示多少條記錄由我們說了算】
在dao層還要編寫獲取具體的分頁數(shù)據(jù),從哪里開始,哪里結(jié)束,返回一個List集合,再把List集合封裝到Page對象上
由于獲取分頁數(shù)據(jù)需要當(dāng)前的頁數(shù)是多少,(所以在service中要判斷當(dāng)前頁數(shù)是否存在,如果不存在,那么就設(shè)置為1)【更新,我認(rèn)為在Controller判斷會好一點(diǎn)】
分頁中,我們還支持上一頁和下一頁的功能,如果頁數(shù)大于1,才顯示上一頁,如果頁數(shù)小于1,才顯示下一頁。
給出下拉框進(jìn)行頁數(shù)跳轉(zhuǎn),使用JavaScript事件機(jī)制,獲取頁數(shù),再提交給Servlet處理即可
我們還要控制頁數(shù)的顯示,因?yàn)椴豢赡苡?00頁,我們就顯示100頁,這樣是不可能的。在Page類中維護(hù)兩個變量,startPage,endPage。我們規(guī)定每次只能顯示10頁數(shù)據(jù),如果第一次訪問就顯示1-10頁。如果當(dāng)前頁數(shù)大于10,那么就顯示6-15頁。如果角標(biāo)越界了,那么就顯示前10頁或者后10頁
我們把顯示分頁的頁面封裝成多帶帶的jsp,使用的Servlet連接也可以用url變量來維護(hù)。
前臺數(shù)據(jù)做拼接,最終都是把拼接好的數(shù)據(jù)用一個隱藏域封裝起來,隨后讓form表單一起提交
如果文章有錯的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章的同學(xué),想要獲取更多的Java資源的同學(xué),可以關(guān)注微信公眾號:Java3y
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/68586.html
摘要:中主要是使用語言。將的動態(tài)功能和標(biāo)準(zhǔn)的安全性引入大型網(wǎng)絡(luò)應(yīng)用的開發(fā)集成部署和管理之中。提供了一個圖形界面的管理工具,稱為信息服務(wù)管理器,可用于監(jiān)視配置和控制服務(wù)。 一、基本概念 1.1、WEB開發(fā)的相關(guān)知識 WEB,在英語中web即表示網(wǎng)頁的意思,它用于表示Internet主機(jī)上供外界訪問的資源?! nternet上供外界訪問的Web資源分為: 靜態(tài)web資源(如html 頁面...
摘要:當(dāng)后繼請求相同的頁面時,容器加載之前生成的類,并且通知去執(zhí)行已經(jīng)存在的字節(jié)碼,從而省去了轉(zhuǎn)換的過程,這也是第一次執(zhí)行頁面時間較長的原因。 以往學(xué)習(xí)的時候大多是看完書或者看完視頻,動手實(shí)踐一下就OK了。然而過了一段時間我發(fā)現(xiàn)東西都忘差不多了,需要復(fù)習(xí)才能重新掌握?,F(xiàn)在開始學(xué)習(xí)JavaWeb了,我將在這里記錄自己的學(xué)習(xí)的一點(diǎn)一滴,不僅便于自己以后回顧知識點(diǎn),也希望能對JavaWeb初學(xué)者有...
摘要:系列文章請查看超詳細(xì)的面試題總結(jié)一之基礎(chǔ)知識篇超詳細(xì)的面試題總結(jié)二之基礎(chǔ)知識篇超詳細(xì)的面試題總結(jié)三之集合篇常見問題下面的都是自己之前在學(xué)習(xí)的時候總結(jié)的,對于鞏固的基礎(chǔ)知識應(yīng)該有很大幫助。注意多線程的并發(fā)的讀寫類屬性會導(dǎo)致數(shù)據(jù)不同步。 系列文章請查看: 超詳細(xì)的Java面試題總結(jié)(一)之Java基礎(chǔ)知識篇 超詳細(xì)的Java面試題總結(jié)(二)之Java基礎(chǔ)知識篇 超詳細(xì)的Java面試題總結(jié)(...
摘要:方法的參數(shù)不但可以使相對于上下文根的路徑,而且可以是相對于當(dāng)前的路徑。如和都是合法的路徑。 轉(zhuǎn)發(fā)與重定向區(qū)別是什么 在調(diào)用方法上 轉(zhuǎn)發(fā) 調(diào)用 HttpServletRequest 對象的方法 request.getRequestDispatcher(test.jsp).forward(req, resp); 重定向 調(diào)用 HttpServletResponse 對象的方法 res...
摘要:實(shí)現(xiàn)不同語言間進(jìn)行協(xié)助開發(fā),可以使用通信的方式來實(shí)現(xiàn),這次實(shí)現(xiàn)和的協(xié)助開發(fā),是項(xiàng)目主要服務(wù)端,由于要處理一些系統(tǒng)底層的事務(wù),所以要用提供一個輔助服務(wù),為主服務(wù)端處理相關(guān)事務(wù),以下是搭建流程和服務(wù)間通信原理。 實(shí)現(xiàn)不同語言間進(jìn)行協(xié)助開發(fā),可以使用通信的方式來實(shí)現(xiàn),這次實(shí)現(xiàn)Nodejs和JavaWeb的協(xié)助開發(fā),Nodejs是項(xiàng)目主要服務(wù)端,由于要處理一些系統(tǒng)底層的事務(wù),所以要用JavaW...
閱讀 2480·2021-11-22 15:35
閱讀 3773·2021-11-04 16:14
閱讀 2701·2021-10-20 13:47
閱讀 2510·2021-10-13 09:49
閱讀 2079·2019-08-30 14:09
閱讀 2380·2019-08-26 13:49
閱讀 893·2019-08-26 10:45
閱讀 2785·2019-08-23 17:54