Java學習日誌(三十四): DbUtils工具包的使用,四種常用Handler結果集

JavaEE學習日誌持續更新----> 必看!JavaEE學習路線(文章總彙)

DbUtils工具包

DbUtisl介紹

作用:使用apache commons組件DbUtils對數據庫表進行增刪改查(簡化原生JDBC6步)

  • org.apache.commons.dbutils.QueryRunner類:用於執行sql語句
  • org.apache.commons.dbutils.DbUtils類:用於釋放資源
  • org.apache.commons.dbutils.ResultSetHandler接口:用於接收查詢的結果集

QueryRunner類使用
構造方法

  • QueryRunner():空參構造,調用update/query方法執行sql語句時,必須傳遞Connection對象
  • QueryRunner(DataSource ds)帶連接池的構造方法,調用update/query方法執行sql語句時,無需傳遞Connection對象

注意:QueryRunner執行sql語句時,會自動在連接池獲取連接使用,使用完畢,會自動把連接歸還給連接池

成員方法

  • 用於執行增刪改的update方法
  1. int update(Connection conn,String sql,Object... params) 空參構造使用

  2. int update(String sql,Object... params) 帶連接池的構造方法使用

     參數:
        Connection conn:數據庫連接對象,可以使用C3P0連接池獲取。
        String sql:sql語句,可以使用?佔位符。
        Object... params:?佔位符的實際參數。
     返回值:
        int:影響數據庫的有效行數。
    
  • 用於執行查詢的Query方法:
  1. T query(Connection conn,String sql,ResultSetHandler<T> rsh,Object... params) 空參構造使用

  2. T query(String sql,ResultSetHandler<T> rsh,Object... params) 帶連接池的構造方法使用

     參數:
        Connection conn:數據庫連接對象,可以使用C3P0連接池獲取。
        String sql:sql語句,可以使用?佔位符。
        ResultSetHandler<T> rsh:用來接收查詢結果的結果集,可以傳遞ResultSetHandler接口的實現類。
        Object... params:?佔位符的實際參數。
     返回值:
        T:傳遞ResultSetHandler接口的實現類不同,QueryRunner處理查詢結果的方式也不同,會返回不同的結果,
           傳遞哪種結果集,就返回對應的處理結果。
    

使用DbUtisl工具包對數據庫進行增刪改

使用的數據庫表:
在這裏插入圖片描述

使用步驟:

  1. 創建QueryRunner對象
  2. 調用QueryRunner對象中的方法update/query執行sql語句,接收結果
  3. 處理結果

代碼示例:不帶連接池的QueryRunner(),使用增加數據(刪改與之相同)

@Test
    public void testInsert() throws SQLException {
        //1.創建QueryRunner對象
        QueryRunner qr = new QueryRunner();
        //2.調用QueryRunner對象中的方法update/query執行sql語句,接收結果
        //int update(Connection conn,String sql,Object... params) 空參構造使用
        Connection conn = C3P0UtilsXML.getConnection();
        String sql = "INSERT INTO product(pid,pname,price,category_id) VALUES(?,?,?,?);";
        int row = qr.update(conn, sql, 14, "優樂美奶茶", 3, "c005");
        //3.處理結果
        System.out.println(row+"行數據添加成功!");
        //把連接歸還給連接池
        DbUtils.closeQuietly(conn);
    }

重點帶連接池的QueryRunner(DataSource ds),使用修改進行示例

@Test
    public void testUpdate() throws SQLException {
        //1.創建QueryRunner對象
        QueryRunner qr = new QueryRunner(C3P0UtilsXML.getDataSource());
        //2.調用QueryRunner對象中的方法update/query執行sql語句,接收結果
        String sql = "UPDATE product SET price = ? WHERE pid = ?;";
        int row = qr.update(sql, 10, 14);
        //3.處理結果
        System.out.println(row+"行數據添加成功!");
    }

使用DbUtisl工具包對數據庫進行查詢

結果集使用BeanHandler

實現類BeanHandler
使用方式:
把查詢的多行結果的第一行取出來,存儲到一個javabean對象中返回

構造方法
BeanHandler(Class<T> type):傳遞javabean的class文件對象,傳遞Product.class
構造方法的內部原理

  1. 使用反射技術,根據傳遞的class文件對象,創建javabean對象
    Object obj = clazz.newInstance();
  2. 使用反射技術,爲對象的每個成員賦值
    Method setNameMethod = clazz.getMethod("setXXX",String.class);
    Object v2 = setNameMethod.invoke(obj,"xxx");

T query(String sql,ResultSetHandler<T> rsh,Object... params) 帶連接池的構造方法使用

返回值
T:傳遞哪個javabean的class文件對象,就返回哪個javabean對象(含有第一行值),傳遞Product.class就返回Product對象

使用前提
類中必須有空參構造方法

代碼示例:Product類的javabean

import java.io.Serializable;

/*
    創建數據庫product的javabean類
    數據庫表與java中類的對應關係
        有product表-->Product類
        表中的列-->類中的成員變量
        表中的行-->Product對象-->多個對象存儲到集合中
 */
public class Product implements Serializable {
    //商品主鍵
    private int pid;
    //商品名稱
    private String pname;
    //商品價格
    private double price;
    //商品分類
    private String category_id;

    public Product() {
    }

