JDBC高級

JDBC高級

1. Statement操作SQL語句

1.1 Statement查詢SQL數據操作
// 查詢指定的一個數據行,轉換成對應的User對象
@Test
public void testSelectOne() {
    ResultSet resultSet = null;
    Statement statement = null;
    Connection connection = null;
    User user1 = null;
    try {
        // 1. 加載驅動
        Class.forName("com.mysql.jdbc.Driver");
        // 2. 準備必要的連接數據
        String url = "jdbc:mysql://localhost:3306/nzgp2001?useSSL=true";
        String user = "root";
        String password = "123456";
        // 3. 獲取數據庫連接
        connection = DriverManager.getConnection(url, user, password);
        // 4. 準備SQL語句
        String sql = "select * from nzgp2001.user where id = 1";
        // 5. 獲取Statement對象
        statement = connection.createStatement();
        // 6. 執行SQL語句
        resultSet = statement.executeQuery(sql);
        // 7. ResultSet結果集對象解析過程
        while (resultSet.next()) {
            // 通過指定的字段獲取對應的數據
            int id = resultSet.getInt("id");
            String userName = resultSet.getString("userName");
            String password1 = resultSet.getString("password");
            user1 = new User(id, userName, password1);
            System.out.println(user1);
        }
    } catch (ClassNotFoundException | SQLException e) {
        e.printStackTrace();
    } finally {
        // 7. 關閉資源
        try {
            if (resultSet != null) {
                resultSet.close();
            }
            if (statement != null) {
                statement.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
// 查詢多個數據
@Test
public void testSelectAll() {
    ResultSet resultSet = null;
    Statement statement = null;
    Connection connection = null;
    // 準備了一個存儲User對象的List集合
    List<User> list = new ArrayList<>();
    try {
        // 1. 加載驅動
        Class.forName("com.mysql.jdbc.Driver");
        // 2. 準備必要的連接數據
        String url = "jdbc:mysql://localhost:3306/nzgp2001?useSSL=true";
        String user = "root";
        String password = "123456";
        // 3. 獲取數據庫連接
        connection = DriverManager.getConnection(url, user, password);
        // 4. 準備SQL語句
        String sql = "select * from nzgp2001.user";
        // 5. 獲取Statement對象
        statement = connection.createStatement();
        // 6. 執行SQL語句
        resultSet = statement.executeQuery(sql);
        // 7. ResultSet結果集對象解析過程
        while (resultSet.next()) {
            // 通過指定的字段獲取對應的數據
            int id = resultSet.getInt("id");
            String userName = resultSet.getString("userName");
            String password1 = resultSet.getString("password");
            // 從數據庫中讀取的User數據保存到對象中,添加到List內
            list.add(new User(id, userName, password1));
        }
        for (User user1 : list) {
            System.out.println(user1);
        }
    } catch (ClassNotFoundException | SQLException e) {
        e.printStackTrace();
    } finally {
        // 7. 關閉資源
        try {
            if (resultSet != null) {
                resultSet.close();
            }
            if (statement != null) {
                statement.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

2. JDBC工具類封裝

需要完成的內容
	1. 數據庫連接對象java.sql.Connection獲取過程
	2. 關閉資源

JDBC工具類
	1. 所有的方法都是static修飾的靜態方法
	2. 需要考慮自動加載過程,完成一些必要數據的自動處理
		url
		driver
		user
		password
	3. 所需數據庫連接條件保存到文件中
	4. 關閉方法提供多種多樣組合方法

【注意】
	db.properties文件保存到src目錄下
# 當前JDBC連接所需的驅動
driverClass=com.mysql.jdbc.Driver

# 數據庫連接符合JDBC規範的url
url=jdbc:mysql://localhost:3306/nzgp2001?useSSL=true

# 用戶名
user=root

# 密碼
password=123456
package util;

import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;

/**
 * JDBC工具類,負責數據庫連接對象和數據庫資源關閉
 *
 * @author Anonymous 2020/3/24 10:08
 */
public class JdbcUtil {
    // 靜態成員變量,保存一些必要的數據
    private static String url = null;
    private static String user = null;
    private static String password = null;


    // 利用static修飾的靜態代碼塊完成文件字段自動讀取和驅動自動加載過分
    static {
        try {
            // Properties實現類,裏面的數據保存形式都是鍵值對形式
            Properties properties = new Properties();

            // 使用字節輸入流,加載對應db.properties,數據保存到Properties對象中
            properties.load(new FileInputStream("./src/db.properties"));

            // 從Properties讀取對應的數據
            String driverClass = properties.getProperty("driverClass");
            url = properties.getProperty("url");
            user = properties.getProperty("user");
            password = properties.getProperty("password");

            // 完整驅動加載
            Class.forName(driverClass);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 返回數據庫連接對象,連接失敗返回null
     *
     * @return java.sql.Connection 數據庫連接對象
     */
    public static Connection getConnection() {
        Connection connection = null;

        try {
            // 通過DriverManager驅動管理類,使用必要參數獲取數據庫連接
            connection = DriverManager.getConnection(url, user, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return connection;
    }

    /*
    以下三個方法實際上都是執行同一個方法,使用這種方式
        1. 簡化代碼結構
        2. 規範化所有的操作
     */

    /**
     * 處理數據庫操作對應的資源問題
     *
     * @param connection java.sql.Connection 數據庫連接對象
     */
    public static void close(Connection connection) {
        close(connection, null, null);
    }

    /**
     * 處理數據庫操作對應的資源問題
     *
     * @param connection java.sql.Connection 數據庫連接對象
     * @param statement java.sql.Statement 數據庫SQL語句搬運工對象
     */
    public static void close(Connection connection, Statement statement) {
        close(connection, statement, null);
    }

    /**
     * 處理數據庫操作對應的資源問題
     *
     * @param connection java.sql.Connection 數據庫連接對象
     * @param statement java.sql.Statement 數據庫SQL語句搬運工對象
     * @param resultSet java.sql.ResultSet 數據庫查詢結果集對象
     */
    public static void close(Connection connection, Statement statement, ResultSet resultSet) {
        try {
            if (resultSet != null) {
                resultSet.close();
            }

            if (statement != null) {
                statement.close();
            }

            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

3. PreparedStatement使用

3.1 PreparedStatement插入數據SQL完成
@Test
public void testInsert() {
    User user = new User(10, "逗比匿名君", "123456");
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    try {
        // 獲取數據庫連接
        connection = JdbcUtil.getConnection();
        // 準備SQL語句
        // ? 表示SQL語句參數佔位符!!!
        String sql = "insert into nzgp2001.user(id, userName, password) VALUE (?,?,?)";
        // 預處理SQL語句,獲取PreparedStatement對象
        preparedStatement = connection.prepareStatement(sql);
        // SQL語句賦值操作,SQL語句參數是從1開始
        preparedStatement.setObject(1, user.getId());
        preparedStatement.setObject(2, user.getUserName());
        preparedStatement.setObject(3, user.getPassword());
        // 使用PreparedStatement執行SQL語句
        int affectedRows = preparedStatement.executeUpdate();
        System.out.println("affectedRows:" + affectedRows);
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        JdbcUtil.close(connection, preparedStatement);
    }
}
3.2 PreparedStatment修改SQL完成
@Test
public void testUpdate() {
    User user = new User(10, "逗比匿名君", "航海中路彭于晏");
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    try {
        connection = JdbcUtil.getConnection();
        String sql = "update user set userName = ?, password = ? where id = ?";
        preparedStatement = connection.prepareStatement(sql);
        // 賦值SQL語句參數
        preparedStatement.setObject(1, user.getUserName());
        preparedStatement.setObject(2, user.getPassword());
        preparedStatement.setObject(3, user.getId());
        int affectedRows = preparedStatement.executeUpdate();
        System.out.println("affectedRows:" + affectedRows);
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        JdbcUtil.close(connection, preparedStatement);
    }
}
3.3 PreparedStatment刪除SQL完成
@Test
public void testDelete() {
    int id = 7;
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    try {
        connection = JdbcUtil.getConnection();
        String sql = "delete from user where id = ?";
        preparedStatement = connection.prepareStatement(sql);
        // 賦值參數
        preparedStatement.setObject(1, id);
        int affectedRows = preparedStatement.executeUpdate();
        System.out.println("affectedRows:" + affectedRows);
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        JdbcUtil.close(connection, preparedStatement);
    }
}
3.4 PreparedStatment查詢SQL完成
@Test
public void testSelectOne() {
    int id = 10;
    User user = null;
    
    ResultSet resultSet = null;
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    
    try {
        connection = JdbcUtil.getConnection();
        String sql = "select * from user where id = ?";
        preparedStatement = connection.prepareStatement(sql);
        
        // 賦值參數
        preparedStatement.setObject(1, id);
        resultSet = preparedStatement.executeQuery();
        
        if (resultSet.next()) {
            String userName = resultSet.getString("userName");
            String password = resultSet.getString("password");
            user = new User(id, userName, password);
        }
        
        if (user != null) {
            System.out.println(user);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        JdbcUtil.close(connection, preparedStatement, resultSet);
    }
}
@Test
public void testSelectAll() {
    List<User> list = new ArrayList<>();
    
    ResultSet resultSet = null;
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    
    try {
        connection = JdbcUtil.getConnection();
        String sql = "select * from user";
        
        preparedStatement = connection.prepareStatement(sql);
        resultSet = preparedStatement.executeQuery();
        
        while (resultSet.next()) {
            int id = resultSet.getInt("id");
            String userName = resultSet.getString("userName");
            String password = resultSet.getString("password");
            list.add(new User(id, userName, password));
        }
        
        for (User user : list) {
            System.out.println(user);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        JdbcUtil.close(connection, preparedStatement, resultSet);
    }
}

4. SQL注入問題

	Statement是一個SQL語句搬運工對象,不存在SQL語句語預處理能力,Java代碼SQL語句原封不動搬運到數據庫!!!
	PreparedStatement 存在SQL語句預處理過程,這個過程可以有效的防止一定條件的SQL注入
	Statement存在SQL注入問題,而PreparedStatemen可以有效的避免SQL注入

牆裂推薦使用PreparedStatement
	1. PreparedStatement操作性更強
	2. PreparedStatement安全性更高
package com.qfedu.a_statement;

import util.JdbcUtil;

import java.sql.*;

/**
 * 使用Statement和PreparedStatement完成Select操作
 *
 * @author Anonymous 2020/3/24 11:07
 */
public class Demo1 {
    private static String userName = "逗比匿名君";
    private static String password = "fdafdsafdsa' or 1=1 -- ";

    public static void main(String[] args) {
        /*
        Statement是一個SQL語句搬運工對象,不存在SQL語句語預處理能力,Java代碼SQL語句原封不動搬運到數據庫!!!
        PreparedStatement 存在SQL語句預處理過程,這個過程可以有效的防止一定條件的SQL注入
        */
        statementSelect();
        preparedStatementSelect();
    }

    public static void statementSelect() {
        ResultSet resultSet = null;
        Statement statement = null;
        Connection connection = null;


        try {
            connection = JdbcUtil.getConnection();
            statement = connection.createStatement();

            // SQL語句準備
            String sql = "select * from user where userName = '" + userName + "' and password = '" + password + "'";
            /*
            select * from user where userName = '逗比匿名君' and password = 'fdafdsafdsa' or 1=1 -- '
            */

            resultSet = statement.executeQuery(sql);

            if (resultSet.next()) {
                System.out.println("Statement 登陸成功");
            } else {
                System.out.println("Statement 登陸失敗");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.close(connection, statement, resultSet);
        }
    }

    public static void preparedStatementSelect() {
        ResultSet resultSet = null;
        PreparedStatement preparedStatement = null;
        Connection connection = null;
        try {
            connection = JdbcUtil.getConnection();
            String sql = "select * from user where userName = ? and password = ?";

            preparedStatement = connection.prepareStatement(sql);

            preparedStatement.setObject(1, userName);
            preparedStatement.setObject(2, password);

            resultSet = preparedStatement.executeQuery();

            if (resultSet.next()) {
                System.out.println("PreparedStatement 登陸成功");
            } else {
                System.out.println("PreparedStatement 登陸失敗");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.close(connection, preparedStatement, resultSet);
        }
    }
}

5. BaseDao封裝

5.1 需求和問題
需求
	1. 完成通用的更新方法,滿足insert,update,delete操作
	2. 完成通用的查詢方法,滿足select

問題
	1. 數據庫連接對象獲取[解決]
	2. 資源關閉[解決]
	3. PreparedStatement參數賦值過程【未解決】
		a. 參數個數
			PreparedStatement預處理SQL語句?有多少個
		b. 賦值順序‘
			參數傳入方式和順序問題
	4. 查詢結果集解析過程【未解決】
		a. 返回值是一個List<目標數據類型>集合
		b. 返回值是一個Object數組
5.2 【補充知識點-元數據】
三種元數據
	數據庫元數據
		通過java.sql.Connection獲取對應的元數據
		
	SQL語句元數據
		通過java.sql.PreparedStatement獲取對應的元數據
		
	數據庫結果集元數據
		通過java.sql.ResultSet獲取對應的元數據
		
MetaData
【重點】
	1. SQL語句元數據,參數元數據其中的參數個數 對應 ? 佔位符個數
	2. 結果集元數據中的字段個數,和對應當前字段下標的字段名字
package com.qfedu.b_matedata;

import org.junit.Test;
import util.JdbcUtil;

import java.sql.*;

/**
 * 元數據測試
 *
 * @author Anonymous 2020/3/24 14:39
 */
public class TestMetaData {
    // 數據庫元數據演示
    @Test
    public void databaseMetaData() throws SQLException {
        Connection connection = JdbcUtil.getConnection();

        // 數據庫元數據
        DatabaseMetaData metaData = connection.getMetaData();

        System.out.println("UserName:" + metaData.getUserName());
        System.out.println("DriverVersion:" + metaData.getDriverVersion());
        System.out.println("DriverName:" + metaData.getDriverName());
        System.out.println("URL:" + metaData.getURL());

        System.out.println(connection);
    }

    @Test
    public void sqlMetaData() throws SQLException {
        // 獲取數據庫連接
        Connection connection = JdbcUtil.getConnection();

        // 準備SQL語句
        // ? 表示SQL語句參數佔位符!!!
        String sql = "insert into nzgp2001.user(id, userName, password) VALUE (?,?,?)";

        // 預處理SQL語句,獲取PreparedStatement對象
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();

        // [重點]
        System.out.println("當前SQL語句的參數個數:"  + parameterMetaData.getParameterCount());
        JdbcUtil.close(connection, preparedStatement);
    }

    @Test
    public void resultMetaData() throws SQLException {
        // 獲取數據庫連接
        Connection connection = JdbcUtil.getConnection();

        // 準備SQL語句
        // ? 表示SQL語句參數佔位符!!!
        String sql = "select * from user";

        // 預處理SQL語句,獲取PreparedStatement對象
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        ResultSet resultSet = preparedStatement.executeQuery();

        ResultSetMetaData metaData = resultSet.getMetaData();

        // 查詢結果集的字段個數
        int columnCount = metaData.getColumnCount();

        while (resultSet.next()) {
            for (int i = 1; i <= columnCount; i++) {
                // 字段名字
                String columnName = metaData.getColumnName(i);

                // 通過字段名從數據庫結果集中讀取對應字段的數據
                System.out.println(columnName + ":" + resultSet.getObject(columnName));
            }
        }
        // [重點]
        JdbcUtil.close(connection, preparedStatement, resultSet);
    }
}

5.3 【補充知識點 BeanUtils使用】
	BeanUtils提供了對於符合JavaBean規範的實體類進行賦值,取值,拷貝操作的一系列方法,可以自動完成數據類型轉換,方便開發者在數據交互中使用。
	所有的方法都是靜態方法
	三個方法
		1. 賦值指定成員變量對應數據
			a. 符合JavaBean規範的類對象
			b. 指定成員變量的名字
			c. Object類型數據用於賦值成員變量
			
		2. 取值指定成員變量的數據
			a. 符合JavaBean規範的類對象
            b. 指定成員變量的名字
            返回值是對應當前成員變量的數據類型
			
		3. 拷貝符合JavaBean規範的兩個對象數據
			a. 符合JavaBean規範的目標類對象
			b. 符合JavaBean規範的目標數據源對象		
           
        4. 真香方法,從Map雙邊對聯中匹配賦值數據到符合JavaBean規範的類對象
        	a. 符合JavaBean規範的類對象
        	b. Map雙邊隊列
package com.qfedu.c_testbeanutils;

import com.qfedu.a_statement.User;
import org.apache.commons.beanutils.BeanUtils;
import org.junit.Test;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;

/**
 * BeanUtils測試
 *
 * @author Anonymous 2020/3/24 15:09
 */
public class Demo1 {
    @Test
    public void testSetProperty()
            throws InvocationTargetException, IllegalAccessException {
        User user = new User();

        // 給符合JavaBean規範的指定成員變量賦值操作
        BeanUtils.setProperty(user, "id", "123");
        BeanUtils.setProperty(user, "userName", "騷磊");
        BeanUtils.setProperty(user, "password", 123456);

        System.out.println(user);
    }

    @Test
    public void testGetProperty()
            throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        User user = new User(1, "騷磊", "2344567");

        System.out.println(BeanUtils.getProperty(user, "id"));
        System.out.println(BeanUtils.getProperty(user, "userName"));
        System.out.println(BeanUtils.getProperty(user, "password"));
    }

    @Test
    public void testCopyProperties() throws InvocationTargetException, IllegalAccessException {
        User user = new User(1, "騷磊", "2344567");
        User user1 = new User();

        System.out.println("before:" + user1);
        BeanUtils.copyProperties(user1, user);

        System.out.println("after:" + user1);
    }

    // populate
    @Test
    public void 真香() throws InvocationTargetException, IllegalAccessException {
        HashMap<String, Integer> map = new HashMap<>();

        map.put("userName", 100);
        map.put("location:", 1);
        map.put("password", 1111);
        map.put("id", 2);

        User user = new User();

        System.out.println("before:" + user);
        BeanUtils.populate(user, map);

        System.out.println("after:" + user);

    }
}

5.4 通用更新方法實現
分析:
	完成通用的更新方法,update,insert,delete操作
	權限修飾符:
		public
	返回值類型:
		int 當前SQL語句參數,數據庫收到影響的行數
	方法名:
		update
	形式參數列表:
		1. String sql語句
			指定執行的SQL語句 update insert delete。。。
		2. SQL語句可能需要參數
			SQL有可能沒有參數,有可能多個參數,而且參數類型都不一樣!!!
			a. Object...
				Object類型的不定長參數
			b. Object[]
				所有對應當前SQL語句的參數都存儲在Object類型數組中
		(String sql, Object[] parameters)

方法聲明:
	public int update(String sql, Object[] parameters)
/**
 * 通用的更新方法,需要參數是SQL語句和對應當前SQL語句的Object類型參數數組
 *
 * @param sql        String類型的SQL語句,需要執行的方法
 * @param parameters 對應當前SQL語句的參數列表。Object類型數組
 * @return SQL語句執行數據庫受到影響的行數
 */
public int update(String sql, Object[] parameters) {
    int affectedRows = 0;
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    
    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]);
            }
        }
        
        // 執行SQL語句
        affectedRows = preparedStatement.executeUpdate();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        JdbcUtil.close(connection, preparedStatement);
    }
    
    return affectedRows;
}
5.5 通用查詢方法實現
分析:
	完成通用的查詢方法,select操作
	權限修飾符:
		public
	需要聲明泛型
		T ==> Type
	返回值類型:
		List<指定數據類型>
	方法名:
		query
	形式參數列表:
		1. String sql語句
			指定執行的SQL語句  Select語句
		2. SQL語句可能需要參數
			SQL有可能沒有參數,有可能多個參數,而且參數類型都不一樣!!!
			a. Object...
				Object類型的不定長參數
			b. Object[]
				所有對應當前SQL語句的參數都存儲在Object類型數組中
		3. 告知當前SQL語句出現的查詢結果對應數據類型是哪一個
			Class<T> cls
			a. 泛型T
				用於數據類型約束,傳入哪一個類的.class當前T對應的就是哪一個類
			b. Class 反射對應的Class類對象
				爲所欲爲!!!
				有了對應類的.class字節碼文件對應Class對象。可以通過反射爲所欲
				爲
            (String sql, Object[] parameters, Class<T> cls)

方法聲明:
	public <T> List<T> query(String sql, Object[] parameters, Class<T> cls)
/**
 * 通用的查詢方法,查詢cls指定數據類型,返回值是一個List集合
 *
 * @param sql        Select SQL語句
 * @param parameters 對應當前SQL語句的參數
 * @param cls        指定數據類型,同時提供Class對象,便於裏用反射操作,約束泛型類型
 * @param <T>        泛型佔位符
 * @return 指定數據類型的List集合,如果集合中不存在數據 size() == 0 返回null
 */
public <T> List<T> query(String sql, Object[] parameters, Class<T> cls) {
    ResultSet resultSet = null;
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    
    List<T> 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]);
            }
        }
            
        // 執行SQL語句,得到結果集對象
        resultSet = preparedStatement.executeQuery();
        // 結果集元數據
        ResultSetMetaData metaData = resultSet.getMetaData();
        // 字段個數
        int columnCount = metaData.getColumnCount();
            
        while (resultSet.next()) {
            // 根據Class類型創建對象,對象的類型是T類型
            T t = cls.getConstructor().newInstance();
            for (int i = 1; i <= columnCount; i++) {
                // 獲取字段名
                String fieldName = metaData.getColumnName(i);
                // 獲取對應字段數據
                Object value = resultSet.getObject(fieldName);
                // 給符合JavaBean規範的實現類,指定成員變量fieldName,賦值value
                BeanUtils.setProperty(t, fieldName, value);
            }
            
            list.add(t);
        }
    } catch (SQLException | NoSuchMethodException | InstantiationException
            | IllegalAccessException | InvocationTargetException e) {
        e.printStackTrace();
    } finally {
        JdbcUtil.close(connection, preparedStatement, resultSet);
    }
            
    // 判斷結果,如果List中沒有存儲數據,返回null
    return list.size() != 0 ? list : null;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章