【JavaWeb基础】JDBC用户登录注册(修订版)

前言

只有光头才能变强。

文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y

在讲解Web开发模式的时候,曾经写过XML版的用户登陆注册案例!现在在原有的项目上,使用数据库版来完成用户的登陆注册!如果不了解的朋友,可以看看我Web开发模式的博文!

本来使用的是XML文件作为小型数据库,现在使用Mysql数据库,代码究竟要改多少呢?我们拭目以待!

使用C3P0数据库连接池

导入C3P0的开发包和导入配置文件

开发包导入的是这个:c3p0-0.9.2-pre1和mchange-commons-0.2.jar.

C3P0不仅性能好,而且配置文件可以使用XML文档来配置!

类似的配置文件可以在官方文档上找得到

【JavaWeb基础】JDBC用户登录注册(修订版)_第1张图片

我们来改造一下:

            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(20UNIQUE NOT NULL,
    password VARCHAR(20)        NOT NULL,
    email    VARCHAR(20),
    birthday DATE

  );

写一个操作数据库的Dao实现

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框架了

【JavaWeb基础】JDBC用户登录注册(修订版)_第2张图片
@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("注册失败了");
  }
}
}

开发DaoFactory

我们的Dao实现已经有了XML版和JDBC版的,BusinessService调用Dao层方法的时候还是要new出具体的Dao实现,也就是以下的代码:

UserDao userDao = new UserImplXML();//或者UserDao userDao= new UserImplDataBase();

//或者
UserDao userDao= new UserImplDataBase();

这样做有点不够灵活,也就有点不够专业!下面我们来说一下为什么需要DaoFactory?

为什么需要DaoFactory?

参考博文:http://blog.sina.com.cn/s/blog_4ca34d0501008tpc.html

摘抄重点:

优点:

缺点:


设计DaoFactory

首先,我们把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;
}

在BusinessService层中用DaoFactory获取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版的成功的效果如下

【JavaWeb基础】JDBC用户登录注册(修订版)_第3张图片

XML版的成功效果如下:

这里写图片描述

总结

  1. 由于我们的Service层可能有多种实现【jdbc,xml】,如果我们直接是使用new具体的Service,那么这耦合性就有点高了

  2. 于是我们有了工厂,工厂的目的就是解耦,我们通过配置文件来创建具体的对象

最后

乐于输出干货的Java技术公众号:Java3y。公众号内有200多篇原创技术文章、海量视频资源、精美脑图,不妨来关注一下!

640?wx_fmt=jpeg

有帮助?在看!转发! 640

你可能感兴趣的:(【JavaWeb基础】JDBC用户登录注册(修订版))