前言
在講解Web開(kāi)發(fā)模式的時(shí)候,曾經(jīng)寫(xiě)過(guò)XML版的用戶(hù)登陸注冊(cè)案例!現(xiàn)在在原有的項(xiàng)目上,使用數(shù)據(jù)庫(kù)版來(lái)完成用戶(hù)的登陸注冊(cè)!如果不了解的朋友,可以看看我Web開(kāi)發(fā)模式的博文!
本來(lái)使用的是XML文件作為小型數(shù)據(jù)庫(kù),現(xiàn)在使用Mysql數(shù)據(jù)庫(kù),代碼究竟要改多少呢?我們拭目以待!
使用C3P0數(shù)據(jù)庫(kù)連接池 導(dǎo)入C3P0的開(kāi)發(fā)包和導(dǎo)入配置文件開(kāi)發(fā)包導(dǎo)入的是這個(gè):c3p0-0.9.2-pre1和mchange-commons-0.2.jar.
C3P0不僅性能好,而且配置文件可以使用XML文檔來(lái)配置!
類(lèi)似的配置文件可以在官方文檔上找得到!
我們來(lái)改造一下:
寫(xiě)獲取連接的工具類(lèi)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/事例名... 用戶(hù)名 密碼 5 10 5 20
public class DBUtils { private static ComboPooledDataSource comboPooledDataSource = null; static { //它會(huì)自動(dòng)尋找配置文件,節(jié)點(diǎn)為mysql的數(shù)據(jù)庫(kù)【如果沒(méi)有指定,就使用默認(rèn)的!】 comboPooledDataSource = new ComboPooledDataSource("mysql"); } public static DataSource getDataSource() { return comboPooledDataSource ; } public static Connection getConnection() { try { return comboPooledDataSource.getConnection(); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException("數(shù)據(jù)庫(kù)初始化失敗了!"); } } }設(shè)計(jì)數(shù)據(jù)庫(kù)表
非常簡(jiǎn)單,根據(jù)實(shí)體表來(lái)設(shè)計(jì)就好了!
CREATE TABLE user ( id VARCHAR(20) PRIMARY KEY, username VARCHAR(20) UNIQUE NOT NULL, password VARCHAR(20) NOT NULL, email VARCHAR(20), birthday DATE );寫(xiě)一個(gè)操作數(shù)據(jù)庫(kù)的Dao實(shí)現(xiàn)
public class UserImplDataBase implements UserDao { @Override public User find(String username, String password) { return null; } @Override public void register(User user) { } }
下面我們就直接使用DBUtils框架了
導(dǎo)入DBUtils的開(kāi)發(fā)包
具體的代碼如下
@Override public User find(String username, String password) { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "SELECT * FROM user WHERE username=? AND password=?"; try { User user = (User) queryRunner.query(sql, new BeanHandler(User.class), new Object[]{username, password}); return user == null ? null : user; } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException("登陸失敗了!"); } } @Override public void register(User user) { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "INSERT INTO user (id, username, password, email,birthday) VALUES (?,?,?,?,?);"; String id = user.getId(); String username = user.getUsername(); String password = user.getPassword(); String email = user.getEmail(); Date date = user.getBirthday(); try { queryRunner.update(sql, new Object[]{id, username, password, email,date}); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException("注冊(cè)失敗了"); } } }開(kāi)發(fā)DaoFactory
我們的Dao實(shí)現(xiàn)已經(jīng)有了XML版和JDBC版的,BusinessService調(diào)用Dao層方法的時(shí)候還是要new出具體的Dao實(shí)現(xiàn),也就是以下的代碼:
UserDao userDao = new UserImplXML(); //或者 UserDao userDao= new UserImplDataBase();
這樣做有點(diǎn)不夠靈活,也就有點(diǎn)不夠?qū)I(yè)!下面我們來(lái)說(shuō)一下為什么需要DaoFactory?
為什么需要DaoFactory?參考博文:http://blog.sina.com.cn/s/blog_4ca34d0501008tpc.html
摘抄重點(diǎn):
優(yōu)點(diǎn):
透明化:商業(yè)對(duì)象可以在完全不知道數(shù)據(jù)源如何具體實(shí)現(xiàn)的情況下來(lái)使用數(shù)據(jù)源. 訪問(wèn)數(shù)據(jù)源是透明的,因?yàn)閷?shí)現(xiàn)細(xì)節(jié)已經(jīng)被隱藏進(jìn)了DAO.
遷移簡(jiǎn)單化:DAO 層的出現(xiàn),使得應(yīng)用程序向不同的數(shù)據(jù)庫(kù)實(shí)現(xiàn)進(jìn)行遷移變的容易.商業(yè)對(duì)象可以對(duì)底層數(shù)據(jù)實(shí)現(xiàn)一無(wú)所知.這樣,遷移只涉及到了對(duì)DAO層的修改. 另外,如果使用工廠策略,則使為每一種底層數(shù)據(jù)實(shí)現(xiàn)提供一個(gè)具體的工廠實(shí)現(xiàn)成為可能.在這種情況下,遷移到一種不同的數(shù)據(jù)實(shí)現(xiàn),其實(shí)就相當(dāng)于為這個(gè)應(yīng)用程序再提供一個(gè)新的工廠實(shí)現(xiàn).
減少在商業(yè)對(duì)象中的編程難度:由于DAO管理著所有的數(shù)據(jù)訪問(wèn)細(xì)節(jié),因而大大簡(jiǎn)化了在商業(yè)對(duì)象和其他使用DAO的數(shù)據(jù)客戶(hù)端里的代碼.所有的實(shí)現(xiàn)細(xì)節(jié)相關(guān)的代碼比如(SQL 語(yǔ)句)都包含在DAO而不在商業(yè)對(duì)象中. 這樣使得代碼變的更加健壯而且大大提高了開(kāi)發(fā)效率.
將所有的數(shù)據(jù)訪問(wèn)都多帶帶集中到一層中去: 因?yàn)樗械臄?shù)據(jù)訪問(wèn)操作現(xiàn)在都已經(jīng)被DAO所代理,所以這個(gè)多帶帶的數(shù)據(jù)訪問(wèn)層可以被看作可以是將數(shù)據(jù)訪問(wèn)實(shí)現(xiàn)和其余應(yīng)用程序相互隔離的一層. 這樣的集中,使得應(yīng)用程序可以更加容易的來(lái)維護(hù)和管理.
缺點(diǎn):
增加了多余的層:由于DAO在數(shù)據(jù)客戶(hù)端和數(shù)據(jù)源之外多創(chuàng)建了一層對(duì)象,因而,需要對(duì)他進(jìn)行設(shè)計(jì)和實(shí)現(xiàn),來(lái)均衡這個(gè)設(shè)計(jì)模式的利弊. 但是,一般來(lái)說(shuō),采用此設(shè)計(jì)模式還是利大于弊的.
需要對(duì)類(lèi)的相互繼承關(guān)系進(jìn)行設(shè)計(jì):當(dāng)使用工廠策略的時(shí)候,具體工廠類(lèi)的繼承關(guān)系和由這些工廠類(lèi)生成的產(chǎn)品需要進(jìn)行設(shè)計(jì)和實(shí)現(xiàn). 我們需要仔細(xì)考慮這些多付出的工作是否真的可以產(chǎn)生出來(lái)更高的靈活性. 使用這個(gè)策略會(huì)使設(shè)計(jì)變的更加復(fù)雜,然而,你可以先從工廠方法模式開(kāi)始來(lái)實(shí)現(xiàn)這個(gè)策略,然后在需要的情況下再轉(zhuǎn)向抽象工廠
設(shè)計(jì)DaoFactory首先,我們把DaoFactory設(shè)計(jì)成單例的【工廠有一個(gè)就夠了!】
public class DaoFactory { private DaoFactory() { } private static final DaoFactory DAO_FACTORY = new DaoFactory(); //暴露公開(kāi)方法獲取工廠對(duì)象 public static DaoFactory newInstance() { return DAO_FACTORY; } }
目前我們操作的是User,所以工廠造UserDao對(duì)象,而UserDao對(duì)象是JDBC版呢,還是XML版呢,我們通過(guò)配置文件來(lái)定(這樣就更靈活了)!
在src目錄下加入配置文件
注意:不要加""字符串的符號(hào)?。。。?!我就是這里搞了很久?。。?!
#class需要的是完整的對(duì)象名稱(chēng)(包括包) #userClass=zhongfucheng.dao.impl.UserImplDataBase userClass=zhongfucheng.dao.impl.UserImplXML
讀取配置文件的信息,創(chuàng)建相對(duì)應(yīng)的UserDao對(duì)象,直接在構(gòu)造函數(shù)做就行了(其實(shí)就是個(gè)初始化的操作罷了)
private static UserDao userDao = null; private DaoFactory() { try { //讀取配置文件的信息 InputStream inputStream = DaoFactory.class.getClassLoader().getResourceAsStream("UserDao.properties"); Properties properties = new Properties(); properties.load(inputStream); String userClass = properties.getProperty("userClass"); //利用反射機(jī)制創(chuàng)建相對(duì)應(yīng)的對(duì)象 userDao = (UserDao) Class.forName(userClass).newInstance(); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("讀取文件失敗了!"); } catch (IllegalAccessException e) { e.printStackTrace(); throw new RuntimeException("反射失敗了!"); } catch (InstantiationException e) { e.printStackTrace(); throw new RuntimeException("反射失敗了!"); } catch (ClassNotFoundException e) { e.printStackTrace(); throw new RuntimeException("反射失敗了!"); } } public static UserDao createUserDao() { return userDao; }在BusinessService層中用DaoFactory獲取UserDao對(duì)象
UserDao userDao = DaoFactory.newInstance().createUserDao();測(cè)試
如果我們的mysql驅(qū)動(dòng)版本太低,就出現(xiàn)以下的異常!我們只需要下載新的mysql的jar包,導(dǎo)入項(xiàng)目即可!
java.sql.SQLException: Feature not implemented Query:insert into guestbook (id,name,email,url,title,content,time) value(?,?,?,?,?,?,?) Parameters: [1, qwq,wqwq,qwqw,qw,qw, 2010-09-13]
JDBC版的成功的效果如下:
XML版的成功效果如下:
總結(jié)由于我們的Service層可能有多種實(shí)現(xiàn)【jdbc,xml】,如果我們直接是使用new具體的Service,那么這耦合性就有點(diǎn)高了
于是我們有了工廠,工廠的目的就是解耦,我們通過(guò)配置文件來(lái)創(chuàng)建具體的對(duì)象。
如果文章有錯(cuò)的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章的同學(xué),可以關(guān)注微信公眾號(hào):Java3y
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/68532.html
摘要:前言由于寫(xiě)的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 前言 由于寫(xiě)的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 由于更新比較頻繁,因此隔一段時(shí)間才會(huì)更新目錄導(dǎo)航哦~想要獲取最新原創(chuàng)的技術(shù)文章歡迎關(guān)注我的公眾號(hào):Java3y Java3y文章目錄導(dǎo)航 Java基礎(chǔ) 泛型就這么簡(jiǎn)單 注解就這么簡(jiǎn)單 Druid數(shù)據(jù)庫(kù)連接池...
摘要:需求通過(guò)異步刷新頁(yè)面驗(yàn)證用戶(hù)輸入的賬號(hào)密碼是否在數(shù)據(jù)庫(kù)中存在。下面是下查詢(xún)的代碼查詢(xún)用戶(hù)名是否存在語(yǔ)句連接代碼關(guān)于類(lèi)關(guān)于控制層獲取到輸入的用戶(hù)名調(diào)用中的查詢(xún)方法設(shè)置字符編碼關(guān)閉資源 需求 通過(guò)ajax異步刷新頁(yè)面驗(yàn)證用戶(hù)輸入的賬號(hào)密碼是否在數(shù)據(jù)庫(kù)中存在。 技術(shù)棧 JSP+Servlet+Oracle 具體代碼 JSP部分: Insert title here fu...
摘要:安全框架是目前為止作為登錄注冊(cè)最常用的框架,因?yàn)樗值膹?qiáng)大簡(jiǎn)單,提供了認(rèn)證授權(quán)加密和會(huì)話管理等功能。本質(zhì)上是一個(gè)特定安全的。當(dāng)配置時(shí),必須指定至少一個(gè)用來(lái)進(jìn)行身份驗(yàn)證和或授權(quán)。提供了多種可用的來(lái)獲取安全相關(guān)的數(shù)據(jù)。 web開(kāi)發(fā)安全框架中的Apache Shiro的應(yīng)用前階段就hadoop的分享了一些內(nèi)容,希望對(duì)新手入門(mén)的朋友有點(diǎn)幫助吧!對(duì)于hadoop新手入門(mén)的,還是比較推薦大快搜索...
摘要:比如將建立連接的代碼放入工具類(lèi)里面,工具類(lèi)提供給外界一個(gè)獲取的方法,需要的時(shí)候直接調(diào)用方法即可。 在之前的這篇博客里面MySQL筆記 —— jdbc連接數(shù)據(jù)庫(kù)(增刪...
摘要:新建一個(gè)項(xiàng)目選擇自己的文件勾選項(xiàng)目構(gòu)造如下設(shè)置項(xiàng)目配置快捷鍵選擇配置紅色框選擇時(shí),運(yùn)行成功會(huì)會(huì)自動(dòng)運(yùn)行下方的鏈接測(cè)試運(yùn)行出現(xiàn)如下便創(chuàng)建成功編寫(xiě)第一個(gè)代碼,測(cè)試環(huán)境是否設(shè)置成功第一個(gè)設(shè)置響應(yīng)內(nèi)容類(lèi)型實(shí)際的邏輯是 新建一個(gè)servlet項(xiàng)目 Flies --> new --> project-->ProjectSDK選擇自己的JDK文件-->勾選Web Appliction -->Next...
閱讀 1942·2021-11-24 09:39
閱讀 3526·2021-09-28 09:36
閱讀 3296·2021-09-06 15:10
閱讀 3453·2019-08-30 15:44
閱讀 1161·2019-08-30 15:43
閱讀 1806·2019-08-30 14:20
閱讀 2721·2019-08-30 12:51
閱讀 2042·2019-08-30 11:04