JDBC高級和DbUtils

JDBC高級和DbUtils

1. BaseDao方法補充

1.1 爲什麼要提供該方法
	完成一個查詢返回值類型是Object[],並且是存儲於List集合中的一種方式,實際返回值類型是 List<Object[]>
	處理的是查詢數據結果無法映射到類對象中,ORM,所有的數據按照查詢結果字段順序要求從數據庫讀取數據保存到Object數組,爲了能滿足多行數據查詢要求,Object數組存儲到List中
1.2 方法分析
分析:
	權限修飾符:
		public
	返回值類型:
		List<Object[]>
	方法名:
		query
	形式參數列表:
		String sql select查詢語句
		對應當前SQL語句的參數
方法聲明:
	public List<Object[]> query(String sql, Object[] parameters)
/**
 * 通用查詢方法,返回值是對應字段數據的Object類型數組,並且存儲於List集合
 *
 * @param sql        Select查詢SQL語句
 * @param parameters 對應當前SQL語句的參數
 * @return 包含數據行數據的List<Object[]> 如果沒有查詢到數據,返回null
 */
public List<Object[]> query(String sql, Object[] parameters) {
    ResultSet resultSet = null;
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    List<Object[]> list = new ArrayList<>();
    try {
        connection = JdbcUtil.getConnection();
        preparedStatement = connection.prepareStatement(sql);
        /*
        獲取SQL語句參數個數!!!通過SQL語句元數據獲取(ParameterMetaData)
         */
        int parameterCount = preparedStatement.getParameterMetaData().getParameterCount();
        /*
        parameterCount 參數個數不能爲0
        parameters != null 參數數組不爲null,因爲存在當前方法沒有參數,數組傳入null
        parameterCount == parameters.length 參數個數和傳入的Object類型參數數容量一致
         */
        if (parameterCount != 0 && parameters != null && parameterCount == parameters.length)
            for (int i = 0; i < parameters.length; i++) {
                /*
                SQL語句參數下標從1開始
                數組數據下標從0開始
                 */
                preparedStatement.setObject(i + 1, parameters[i]);
            }
        }
        resultSet = preparedStatement.executeQuery();
        ResultSetMetaData metaData = resultSet.getMetaData();
        int columnCount = metaData.getColumnCount();
        while (resultSet.next()) {
            Object[] values = new Object[columnCount];
            for (int i = 1; i <= columnCount; i++) {
                values[i - 1] = resultSet.getObject(i);
            }
            list.add(values);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        JdbcUtil.close(connection, preparedStatement, resultSet);
    }
    return list.size() != 0 ? list : null;
}
1.3 BaseDao優化
// Ctrl + Alt + M 光標選擇代碼塊生成一個方法
/**
 * 類內私有化處理PreparedStatement預處理SQL語句和參數數組賦值操作
 *
 * @param preparedStatement 預處理SQL語句對應的PreparedStatement對象
 * @param parameters        對應當前SQL語句的Object類型數組
 * @throws SQLException SQL異常
 */
private void parseSqlParameter(PreparedStatement preparedStatement, Object[] parameters) throws SQLException {
    /*
    獲取SQL語句參數個數!!!通過SQL語句元數據獲取(ParameterMetaData)
    */
    int parameterCount = preparedStatement.getParameterMetaData().getParameterCount();
    
    /*
    parameterCount 參數個數不能爲0
    parameters != null 參數數組不爲null,因爲存在當前方法沒有參數,數組傳入null
    parameterCount == parameters.length 參數個數和傳入的Object類型參數數容量一致
    */
    if (parameterCount != 0 && parameters != null && parameterCount == parameters.length) {
        for (int i = 0; i < parameters.length; i++) {
            /*
            SQL語句參數下標從1開始
            數組數據下標從0開始
            */
            preparedStatement.setObject(i + 1, parameters[i]);
        }
    }
}

2. 項目使用JdbcUitl,BaseDao完成數據持久化操作

