【JavaWeb基礎】JDBC用戶登陸註冊(修訂版)

前言

只有光頭才能變強。java

GitHub倉庫:https://github.com/ZhongFuCheng3y/3ymysql

在講解Web開發模式的時候,曾經寫過XML版的用戶登錄註冊案例!如今在原有的項目上,使用數據庫版來完成用戶的登錄註冊!若是不瞭解的朋友,能夠看看我Web開發模式的博文!git

原本使用的是XML文件做爲小型數據庫,如今使用Mysql數據庫,代碼究竟要改多少呢?咱們拭目以待!github

使用C3P0數據庫鏈接池

導入C3P0的開發包和導入配置文件

開發包導入的是這個:c3p0-0.9.2-pre1和mchange-commons-0.2.jar.sql

C3P0不只性能好,並且配置文件可使用XML文檔來配置!數據庫

相似的配置文件能夠在官方文檔上找獲得oracle

640?wx_fmt=png

咱們來改造一下:app

<?xml version="1.0" encoding="UTF-8"?><c3p0-config>    <default-config>        <property name="driverClass">com.mysql.jdbc.Driver</property>        <property name="jdbcUrl">jdbc:mysql://localhost:3306/zhongfucheng</property>        <property name="user">root</property>        <property name="password">root</property>        <property name="acquireIncrement">5</property>        <property name="initialPoolSize">10</property>        <property name="minPoolSize">5</property>        <property name="maxPoolSize">20</property>    </default-config>    <named-config name="mysql">        <property name="driverClass">com.mysql.jdbc.Driver</property>        <property name="jdbcUrl">jdbc:mysql://localhost:3306/zhongfucheng</property>        <property name="user">root</property>        <property name="password">root</property>        <property name="acquireIncrement">5</property>        <property name="initialPoolSize">10</property>        <property name="minPoolSize">5</property>        <property name="maxPoolSize">20</property>    </named-config>    <named-config name="oracle">        <property name="driverClass">oracle.jdbc.driver.OracleDriver</property>        <property name="jdbcUrl">jdbc:oracle:thin:@//localhost:1521/事例名...</property>        <property name="user">用戶名</property>        <property name="password">密碼</property>        <property name="acquireIncrement">5</property>        <property name="initialPoolSize">10</property>        <property name="minPoolSize">5</property>        <property name="maxPoolSize">20</property>    </named-config></c3p0-config>
<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/zhongfucheng</property>
        <property name="user">root</property>
        <property name="password">root</property>

        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </default-config>

    <named-config name="mysql">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/zhongfucheng</property>
        <property name="user">root</property>
        <property name="password">root</property>

        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </named-config>


    <named-config name="oracle">
        <property name="driverClass">oracle.jdbc.driver.OracleDriver</property>
        <property name="jdbcUrl">jdbc:oracle:thin:@//localhost:1521/事例名...</property>
        <property name="user">用戶名</property>
        <property name="password">密碼</property>

        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </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

  );
寫一個操做數據庫的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框架了ide

640?wx_fmt=png
@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?

摘抄重點:

優勢:

缺點:


設計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版的成功的效果以下

640?wx_fmt=gif

XML版的成功效果以下:

640?wx_fmt=gif這裏寫圖片描述
總結
  1. 因爲咱們的Service層可能有多種實現【jdbc,xml】,若是咱們直接是使用new具體的Service,那麼這耦合性就有點高了

  2. 因而咱們有了工廠,工廠的目的就是解耦,咱們經過配置文件來建立具體的對象

最後

640?wx_fmt=jpeg

相關文章
相關標籤/搜索