1. 程式人生 > 實用技巧 >JDBC(二)

JDBC(二)

在開發過程中資料庫訪問程式碼應和業務程式碼徹底分離

將資料層抽離出來,將資料訪問的程式碼以物件的方式進行封裝,便於業務層進行復用

資料訪問物件稱為DAO(DAO Data Access Object 資料訪問物件)

DAO應根據資料表為單位進行獨立的封裝,如現在有Users表以及Dep表,在設計DAO時應封裝UserDao和DepDao兩個資料訪問物件;UserDao中僅封裝和Users表有關的資料訪問方法,DepDao封裝和dep有關的資料訪問方法

DAO層屬於專案結構中相對底層的呼叫,因此在業務層訪問資料層時應確保DAO編寫的準確性,每個DAO都應進行測試

測試分為白盒測試和黑盒測試

  白盒測試:測試的過程是能看得到的

  黑盒:只看結果執行是否通過,不看過程

  匯入單元測試的jar包:File——ProjectStructure——Libraries——點選加號——匯入“C3P0”包

使用資料池(連線池)技術解決應用程式與資料庫通訊連線消耗資源過大的問題

常用的連線池:
c3p0、DBCP、Duird

匯入連線池jar包:

<c3p0-config>
  <default-config>
      <!--配置連線池初始的連線數-->
    <property name="initialPoolSize">10</property>
      <!--配置最大的連線數-->
    <property name="maxPoolSize">25</property>
      <!--配置最小的連線數-->
   <property name="minPoolSize">5</property>
      <!--配置驅動-->
   <property name="driverClass">com.mysql.jdbc.Driver</property>
      <!--配置URL-->
   <property name="jdbcUrl">jdbc:mysql:\\localhost:3306/bbs_db</property>
      <!--配置連線資料庫的使用者名稱-->
   <property name="user">root</property>
      <!--配置密碼-->
   <property name="password">tjhilu</property>
  </default
-config> </c3p0-config>

建立和資料的連線有兩種方法:

  1.使用靜態塊載入驅動

    Class.forName("com.mysql.jdbc.Driver"),

    在獲取連線的方法中通過

    con = DriverManager.getConnection("jdbc:mysql://localhost:3306/geekhome", "root", "root")

    獲取連線物件

  2.使用資料池進行載入資料

/**
 * 連線池的使用
 */