2.1 需求
	使用數據庫作爲數據持久化操作是一個非常非常常見。剝離原本的數據保存方式,之前數據保存使用的是Json個數文件,並且使用到Dao層
	項目Dao層需要繼承BaseDao完成對於數據的操作CRUD。並且數據庫和當前項目中的實體類是對應關係:
	數據表 ==> 實體類名一致 
	字段名 ==> 成員變量名 
	數據類型 ==> 成員變量數據類型
	
	完成一個簡版Student管理系統
	dao
		interface StudentDao
		impl(package)
			StudentDaoImpl
	service
		interface StudentService
		impl(package)
			StudentServiceImpl
	view
		interface ProjectView
		impl(package)
			ProjectViewImpl
	mainproject
		main方法
2.2 數據庫設計
字段 數據類型
id int PRI AI
name varchar(50) NN
age int NN
gender boolean NN
score float(5, 2) NN
address text NN
2.3 Student實體類
2.4 StudentDao規範
2.5 StudentDaoImpl實現
2.6 StudentService規範
2.7 StudentServiceImpl實現
2.8 StudentView規範
2.9 StudentViewImpl實現
2.10 StudentController實現
2.11 StudentProject main方法

在這裏插入圖片描述

3. 輕量級數據庫ORM框架DbUtils

3.1 DbUtils介紹
	Apache組織下的一個輕量級ORM框架
	Commons DbUtils: JDBC Utility Component
兩個核心方法
	update方法 ==> insert,update,delete
	query方法 ==> select

一個核心類
	QueryRunner DbUtils的核心類
3.2 DbUtils ORM工具使用
package com.qfedu.c_dbutils;

import com.qfedu.b_studentsys.entity.Student;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.*;
import org.junit.Test;
import util.JdbcUtil;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * DbUtils ORM框架演示
 *
 * @author Anonymous 2020/3/25 16:03
 */
public class DbUtilsTest {
    @Test
    public void testInsert() throws SQLException {
        // 1. DbUtils核心類 QueryRunner對象
        QueryRunner runner = new QueryRunner();

        // 2. 插入數據到Student數據表中
        String sql = "insert into student(name, age, gender, score, address) value(?, ?, ?, ?, ?)";
        Object[] parameters = {"老黑", 70, true, 59, "河南鄭州"};

        // 3. 獲取數據庫連接
        Connection connection = JdbcUtil.getConnection();

        // 4. 執行Update方法
        runner.update(connection, sql, parameters);

        JdbcUtil.close(connection);
    }

    /**
     * 瞭解操作方式, ResultSetHandler
     */
    @Test
    public void testQuery1() throws SQLException {
        // 1. DbUtils核心類 QueryRunner對象
        QueryRunner runner = new QueryRunner();

        // 2. SQL語句
        String sql = "select * from student where id = 1";

        Connection connection = JdbcUtil.getConnection();

        /*
         ResultSetHandler 核心接口
            ResultSet結果集 Handler處理,
            核心方法 handler(ResultSet rs)
         */
        Student student = runner.query(connection, sql, rs -> {
            Student stu = null;
            if (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                int age = rs.getInt("age");
                boolean gender = rs.getBoolean("gender");
                float score = rs.getFloat("score");
                String address = rs.getString("address");

                stu = new Student(id, name, age, gender, score, address);
            }
            return stu;
        });

        System.out.println(student);
        JdbcUtil.close(connection);
    }

    /**
     * BeanHandler
     */
    @Test
    public void queryBean() throws SQLException {
        // 1. DbUtils核心類 QueryRunner對象
        QueryRunner runner = new QueryRunner();

        // 2. SQL語句
        String sql = "select * from student where id = 1";

        Connection connection = JdbcUtil.getConnection();

        /*
        BeanHandler: 處理符合JavaBean規範的類對象,傳入參數是對應JavaBean規範 Class對象
         */
        Student student = runner.query(connection, sql, new BeanHandler<>(Student.class));

        System.out.println(student);

        JdbcUtil.close(connection);
    }

