1. 程式人生 > >DBUtil介紹以及連線池DBCP和C3P0的使用概述

DBUtil介紹以及連線池DBCP和C3P0的使用概述

1.DBUtil概述

DBUtil是JDBC的簡化開發工具包,是apache commons的一個元件成員.
是對JDBC簡單封裝的開源的工具類庫,使用它能簡化JDBC應用程式的開發,而且不會影響效能
注意:使用時需要匯入commons-dbutils-1.6.jar包
DBUtils中的檔案註釋:
這裡寫圖片描述

2.三個核心功能:

QueryRunner類中提供對sql語句操作的API.(增,刪,改,查)
ResultSetHandler介面,用於定義select操作後,怎樣封裝結果集.
DbUtils類,它就是一個工具類,定義了關閉資源與事務處理的方法,有一個close方法,可以釋放資源

在下邊的介紹中會依次介紹這三個功能類和介面的使用。

3.事務(Transaction)處理

使系統擺脫不一致的狀態
這裡寫圖片描述

4.QueryRunner類的操作(可以實現增,刪,改的操作)

核心方法:
1.update(Connection conn,String sql, Object…params)用於完成資料的增刪改操作
第一個引數是資料庫連線物件,第二個引數是資料庫語句(裡面的變數用?佔位符替代),第三個引數就是?佔位符的實際引數的陣列.
2.query(Connection conn, String sql, ResultSetHandler rsh, Object… params) ,用來完成表資料的查詢操作
ResultSetHandler rsh 是結果集的處理方式,傳遞ResultSetHandler介面實現類
Object…params sql語句中的?佔位符
注意:
query方法的返回值,返回的是T,是泛型,具體返回值型別,隨著結果集處理方式變化

操作演示:
//ExceptionInInitializerError 靜態初始化異常
    //主要原因 沒有匯入mysql-connection這個jar包
    private static Connection conn = JDBCConfig.getConnection();
    public static void main(String[] args) throws SQLException {
            //insert();
        //update();
        delete();

    }
    public static void delete
() throws SQLException { QueryRunner qr = new QueryRunner(); String sql = "DELETE FROM sort WHERE sid=10"; int line = qr.update(conn, sql); if(line > 0) { System.out.println("刪除成功"); }else { System.out.println("刪除失敗"); } DbUtils.closeQuietly(conn); } //修改操作 public static void update()throws SQLException { QueryRunner qr = new QueryRunner(); String sql = "UPDATE sort SET sname=?,sprice=?,sdesc=? WHERE sid=?"; Object[] params = {"足療",3000,"呵呵呵",12}; int line = qr.update(conn, sql, params); System.out.println(line); DbUtils.closeQuietly(conn); } //插入操作 public static void insert() throws SQLException { QueryRunner qr = new QueryRunner(); String sql = "INSERT INTO sort(sname,sprice,sdesc) VALUES(?,?,?)"; Object[] params = {"外賣",30,"好吃不貴"}; int line = qr.update(conn, sql, params); System.out.println(line); DbUtils.closeQuietly(conn); } }

5.ResultSetHandler(是一個介面)結果集處理

下面這些是實現這個介面的一些方法
ArrayHandler 將結果集中的第一條記錄封裝到一個Object[]陣列中,陣列中的每一個元素就是這條記錄中的每一個欄位的值
ArrayListHandler 將結果集中的每一條記錄都封裝到一個Object[]陣列中,將這些陣列在封裝到List集合中。
BeanHandler 將結果集中第一條記錄封裝到一個指定的javaBean中。
BeanListHandler 將結果集中每一條記錄封裝到指定的javaBean中,將這些javaBean在封裝到List集合中
ColumnListHandler 將結果集中指定的列的欄位值,封裝到一個List集合中
ScalarHandler 它是用於單資料。例如select count(*) from 表操作。
MapHandler 將結果集第一行封裝到Map集合中,Key 列名, Value 該列資料
MapListHandler 將結果集第一行封裝到Map集合中,Key 列名, Value 該列資料,Map集合儲存到List集合

6.JavaBean概述:

就是一個類,在開發中常用封裝資料。具有如下特性
1.需要實現介面:java.io.Serializable ,通常實現介面這步驟省略了,不會影響程式。
2.提供私有欄位:private 型別 欄位名; //對應的資料庫表中的欄位
3.提供getter/setter方法:
4.提供無參構造 //必須提供

7.連線池

為了解決”獲得連線”或”釋放資源”的效能問題,共享連線Connection
概述
用池管理連線,可以實現重複使用連線,對於多併發的時候有較好的效能
怎麼獲取連線
從連線池中獲取,用完再歸還給連線池
這裡寫圖片描述

規範:
連線池必須實現介面:
javax.sql.DataSource
常見的連線池:DBCP,C3P0

8.DBCP(Database Connection Pool)概述:

是資料庫連線池的一種,通過連線池可以讓程式自動的管理資料庫的連線和釋放,Tomcat當中內建了這個連線池
Tomcat是什麼?
是JavaWeb伺服器,我們需要把我們寫好的class檔案,放在Tomcat軟體中,當開啟Tomcat的時候會監聽埠80.

匯入jar包
dbcp 和pool的jar包
DBCP連線池的使用:

/*
 * 
 連線池的jar包中,定義好一個類BasicDataSource
 實現了資料來源的規範介面javax.sql.DataSource
 */
public class DBCP_Demo {
    public static void main(String[] args) {

        // 建立DataSource介面的實現類物件
        // 實現類,org.apache.commons.dbcp
        BasicDataSource dataSource = new BasicDataSource();
        // 連線資料庫的4個基本資訊,通過物件方法SetXXX設定進來
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/mybase");
        dataSource.setUsername("root");
        dataSource.setPassword("123");
        // 呼叫物件的方法getConnection方法獲取資料庫的連線
        try {
            Connection connection = dataSource.getConnection();
            System.out.println(connection);
        } catch (SQLException ex) {
            // 這些資訊是給開發者使用,幫助找到錯誤是在哪.
            ex.printStackTrace();
            System.out.println(ex);// 錯誤資訊較短
            // 資料庫連線不上,就拋執行時異常,因為資料庫都連線不上,下邊的操作就沒任何用.
            // throw丟擲來的資訊是給使用者看的
            throw new RuntimeException("資料庫連線失敗");
        }
    }
}

9.BasicDataSource類的常見配置

這裡寫圖片描述

10.DBCP連線池實現資料庫連線池的工具類

/*
 * 
使用DBCP實現資料庫連線池
連線池配置,自定義類
最基本的四項必須有
對於資料庫連線池其他配置,自定義
 */
public class DBCPUtils {
    //創建出BasicDataSource
    private static BasicDataSource dataSource = new BasicDataSource();

    //靜態程式碼塊
    static {
        //資料庫連線必須的
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/mybase");
        dataSource.setUsername("root");
        dataSource.setPassword("123");
        ////物件連線池中的連線數量配置,可選擇的
        dataSource.setMaxActive(10);//最大連線數量
        dataSource.setMinIdle(5);//最小空閒連線
        dataSource.setMaxIdle(8);//最大空閒連線
        dataSource.setInitialSize(3);//初始化連線
    }
    ////定義靜態方法,返回BasicDataSource類的父介面DataSource
    public static DataSource getDataSource(){
        return dataSource;
    }
}

11測試工具類(插入和查詢操作)

/*
 * 
 測試寫好的工具類
 提供的是一個DataSource介面的資料來源
 QueryRunner類構造方法,接收DataSource介面的實現類
 後面,呼叫方法update,query,無需傳遞他們COnnection連線物件
 */
public class TestDbCPUtils {
    private static QueryRunner qr = new QueryRunner(DBCPUtils.getDataSource());

    public static void main(String[] args) {
        // 定義兩個方法,實現資料表的新增,資料表的查詢
        // QueryRunner類物件,解除安裝類成員位置
        //insert();
        select();
    }
    public static void select() {
        //查詢語句
        String sql = "SELECT *FROM sort";
        try{
            //獲得查詢結果集的集合存入到ArrayList集合中
        List<Object[]> list = qr.query(sql, new ArrayListHandler());
        //兩次遍歷得到每一個元素
        for (Object[] objects : list) {
            for (Object object : objects) {
                System.out.print(object+"\t");
            }
            System.out.println();
        }
        }catch(SQLException ex) {
            ex.printStackTrace();
            throw new RuntimeException("查詢失敗");
        }
    }
    public static void insert() {
        String sql = "INSERT INTO sort(sname,sprice,sdesc) VALUES(?,?,?)";
        Object[] params = {"堅果",699,"核桃碧根果"};
        try{
            int update = qr.update(sql, params);
            System.out.println(update);
        }catch(SQLException ex) {
            ex.printStackTrace();
            throw new RuntimeException("新增資料失敗");
        }
    }
}

12查詢之後結果集中處理方法

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;
import org.apache.commons.dbutils.handlers.ArrayListHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import com.bean.Sort;
import com.jdbc.JDBCProperties;

public class Demo2_ResultSetHandler {
    private static Connection conn = JDBCProperties.getConnection();

    public static void main(String[] args) throws SQLException {
        // ArrayHandler();
        // ArrayListHandler();
        //BeanHandler();
        //BeanListHandler();
        //MapHandler();
        // MapListHandler();
        //ColumnListHandler();
        ScalarHandler();
    }