public class Demo8 {
    public static void
main(String[] args) { try { //建立連線池物件 DataSource dataSource = new ComboPooledDataSource(); //從連線池中獲取連線物件 Connection con = dataSource.getConnection(); System.out.println(con); } catch (SQLException e) { e.printStackTrace(); } } }

將資料層和業務層分離出來,需要建立一個Dao包將資料類都封裝起來

資料庫連線的類:

/**
 * 封裝了資料庫連線和關閉的工具類
 */
public class DaoUtil {
    //使用靜態塊載入驅動
//    static{
//        try {
//            Class.forName("com.mysql.jdbc.Driver");
//        } catch (ClassNotFoundException e) {
//            e.printStackTrace();
//        }
//    }

    //資料池
    private static DataSource dataSource;

    static{
        //初始化連線池
        dataSource = new ComboPooledDataSource();
    }
    /**
     * 獲得連線
     * @return
     */
    public static Connection openConnection(){
        Connection con = null;
//        try {
//            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/geekhome", "root", "root");
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
        //通過連線池獲取連線物件
        if(dataSource != null){
            try {
                con = dataSource.getConnection();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return con;
    }

    /**
     * 關閉資料庫物件:判斷只要不為null就要關閉
     * @param con
     * @param pstmt
     * @param rs
     */
    public static void close(Connection con, PreparedStatement pstmt, ResultSet rs){
        try {
            if(rs != null){
                rs.close();
            }
            if(pstmt != null){
                pstmt.close();
            }
            if(con != null){
                con.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

使用者類的Dao包:

  將業務中需要對資料進行的操作方法寫在資料類中,業務層中直接呼叫方法得到返回值即可

package com.igeek.dao;

import com.igeek.pojo.User;

import java.sql.*;
import java.util.ArrayList;

/**
 * 封裝users表相關的資料訪問操作
 */
public class UserDao {
    /**
     * 刪除使用者
     * @param userId
     */
    public void delete(int userId){
        //開啟資料庫連線
        Connection con = DaoUtil.openConnection();
        PreparedStatement pstmt = null;
            if(con != null){
            try {
                //建立處理器
                pstmt = con.prepareStatement("delete from users where userid=?");
                //注入引數
                pstmt.setInt(1, userId);
                //執行刪除
                pstmt.executeUpdate();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally{
                //關閉資料庫物件
                DaoUtil.close(con, pstmt, null);
            }
        }
    }

    /**
     * 新增使用者資料
     * @param user
     */
    public void addUser(User user){
        //開啟資料庫連線
        Connection con = DaoUtil.openConnection();
        PreparedStatement pstmt = null;
        if(con != null){
            try {
                pstmt = con.prepareStatement("insert into users values(null,?,?,null,null,null,null,?)");
                //注入引數
                pstmt.setString(1, user.getUserName());
                //pstmt.setTimestamp(2, new Timestamp(user.getBirthday().getTime()));
                pstmt.setTimestamp(2, null);
                pstmt.setString(3, user.getPassword());
                //執行新增
                pstmt.executeUpdate();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                DaoUtil.close(con, pstmt, null);
            }
        }
    }

    /**
     * 修改使用者
     * 根據使用者的編號進行修改,修改使用者的密碼和生日
     * @param user
     */
    public void update(User user){
        Connection con = DaoUtil.openConnection();
        PreparedStatement pstmt = null;
        if(con != null){
            try {
                pstmt = con.prepareStatement("update users set password=?,birthday=? where userid=?");
                //注入引數
                pstmt.setString(1, user.getPassword());
                pstmt.setDate(2, new Date(user.getBirthday().getTime()));
                pstmt.setInt(3, user.getUserId());
                pstmt.executeUpdate();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                DaoUtil.close(con, pstmt, null);
            }
        }
    }

    /**
     * 根據使用者編號查詢
     * @param userId
     * @return
     */
    public User findById(int userId){
        User user = null;
        Connection con = DaoUtil.openConnection();
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        if(con != null){
            try {
                pstmt = con.prepareStatement("select userid,username,birthday,password from users where " +
                        "userid=? ");
                pstmt.setInt(1, userId);
                //執行查詢
                rs = pstmt.executeQuery();
                while(rs.next()){
                     user = new User();
                     user.setUserId(rs.getInt(1));
                     user.setUserName(rs.getString(2));
                     user.setBirthday(rs.getTimestamp(3));
                     user.setPassword(rs.getString(4));
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                DaoUtil.close(con, pstmt, rs);
            }
        }
        return user;
    }

    /**
     * 查詢users表的所有資料:返回一個user集合
     */
    public ArrayList<User> findAll(){
        ArrayList<User> list = new ArrayList<>();
        Connection con = DaoUtil.openConnection();
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        if(con != null){
            try {
                pstmt = con.prepareStatement("select userid,username,password,birthday from users");
                rs = pstmt.executeQuery();
                while(rs.next()){
                    //建立User物件
                    User user = new User();
                    //封裝列值至user物件
                    user.setUserId(rs.getInt(1));
                    user.setUserName(rs.getString(2));
                    user.setPassword(rs.getString(3));
                    user.setBirthday(rs.getDate(4));
                    //將user物件新增至集合儲存
                    list.add(user);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                DaoUtil.close(con, pstmt, rs);
            }
        }
        return list;
    }

  /**
  * 查詢users表中的所有使用者:返回一個user集合
  * 按照頁面進行查詢
  *
pstmt = con.prepareStatement("select userid,username,password,birthday " +
                          "from users limit ?,3");//第一個引數表示從什麼位置開始,第二個引數表示每頁顯示多少條內容
  *pstmt.setInt(1, (page-1)*3); //注入佔位符處的引數
  */
public ArrayList<User> findByPage(int page){
     //要先例項化,不然要是找到以後在例項化,那麼每次都會重新new ArrayList
<User> list = new ArrayList<>(); Connection con = DaoUtil.openConnection(); PreparedStatement pstmt = null; ResultSet rs = null; if(con != null){ try { pstmt = con.prepareStatement("select userid,username,password,birthday " + "from users limit ?,3"); pstmt.setInt(1, (page-1)*3); rs = pstmt.executeQuery(); while(rs.next()){ //建立User物件 User user = new User(); //封裝列值至user物件 user.setUserId(rs.getInt(1)); user.setUserName(rs.getString(2)); user.setPassword(rs.getString(3)); user.setBirthday(rs.getDate(4)); //將user物件新增至集合儲存 list.add(user); } } catch (SQLException e) { e.printStackTrace(); } finally { DaoUtil.close(con, pstmt, rs); } } return list; } /** * 根據使用者名稱查詢 * @param userName * @return */ public User findByName(String userName){ User user = null; Connection con = DaoUtil.openConnection(); PreparedStatement pstmt = null; ResultSet rs = null; if(con != null){ try { pstmt = con.prepareStatement("select 1userid,username,birthday,password from users where " + "userName=? "); pstmt.setString(1, userName); //執行查詢 rs = pstmt.executeQuery(); while(rs.next()){ user = new User(); user.setUserId(rs.getInt(1)); user.setUserName(rs.getString(2)); user.setBirthday(rs.getTimestamp(3)); user.setPassword(rs.getString(4)); } } catch (SQLException e) { e.printStackTrace(); } finally { DaoUtil.close(con, pstmt, rs); } } return user; } }

user類:

package com.igeek.pojo;

import java.util.Date;

/**
 * users表的對映類,用於封裝users表的資料行
 */
public class User {
    private int userId;
    private String userName;
    private String password;
    private Date birthday;


    public User() {
    }

    public User(String userName, String password, Date birthday) {
        this.userName = userName;
        this.password = password;
        this.birthday = birthday;
    }

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

業務類:

package com.igeek;

import com.igeek.dao.UserDao;
import com.igeek.pojo.User;

import java.util.Scanner;

/**
 * 在業務中使用DAO實現資料訪問
 */
public class Demo7 {

    private UserDao userDao;
    private Scanner sc;

    public Demo7() {
        userDao = new UserDao();
        sc = new Scanner(System.in);
    }

    public void start(){
        System.out.println("1. 登入");
        System.out.println("2. 註冊");
        System.out.println("請選擇:");
        int chooice = sc.nextInt();
        switch(chooice){
            case 1:
                login();
                break;
            case 2:
                regist();
                break;
        }
    }

    /**
     * 登入
     */
    public void login(){
        System.out.println("請輸入使用者名稱:");
        String userName = sc.next();
        System.out.println("請輸入密碼:");
        String password = sc.next();
        //根據使用者名稱查詢
        User user = userDao.findByName(userName);
        //判斷使用者是否找到
        if(user != null){
            //判斷密碼
            if(password.equals(user.getPassword())){
                System.out.println("登入成功!");
            }
            else{
                System.out.println("密碼錯誤!");
                login();
            }
        }
        else{
            System.out.println("使用者名稱不存在!");
            login();
        }
    }

    /**
     * 註冊
     */
    public void regist(){
        System.out.println("請輸入使用者名稱:");
        String userName = sc.next();
        System.out.println("請輸入密碼:");
        String password = sc.next();
        //查詢使用者名稱是否被註冊
        User user = userDao.findByName(userName);
        if(user == null){
            //建立要註冊的使用者物件
            User registUser = new User();
            registUser.setUserName(userName);
            registUser.setPassword(password);
            userDao.addUser(registUser);
            System.out.println("註冊成功!");
            start();
        }
        else{
            System.out.println("使用者名稱已被註冊!");
            regist();
        }
    }


    public static void main(String[] args) {
        Demo7 demo = new Demo7();
        demo.start();
    }

}