    /**
     * BeanListHandler
     */
    @Test
    public void queryBeanList() throws SQLException {
        // 1. DbUtils核心類 QueryRunner對象
        QueryRunner runner = new QueryRunner();

        // 2. SQL語句
        String sql = "select * from student where id > ?";

        Connection connection = JdbcUtil.getConnection();

        /*
        BeanListHandler: 處理符合JavaBean規範的實體類,並且返回值是一個List集合
        包含制定的JavaBean實體類
         */
        List<Student> list = runner.query(connection, sql, new BeanListHandler<>(Student.class), 2);

        for (Student student : list) {
            System.out.println(student);
        }
        JdbcUtil.close(connection);
    }

    /**
     * ArrayHandler
     */
    @Test
    public void queryArray() throws SQLException {
        // 1. DbUtils核心類 QueryRunner對象
        QueryRunner runner = new QueryRunner();

        // 2. SQL語句
        String sql = "select * from student where id = 1";

        Connection connection = JdbcUtil.getConnection();

        /*
        ArrayHandler: 查詢一個數據行,數據行中的所有數據整合成一個Object類型數組返回
         */
        Object[] values = runner.query(connection, sql, new ArrayHandler());

        System.out.println(Arrays.toString(values));

        JdbcUtil.close(connection);
    }

    /**
     * ArrayListHandler
     */
    @Test
    public void queryArrayList() throws SQLException {
        // 1. DbUtils核心類 QueryRunner對象
        QueryRunner runner = new QueryRunner();

        // 2. SQL語句
        String sql = "select * from student where id > ?";

        Connection connection = JdbcUtil.getConnection();

        /*
        ArrayListHandler: 查詢結果集中所有數據行,每一行數據對應一個Object類型數組,存儲在List集合中
         */
        List<Object[]> list = runner.query(connection, sql, new ArrayListHandler(), 2);

        for (Object[] values : list) {
            System.out.println(Arrays.toString(values));
        }
        JdbcUtil.close(connection);
    }

    /**
     * MapHandler
     */
    @Test
    public void queryMap() throws SQLException {
        // 1. DbUtils核心類 QueryRunner對象
        QueryRunner runner = new QueryRunner();

        // 2. SQL語句
        String sql = "select * from student where id = 1";

        Connection connection = JdbcUtil.getConnection();

        /*
        MapHandler: 處理一個數據行,數據行中字段是對應Key,字段對應數據是value,組成一個Map雙邊隊列
         */
        Map<String, Object> map = runner.query(connection, sql, new MapHandler());

        System.out.println(map);
    }

    /**
     * MapListHandler
     */
    @Test
    public void queryMapList() throws SQLException {
        // 1. DbUtils核心類 QueryRunner對象
        QueryRunner runner = new QueryRunner();

        // 2. SQL語句
        String sql = "select * from student where id > ?";

        Connection connection = JdbcUtil.getConnection();

        /*
        MapListHandler: 結果集中所有的數據行,每一行對應一個Map對象,字段名爲Key,字段對應的數據爲value,所有數據行存儲
        在List中
         */
        List<Map<String, Object>> mapList = runner.query(connection, sql, new MapListHandler(), 2);

        for (Map<String, Object> map : mapList) {
            System.out.println(map);
        }
    }
}

3.3 ResultHandler以及其子類
ResultSetHandler 核心接口
	ResultSet結果集 Handler處理,	
	核心方法 handler(ResultSet rs)
 
BeanHandler: 
	處理符合JavaBean規範的類對象,傳入參數是對應JavaBean規範 Class對象

BeanListHandler: 
	處理符合JavaBean規範的實體類,並且返回值是一個List集合包含制定的JavaBean實體類

ArrayHandler: 
	查詢一個數據行,數據行中的所有數據整合成一個Object類型數組返回

ArrayListHandler: 
	查詢結果集中所有數據行,每一行數據對應一個Object類型數組,存儲在List集合中

MapHandler: 
	處理一個數據行,數據行中字段是對應Key,字段對應數據是value,組成一個Map雙邊隊列

MapListHandler: 
	結果集中所有的數據行,每一行對應一個Map對象,字段名爲Key,字段對應的數據爲value,所有數據行存儲在List中
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章