    /*
     * 結果集的第一種處理方法,ArrayHandler(是ResultSetHandler的實現類) 將結果集的第一行儲存到物件陣列中Object[]
     */
    public static void ArrayHandler() throws SQLException {
        QueryRunner qr = new QueryRunner();
        String sql = "SELECT *FROM sort";
        // 這個地方導包的時候一定要注意是:org.apache.commons.dbutils.handlers.ArrayHandler;
        Object[] result = qr.query(conn, sql, new ArrayHandler());
        for (Object object : result) {
            System.out.print(object + "\t");
        }
    }
/*
 * 
 * 第二種處理方法 ArrayListHandler 將結果集的每一行,封裝到物件陣列中,會出現很多物件 陣列, 物件陣列儲存到List集合
 */
public static void ArrayListHandler() throws SQLException {
    QueryRunner qr = new QueryRunner();
    String sql = "SELECT *FROM sort";
    List<Object[]> result = qr.query(conn, sql, new ArrayListHandler());
    for (Object[] objects : result) {
        for (Object object : objects) {
            System.out.print(object + "\t");
        }
        System.out.println();
    }
}

/*
 * 第三種處理方法 BeanHandler 將結果的第一行資料,封裝成JavaBean物件
 * 注意:被封裝成資料到JavaBean物件,Sort類必須有空參構造
 */
public static void BeanHandler() throws SQLException {
    QueryRunner qr = new QueryRunner();
    String sql = "SELECT *FROM sort";

    // 呼叫方法,傳遞結果集實現類BeanHandler
    // BeanHandler(Class<T>(type))
    /**
     * 
     BeanHandler結果集,資料表第一行,封裝到JavaBean物件中,結果集第一行封裝成Sort類物件 Sort s = new
     * Sort(sid ,sname,..) BeanHandler(Class c
     * )傳遞Sort類的class檔案的物件Sort.class內部,獲取到了傳遞的Sort.class檔案物件,反射,建立物件
     */
    Sort result = qr.query(conn, sql, new BeanHandler<Sort>(Sort.class));
    // Sort [sid=1, sname=家電, sprice=3000.0, sdesc=降價了!!!!!]
    System.out.println(result);
}
public static void BeanListHandler() throws SQLException{
    QueryRunner qr = new QueryRunner();
    String sql = "SELECT *FROM sort";
    List<Sort> result = qr.query(conn, sql, new BeanListHandler<Sort>(Sort.class));

    //遍歷結果集
    for (Sort sort : result) {
        System.out.println(sort);
    }
}

public static void MapHandler() throws SQLException{
    QueryRunner qr = new QueryRunner();
    String sql = "SELECT *FROM sort";
    Map<String, Object> result = qr.query(conn, sql, new MapHandler());
    //拿到的是第一列的集合,只是以鍵值對的形式出現,鍵為資料表的標題,值就是新增的資料
    Set<String> set = result.keySet();
    for (String key : set) {

        Object value = result.get(key);
        System.out.println(key+" = "+value);
    }
}

public static void MapListHandler() throws SQLException{
    QueryRunner qr = new QueryRunner();
    String sql = "SELECT *FROM sort";
    List<Map<String, Object>> result = qr.query(conn, sql, new MapListHandler());
    //拿到的是第一列的集合,只是以鍵值對的形式出現,鍵為資料表的標題,值就是新增的資料

    for (Map<String, Object> map : result) {
        Set<String> set = map.keySet();
        for (String key : set) {
            Object value = map.get(key);
            System.out.print(key+" = "+value);
        }
        System.out.println();
    }

}

public static void ColumnListHandler() throws SQLException{
    QueryRunner qr = new QueryRunner();
    String sql = "SELECT *FROM sort";
    //獲取指定列的所有資料
    Object result = qr.query(conn, sql, new ColumnListHandler<>(2));

    System.out.println(result);

}

// ScalarHandler

public static void ScalarHandler() throws SQLException{
    QueryRunner qr = new QueryRunner();
    String sql = "SELECT *FROM sort";
    //獲取第一行的第幾個資料,給個2就是獲取第一行的第二個資料,只能獲取到第一行當中的資料
    Object result = qr.query(conn, sql, new ScalarHandler<>(2));

    System.out.println(result);

}

}

13.Scanner類中next方法和nextLine方法的區別

1.next()方法
next()一定要讀取到有效字元後才可以結束輸入,對輸入有效字元之前遇到的空格鍵、Tab鍵或Enter鍵等結束符,next()方法會自動將其去掉,只有在輸入有效字元之後,next()方法才將其後輸入的空格鍵、Tab鍵或Enter鍵等視為分隔符或結束符。

簡單地說,next()查詢並返回來自此掃描器的下一個完整標記。完整標記的前後是與分隔模式匹配的輸入資訊,所以next方法不能得到帶空格的字串。
2.nextLine()方法
而nextLine()方法的結束符只是Enter鍵,即nextLine()方法返回的是Enter鍵之前的所有字元,它是可以得到帶空格的字串的。