前言在讲解Web开发模式的时候,曾经写过XML版的用户登陆注册案例!现在在原有的项目上,使用数据库版来完成用户的登陆注册!如果不了解的朋友,可以看看我Web开发模式的博文!本来使用的是XML文件作为小型数据库,现在使用Mysql数据库,代码究竟要改多少呢?我们拭目以待!使用C3P0数据库连接池导入C3P0的开发包和导入配置文件开发包导入的是这个:c3p0-0.9.2-pre1和mchange-commons-0.2.jar.C3P0不仅性能好,而且配置文件可以使用XML文档来配置!类似的配置文件可以在官方文档上找得到!我们来改造一下:
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
写获取连接的工具类
publicclassDBUtils{
privatestaticComboPooledDataSourcecomboPooledDataSource=null;
static{
//它会自动寻找配置文件,节点为mysql的数据库【如果没有指定,就使用默认的!】
comboPooledDataSource=newComboPooledDataSource("mysql");
}
publicstaticDataSourcegetDataSource(){
returncomboPooledDataSource;
}
publicstaticConnectiongetConnection(){
try{
returncomboPooledDataSource.getConnection();
}catch(SQLExceptione){
e.printStackTrace();
thrownewRuntimeException("数据库初始化失败了!");
}
}
}
设计数据库表非常简单,根据实体表来设计就好了!
CREATETABLEuser(
idVARCHAR(20)PRIMARYKEY,
usernameVARCHAR(20)UNIQUENOTNULL,
passwordVARCHAR(20)NOTNULL,
emailVARCHAR(20),
birthdayDATE
);
写一个操作数据库的Dao实现
publicclassUserImplDataBaseimplementsUserDao{
@Override
publicUserfind(Stringusername,Stringpassword){
returnnull;
}
@Override
publicvoidregister(Useruser){
}
}
下面我们就直接使用DBUtils框架了
导入DBUtils的开发包
具体的代码如下
@Override
publicUserfind(Stringusername,Stringpassword){
QueryRunnerqueryRunner=newQueryRunner(Utils2DB.getDataSource());
Stringsql="SELECT * FROM user WHERE username=? AND password=?";
try{
Useruser=(User)queryRunner.query(sql,newBeanHandler(User.class),newObject[]{username,password});
returnuser==null?null:user;
}catch(SQLExceptione){
e.printStackTrace();
thrownewRuntimeException("登陆失败了!");
}
}
@Override
publicvoidregister(Useruser){
QueryRunnerqueryRunner=newQueryRunner(Utils2DB.getDataSource());
Stringsql="INSERT INTO user (id, username, password, email,birthday) VALUES (?,?,?,?,?);";
Stringid=user.getId();
Stringusername=user.getUsername();
Stringpassword=user.getPassword();
Stringemail=user.getEmail();
Datedate=user.getBirthday();
try{
queryRunner.update(sql,newObject[]{id,username,password,email,date});
}catch(SQLExceptione){
e.printStackTrace();
thrownewRuntimeException("注册失败了");
}
}
}
开发DaoFactory我们的Dao实现已经有了XML版和JDBC版的,BusinessService调用Dao层方法的时候还是要new出具体的Dao实现,也就是以下的代码:
UserDaouserDao=newUserImplXML();
//或者
UserDaouserDao=newUserImplDataBase();
这样做有点不够灵活,也就有点不够专业!下面我们来说一下为什么需要DaoFactory?为什么需要DaoFactory?参考博文:http://blog.sina.com.cn/s/blog_4ca34d0501008tpc.html摘抄重点:优点:
透明化:商业对象可以在完全不知道数据源如何具体实现的情况下来使用数据源.访问数据源是透明的,因为实现细节已经被隐藏进了DAO.
迁移简单化:DAO 层的出现,使得应用程序向不同的数据库实现进行迁移变的容易.商业对象可以对底层数据实现一无所知.这样,迁移只涉及到了对DAO层的修改. 另外,如果使用工厂策略,则使为每一种底层数据实现提供一个具体的工厂实现成为可能.在这种情况下,迁移到一种不同的数据实现,其实就相当于为这个应用程序再提供一个新的工厂实现.
减少在商业对象中的编程难度:由于DAO管理着所有的数据访问细节,因而大大简化了在商业对象和其他使用DAO的数据客户端里的代码.所有的实现细节相关的代码比如(SQL 语句)都包含在DAO而不在商业对象中. 这样使得代码变的更加健壮而且大大提高了开发效率.
将所有的数据访问都单独集中到一层中去:因为所有的数据访问操作现在都已经被DAO所代理,所以这个单独的数据访问层可以被看作可以是将数据访问实现和其余应用程序相互隔离的一层. 这样的集中,使得应用程序可以更加容易的来维护和管理.
缺点:
增加了多余的层:由于DAO在数据客户端和数据源之外多创建了一层对象,因而,需要对他进行设计和实现,来均衡这个设计模式的利弊. 但是,一般来说,采用此设计模式还是利大于弊的.
需要对类的相互继承关系进行设计:当使用工厂策略的时候,具体工厂类的继承关系和由这些工厂类生成的产品需要进行设计和实现. 我们需要仔细考虑这些多付出的工作是否真的可以产生出来更高的灵活性. 使用这个策略会使设计变的更加复杂,然而,你可以先从工厂方法模式开始来实现这个策略,然后在需要的情况下再转向抽象工厂
设计DaoFactory首先,我们把DaoFactory设计成单例的【工厂有一个就够了!】
publicclassDaoFactory{
privateDaoFactory(){
}
privatestaticfinalDaoFactoryDAO_FACTORY=newDaoFactory();
//暴露公开方法获取工厂对象
publicstaticDaoFactorynewInstance(){
returnDAO_FACTORY;
}
}
目前我们操作的是User,所以工厂造UserDao对象,而UserDao对象是JDBC版呢,还是XML版呢,我们通过配置文件来定(这样就更灵活了)!
在src目录下加入配置文件
注意:不要加""字符串的符号!!!!!我就是这里搞了很久!!!!
读取配置文件的信息,创建相对应的UserDao对象,直接在构造函数做就行了(其实就是个初始化的操作罢了)
privatestaticUserDaouserDao=null;
privateDaoFactory(){
try{
//读取配置文件的信息
InputStreaminputStream=DaoFactory.class.getClassLoader().getResourceAsStream("UserDao.properties");
Propertiesproperties=newProperties();
properties.load(inputStream);
StringuserClass=properties.getProperty("userClass");
//利用反射机制创建相对应的对象
userDao=(UserDao)Class.forName(userClass).newInstance();
}catch(IOExceptione){
e.printStackTrace();
thrownewRuntimeException("读取文件失败了!");
}catch(IllegalAccessExceptione){
e.printStackTrace();
thrownewRuntimeException("反射失败了!");
}catch(InstantiationExceptione){
e.printStackTrace();
thrownewRuntimeException("反射失败了!");
}catch(ClassNotFoundExceptione){
e.printStackTrace();
thrownewRuntimeException("反射失败了!");
}
}
publicstaticUserDaocreateUserDao(){
returnuserDao;
}
在BusinessService层中用DaoFactory获取UserDao对象
UserDaouserDao=DaoFactory.newInstance().createUserDao();
测试如果我们的mysql驱动版本太低,就出现以下的异常!我们只需要下载新的mysql的jar包,导入项目即可!
java.sql.SQLException:FeaturenotimplementedQuery:insertintoguestbook(id,name,email,url,title,content,time)value(?,?,?,?,?,?,?)Parameters:[1,qwq,wqwq,qwqw,qw,qw,2010-09-13]
JDBC版的成功的效果如下:
总结
由于我们的Service层可能有多种实现【jdbc,xml】,如果我们直接是使用new具体的Service,那么这耦合性就有点高了
于是我们有了工厂,工厂的目的就是解耦,我们通过配置文件来创建具体的对象。
领取专属 10元无门槛券
私享最新 技术干货