前言
只有光头才能变强。
文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y
在讲解Web开发模式的时候,曾经写过XML版的用户登陆注册案例!现在在原有的项目上,使用数据库版来完成用户的登陆注册!如果不了解的朋友,可以看看我Web开发模式的博文!
本来使用的是XML文件作为小型数据库,现在使用Mysql数据库,代码究竟要改多少呢?我们拭目以待!
开发包导入的是这个: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
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driverproperty>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/zhongfuchengproperty>
<property name="user">rootproperty>
<property name="password">rootproperty>
<property name="acquireIncrement">5property>
<property name="initialPoolSize">10property>
<property name="minPoolSize">5property>
<property name="maxPoolSize">20property>
default-config>
<named-config name="mysql">
<property name="driverClass">com.mysql.jdbc.Driverproperty>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/zhongfuchengproperty>
<property name="user">rootproperty>
<property name="password">rootproperty>
<property name="acquireIncrement">5property>
<property name="initialPoolSize">10property>
<property name="minPoolSize">5property>
<property name="maxPoolSize">20property>
named-config>
<named-config name="oracle">
<property name="driverClass">oracle.jdbc.driver.OracleDriverproperty>
<property name="jdbcUrl">jdbc:oracle:thin:@//localhost:1521/事例名...property>
<property name="user">用户名property>
<property name="password">密码property>
<property name="acquireIncrement">5property>
<property name="initialPoolSize">10property>
<property name="minPoolSize">5property>
<property name="maxPoolSize">20property>
named-config>
c3p0-config>
public class DBUtils { private static ComboPooledDataSource comboPooledDataSource = null; static { //它会自动寻找配置文件,节点为mysql的数据库【如果没有指定,就使用默认的!】 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("数据库初始化失败了!"); } }}class DBUtils {
private static ComboPooledDataSource comboPooledDataSource = null;
static {
//它会自动寻找配置文件,节点为mysql的数据库【如果没有指定,就使用默认的!】
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("数据库初始化失败了!");
}
}
}
非常简单,根据实体表来设计就好了!
CREATE TABLE user ( id VARCHAR(20) PRIMARY KEY, username VARCHAR(20) UNIQUE NOT NULL, password VARCHAR(20) NOT NULL, email VARCHAR(20), birthday DATE );TABLE user (
id VARCHAR(20) PRIMARY KEY,
username VARCHAR(20) UNIQUE NOT NULL,
password VARCHAR(20) NOT NULL,
email VARCHAR(20),
birthday DATE
);
public class UserImplDataBase implements UserDao { @Override public User find(String username, String password) { return null; } @Override public void register(User user) { }}class UserImplDataBase implements UserDao {
@Override
public User find(String username, String password) {
return null;
}
@Override
public void register(User user) {
}
}
下面我们就直接使用DBUtils框架了
@Overridepublic 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("登陆失败了!"); }}@Overridepublic 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("注册失败了"); }}}
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("注册失败了");
}
}
}
我们的Dao实现已经有了XML版和JDBC版的,BusinessService调用Dao层方法的时候还是要new出具体的Dao实现,也就是以下的代码:
UserDao userDao = new UserImplXML();//或者UserDao userDao= new UserImplDataBase();
//或者
UserDao userDao= new UserImplDataBase();
这样做有点不够灵活,也就有点不够专业!下面我们来说一下为什么需要DaoFactory?
参考博文:http://blog.sina.com.cn/s/blog_4ca34d0501008tpc.html
摘抄重点:
优点:
缺点:
首先,我们把DaoFactory设计成单例的【工厂有一个就够了!】
public class DaoFactory { private DaoFactory() { } private static final DaoFactory DAO_FACTORY = new DaoFactory(); //暴露公开方法获取工厂对象 public static DaoFactory newInstance() { return DAO_FACTORY; }}class DaoFactory {
private DaoFactory() {
}
private static final DaoFactory DAO_FACTORY = new DaoFactory();
//暴露公开方法获取工厂对象
public static DaoFactory newInstance() {
return DAO_FACTORY;
}
}
目前我们操作的是User,所以工厂造UserDao对象,而UserDao对象是JDBC版呢,还是XML版呢,我们通过配置文件来定(这样就更灵活了)!
#class需要的是完整的对象名称(包括包)#userClass=zhongfucheng.dao.impl.UserImplDataBaseuserClass=zhongfucheng.dao.impl.UserImplXML
userClass=zhongfucheng.dao.impl.UserImplXML
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"); //利用反射机制创建相对应的对象 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;}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");
//利用反射机制创建相对应的对象
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;
}
UserDao userDao = DaoFactory.newInstance().createUserDao();
如果我们的mysql驱动版本太低,就出现以下的异常!我们只需要下载新的mysql的jar包,导入项目即可!
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版的成功效果如下:
这里写图片描述由于我们的Service层可能有多种实现【jdbc,xml】,如果我们直接是使用new具体的Service,那么这耦合性就有点高了
于是我们有了工厂,工厂的目的就是解耦,我们通过配置文件来创建具体的对象
有帮助?在看!转发!乐于输出干货的Java技术公众号:Java3y。公众号内有200多篇原创技术文章、海量视频资源、精美脑图,不妨来关注一下!