    @Override
    public String toString() {
        return "Product{" +
                "pid=" + pid +
                ", pname='" + pname + '\'' +
                ", price=" + price +
                ", category_id='" + category_id + '\'' +
                '}';
    }

    public int getPid() {
        return pid;
    }

    public void setPid(int pid) {
        this.pid = pid;
    }

    public String getPname() {
        return pname;
    }

    public void setPname(String pname) {
        this.pname = pname;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getCategory_id() {
        return category_id;
    }

    public void setCategory_id(String category_id) {
        this.category_id = category_id;
    }
}

測試

@Test
    public void testBeanHandler() throws SQLException {
        //1.創建QueryRunner對象
        QueryRunner qr = new QueryRunner(C3P0UtilsXML.getDataSource());
        //2.使用QueryRunner對象中的方法query,執行sql語句,獲取結果
        String sql = "select * from product;";
        Product p = qr.query(sql, new BeanHandler<>(Product.class));
        //3.處理結果
        System.out.println(p);
    }

結果:把查詢的多行結果的第一行取出來,只取出第一行
在這裏插入圖片描述

結果集使用BeanListHandler

實現類BeanListHandler
使用方式:把查詢的多行結果,存儲到多個javabean對象中,多個javabean對象存儲到list集合中。

構造方法:
BeanListHandler(Class<T> type):傳遞javabean的class文件對象,傳遞Product.class
內部實現:也是使用反射技術

T query(String sql,ResultSetHandler<T> rsh,Object... params) 帶連接池的構造方法使用
返回值:
T:傳遞哪個javabean的class文件對象,就存儲javabean對象的List集合,傳遞Product.class就返回List

使用前提:
類中必須有空參構造方法

代碼示例:測試

@Test
    public void testBeanListHandler() throws SQLException {
        //1.創建QueryRunner對象
        QueryRunner qr = new QueryRunner(C3P0UtilsXML.getDataSource());
        //2.使用QueryRunner對象中的方法query,執行sql語句,獲取結果
        String sql = "select * from product;";
        List<Product> listP = qr.query(sql, new BeanListHandler<>(Product.class));
        //3.處理結果
        for (Product p : listP) {
            System.out.println(p);
        }
    }

結果:查詢多行數據
在這裏插入圖片描述

結果集使用ScalarHandler

實現類ScalarHandler
使用方式:用於接收sql語句是單一返回值的情況

  • 聚合函數:sum,avg,count,max,min
  • 獲取某一行的某一個字段的值:select pname from product where pid = ?;

T query(String sql,ResultSetHandler<T> rsh,Object... params) 帶連接池的構造方法使用
返回值
T:返回值類型多種類型,所以使用Object類型來接收這個值。

代碼示例:

@Test
    public void testScalarHandler() throws SQLException {
        //1.創建QueryRunner對象
        QueryRunner qr = new QueryRunner(C3P0UtilsXML.getDataSource());
        //2.調用QueryRunner對象中的方法query執行sql語句,獲取結果
        //String sql = "select count(*) from product;";
        String sql = "select pname from product where pid = ?;";
        Object obj = qr.query(sql, new ScalarHandler(),10);
        //3.處理結果集
        //System.out.println(obj);//14
        System.out.println(obj);//麪霸
    }

結果集使用ColumnListHandler

實現類ColumnListHandler
使用方式:用於查詢指定的,把指定列的數據存儲到一個list集合中返回

構造方法

  • ColumnListHandler() 沒有指定列,默認查詢第1列
  • ColumnListHandler(int columnIndex) 指定列的索引,從第1列開始
  • ColumnListHandler(String columnName) 指定列名

T query(String sql,ResultSetHandler<T> rsh,Object... params) 帶連接池的構造方法使用
返回值:
T返回存儲列中數據的List集合,因爲列的數據類型有多種,集合的泛型使用Object, List < Object>

注意查詢的結果必須包含指定的列,否則會報SQLException異常:Column 'xxx' not found。

代碼示例:ColumnListHandler() 沒有指定列,默認查詢第1列

@Test
    public void testColumnListHandler() throws SQLException {
        //1.創建QueryRunner對象
        QueryRunner qr = new QueryRunner(C3P0UtilsXML.getDataSource());
        ////2.調用QueryRunner對象中的方法query執行sql語句,獲取結果
        String sql = "select * from product";
        List<Object> list = qr.query(sql, new ColumnListHandler());//沒有指定列,默認查詢第1列
        //3.處理結果集
        for (Object obj : list) {
            System.out.println(obj);
        }
    }

結果
在這裏插入圖片描述

ColumnListHandler(int columnIndex) 指定列的索引爲第2列
ColumnListHandler(String columnName) 指定列名爲pname

@Test
    public void testColumnListHandler() throws SQLException {
        //1.創建QueryRunner對象
        QueryRunner qr = new QueryRunner(C3P0UtilsXML.getDataSource());
        ////2.調用QueryRunner對象中的方法query執行sql語句,獲取結果
        String sql = "select * from product";
        //List<Object> list = qr.query(sql, new ColumnListHandler());//沒有指定列,默認查詢第1列
        //List<Object> list = qr.query(sql, new ColumnListHandler(2));//列的索引爲2,pname
        List<Object> list = qr.query(sql, new ColumnListHandler("pname"));//列的索引爲2,pname
        //3.處理結果集
        for (Object obj : list) {
            System.out.println(obj);
        }
    }

結果
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章