java-jdbc2-PreparedStatement, 元数据, JdbcUtils

3 篇文章 0 订阅

PreparedStatement, 元数据, JdbcUtils

总结:
MetaData 元数据
一个对象一个数据的组成部分。

Connection 数据库连接对象:

  1. DriverClass 驱动类 ==> 明确连接的数据库是哪一个
  2. JdbcUrl JDBC 协议规范的数据库连接对应 统一资源定位符
  3. username 数据连接的用户名
  4. password 对应当时数据连接用户名的密码

Connection 对象中一定是存在以上四个数据的蛛丝马迹~~~

思考问题:

  1. 是否可以通过 Connection 对象获取数据库版本
  2. 是否可以判断 当前数据库的 编码集
    1. 参数元数据获取 SQL 语句参数格式
      通过 PreparedStatement 对象调用方法获取 参数元数据对象
      ParameterMetaData getParameterMetaData();
      通过 ParameterMetaData 对象调用方法 获取参数个数
      int getParameterCount();
    2. 结果集元数据获取字段个数和字段名称
      通过 ResultSet 结果集对象调用方法获取结果集元数据对象
      ResultSetMetaData getMetaData();
      通过 ResultSetMetaData 结果集元数据对象获取字段个数
      int getColumnCount();
      通过 ResultSetMetaData 结果集元数据获取字段名称,【注意】字段下标从 1 开始
      String getColumnName(int columnIndex);

insert delete update
流程:

  1. 数据库连接必要资源准备
  	jdbcUrl username password
  2. 加载驱动
  	com.mysql.jdbc.Driver
  	com.mysql.cj.jdbc.Driver
  3. 获取数据库连接对象 Connection
  4. 准备 SQL 语句
  5. 通过 Connection 对象预处理 SQL 语句得到 PreparedStatement 对象
  6. 根据情况给予 SQL 参数赋值操作
  7. 执行 SQL 语句  (查询时,得到 ResultSet 结果集对象针对于 ResultSet 结果集对象的处理方式)
  8. 关闭资源

功能分类:

  1. 工具类
    针对于数据库操作资源的管理操作
    核心方法
    a. 数据库连接对象获取
    b. 资源关闭操作
    2. 业务逻辑相关的 BaseDao 【重点 复习 接口 反射】
    针对于 SQL 语句任务目标处理方式
    核心方法:
    a. update 更新操作
    b. query 查询操作
    ==> 利用接口规范完成针对于数据库查询结果的多种处理方式,完成【插件式编程】
1. PreparedStatement
1.1 SQL 注入问题
Statement 搬运工
	java.sql.Connection createStatement();
	java.sql.ResultSet executeQuery(String sql);
	int executeUpdate(String sql);	
public class Demo1 {
    private static String user = "张三";
    private static String pass = "321321312' or 1=1 -- ";

    /*
    SQL 注入会导致用户在特定的语法,语句情况下,绕过 SQL 校验操作,影响 SQL 语句正常逻辑
    select * from t_user where username = '张三' and password = '321321312' or 1=1 -- ';
     */

    /*
    JVM ==> 核心方法 ==> 检索所有的 @Test 标记 Annotation
    Demo1.class.getConstructor().newInstance()  ==> 执行带有 @Test 标记的方法;
    Demo1.class.newInstance();
     */
    @Test
    public void testStatement() throws ClassNotFoundException, SQLException {
        // 1. 加载驱动
        Class.forName("com.mysql.jdbc.Driver");

        // 2. 数据连接必要资源
        String username = "root";
        String password = "123456";
        String jdbcUrl = "jdbc:mysql://localhost:3306/javaee_2207?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false";

        /*
         3. 获取数据库连接
         带有返回值的方法().var  ==> 对应当前方法返回值数据类型的变量
         Alt + Enter ==> 快速修复
         */
        Connection connection = DriverManager.getConnection(jdbcUrl, username, password);

        // 4. 获取 Statement SQL 语句搬运工对象
        Statement statement = connection.createStatement();

        // 5. 准备 SQL 语句
        String sql = "select * from t_user where username =  '" + user + "' and password = '" + pass + "'";
        // select * from t_user where username = '张三' and password = '123456';

        // 6. 执行 SQL 语句 得到 ResultSet 结果集对象
        ResultSet resultSet = statement.executeQuery(sql);

        // 7. 判断当前 ResultSet 是否有对应数据情况
        if (resultSet.next()) {
            System.out.println("Statement 登陆成功");
        } else {
            System.err.println("Statement 登陆失败");
        }

        // 8. 关闭资源
        resultSet.close();
        statement.close();
        connection.close();
    }
1.2 PreparedStatement 常用 API
1. 通过 Connection 数据库连接对象获取 PreparedStatement 数据库 SQL 语句预处理搬运工对象
	java.sql.PreparedStatement prepareStatement(String sql)
	在获取 PreparedStatement 对象过程中,需要传入的预处理 SQL 语句,并且 SQL 语句允许带有参数

2. PreparedStatement 操作相关方法
	java.sql.ResultSet executeQuery();
		执行 DQL 语句 ==> Select, 得到 ResultSet 结果集对象
	int executeUpdate();
		执行 Update Insert Delete,当前 SQL 语句对应数据表的影响行数
	
	设置参数相关方法
		setXXX(int parameterIndex, XXX value);
		
		setString(int parameterIndex, String value); 常用!!!
		setInt(int parameterIndex, int value);
		
		setObject(int parameterIndex, Object value); 使用最多!!!

3. SQL 语句参数
	insert 操作为例
		create table student
		(
			id int,
			name varchar(32),
			gender tinyInt(1)
		)
		insert into student(id, name, gender) value(?,?,?);
		? ==> SQL 语句参数占位符
		SQL 语句通过该 Connection 对象处理 ==> PreparedStatement
		通过  PreparedStatement ==> setXXX 设置参数内容
		【注意】 SQL 语句参数下标从 1 开始
			preparedStatement.setObject(1, 10);
			preparedStatement.setObject(2, "老黑");			
			preparedStatement.setObject(3, false);			
1.3 PreparedStatement 操作使用和防止 SQL 注入
@Test
public void testPreparedStatement() throws ClassNotFoundException, SQLException {
    // 1. 加载驱动
    Class.forName("com.mysql.jdbc.Driver");
    
    // 2. 数据连接必要资源
    String username = "root";
    String password = "123456";
    String jdbcUrl = "jdbc:mysql://localhost:3306/javaee_2207?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useS
    
     /*
     3. 准备 SQL 语句
        ? 是 SQL 语句参数占位符
     */
    String sql = "select * from t_user where username = ? and password = ?";
    
    // 4. 获取数据库连接对象 java.sql.Connection
    Connection connection = DriverManager.getConnection(jdbcUrl, username, password);
    
    // 5. 预处理 SQL 语句 得到 java.sql.PreparedStatement(extends Statement) 对象
    PreparedStatement preparedStatement = connection.prepareStatement(sql);
    
    /*
     6. 设置 SQL 语句参数
     Ctrl + D 复制光标所在行
     */
    preparedStatement.setObject(1, user);
    preparedStatement.setObject(2, pass);
    
    /*
    7. 执行 SQL 语句得到 java.sql.ResultSet 结果集对象
     */
    ResultSet resultSet = preparedStatement.executeQuery();
    
    // 8. 判断是否有结果产出
    if (resultSet.next()) {
        System.out.println("PreparedStatement 登陆成功");
    } else {
        System.err.println("PreparedStatement 登陆失败");
    }
    
    // 9. 关闭资源
    resultSet.close();
    preparedStatement.close();
    connection.close();
}
1.4 PreparedStatement 完成 CRUD
1.4.1 PreparedStatement insert 操作
@Test
public void testInsert() {
    // 1. 准备数据库连接所需必要资源
    String username = "root";
    String password = "123456";
    String jdbcUrl = "jdbc:mysql://localhost:3306/javaee_2207?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false";

    Connection connection = null;
    PreparedStatement statement = null;

    try {
        // 2. 加载驱动
        Class.forName("com.mysql.jdbc.Driver");

        // 3. 获取数据库连接对象
        connection = DriverManager.getConnection(jdbcUrl, username, password);

        /*
        4. 准备 SQL 语句
        Java "" 字符串  ==> Alt + Enter
            inject language or reference
            输入 MySQL
        */
        String sql = "insert into javaee_2207.t_user(username, password) values(?, ?)";


        // 5. 预处理 SQL 语句得到 PreparedStatement 对象
        statement = connection.prepareStatement(sql);

        // 6. 给予当前 SQL 语句参数赋值操作
        statement.setObject(1, "老黑");
        statement.setObject(2, "老嘿嘿嘿");

        // 7. 执行 SQL 语句,得到当前 SQL 语句执行对应数据表影响行数
        int affectedRows = statement.executeUpdate();

        System.out.println("受到影响的行数:" + affectedRows);

    } catch (ClassNotFoundException | SQLException e) {
        e.printStackTrace();
    } finally {
        // 关闭资源
        try {
            if (statement != null) {
                statement.close();
            }

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

    }
}
1.4.2 PreparedStatement delete 操作
@Test
public void testDelete() {
    // 1. 准备数据库连接所需必要资源
    String username = "root";
    String password = "123456";
    String jdbcUrl = "jdbc:mysql://localhost:3306/javaee_2207?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false";

    Connection connection = null;
    PreparedStatement statement = null;

    try {
        /*
         2. 加载驱动
         Ctrl + Shift + ↑/↓
         */
        Class.forName("com.mysql.jdbc.Driver");

        // 3. 获取数据库 Connection 连接对象
        connection = DriverManager.getConnection(jdbcUrl, username, password);

        // 4. 准备 SQL 语句
        String sql = "delete from javaee_2207.t_user where id = ?";

        // 5. 预处理 SQL 语句得到 PreparedStatement 对象
        statement = connection.prepareStatement(sql);

        // 6. 给予 SQL 语句赋值操作
        statement.setObject(1, 3);

        // 7. 执行 SQL 语句得到当前 SQL 语句执行对应数据表的影响行数
        int affectedRows = statement.executeUpdate();
        System.out.println("受到影响的行数:" + affectedRows);
        
        /*
        Stream 流
            Predicate Supplier Consumer Comparator Function
         */
    } catch (ClassNotFoundException | SQLException e) {
        e.printStackTrace();
    } finally {
        // 关闭资源
        try {
            if (statement != null) {
                statement.close();
            }

            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
1.4.3 PreparedStatement update 操作
@Test
public void testUpdate() {
    // 1. 准备数据库连接所需必要资源
    String username = "root";
    String password = "123456";
    String jdbcUrl = "jdbc:mysql://localhost:3306/javaee_2207?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false";

    Connection connection = null;
    PreparedStatement statement = null;

    // ORM 老邢没讲
    try {
        // 2. 加载驱动
        Class.forName("com.mysql.jdbc.Driver");

        // 3. 获取数据库连接对象
        connection = DriverManager.getConnection(jdbcUrl, username, password);

        // 4. 准备 SQL 语句
        String sql = "update javaee_2207.t_user set username = ? , password = ? where id = ?";

        // 5. 预处理 SQL 语句,得到 PreparedStatement 对象
        statement = connection.prepareStatement(sql);

        // 6. 给予 SQL 语句参数赋值操作
        statement.setObject(1, "大哥");
        statement.setObject(2, "路见不平一声吼,大哥没有男朋友");
        statement.setObject(3, 1);

        // 7. 执行 SQL 语句,得到当前 SQL 语句执行对应数据表的影响行数
        int affectedRows = statement.executeUpdate();

        System.out.println("受到影响的行数:" + affectedRows);
    } catch (ClassNotFoundException | SQLException e) {
        e.printStackTrace();
    } finally {
        // 关闭资源
        try {
            if (statement != null) {
                statement.close();
            }

            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
1.4.4 PreparedStatement select操作
@Test
public void testSelect() {
    // 1. 准备数据库连接所需必要资源
    String username = "root";
    String password = "123456";
    String jdbcUrl = "jdbc:mysql://localhost:3306/javaee_2207?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false";

    ResultSet resultSet = null;
    Connection connection = null;
    PreparedStatement statement = null;

    try {
        // 2. 加载驱动
        Class.forName("com.mysql.jdbc.Driver");

        // 3. 获取数据库 Connection 连接对象
        connection = DriverManager.getConnection(jdbcUrl, username, password);

        // 4. 准备 SQL 语句
        String sql = "select * from javaee_2207.t_user where id = ?";

        // 5. 预处理 SQL 语句,得到 PreparedStatement 对象
        statement = connection.prepareStatement(sql);

        // 6. 给予 SQL 语句赋值操作
        statement.setObject(1, 5);

        // 7. 执行 SQL 语句,得到 ResultSet 结果集对象
        resultSet = statement.executeQuery();

        // 8. 通过 ResultSet 结果集对象的 next() 方法,判断是否需要进行解析数据操作
        if (resultSet.next()) {
            /*
            resultSet.getXXX(String columnName);
                根据字段名获取指定数据类型数据内容
            resultSet.getXXX(int columnIndex);
                根据字段下标获取指定数据类型数据内容,下标从 1 开始
             */
            int id = resultSet.getInt("id");
            String username1 = resultSet.getString("username");
            String password1 = resultSet.getString("password");

            System.out.println("id:" + id);
            System.out.println("username:" + username1);
            System.out.println("password:" + password1);
        } else {
            System.out.println("Source Not Found!!! 404");
        }

    } catch (ClassNotFoundException | SQLException e) {
        e.printStackTrace();
    } finally {
        try {
            if (resultSet != null) {
                resultSet.close();
            }

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

            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
1.4.5 PreparedStatement select All 操作
@Test
public void testSelectAll() {
    // 1. 准备数据库连接所需必要资源
    String username = "root";
    String password = "123456";
    String jdbcUrl = "jdbc:mysql://localhost:3306/javaee_2207?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false";

    ResultSet resultSet = null;
    Connection connection = null;
    PreparedStatement statement = null;

    try {
        // 2. 加载驱动
        Class.forName("com.mysql.jdbc.Driver");

        // 3. 获取数据库连接对象
        connection = DriverManager.getConnection(jdbcUrl, username, password);

        // 4. 准备 SQL 语句
        String sql = "select * from javaee_2207.t_user";

        // 5. 预处理 SQL 语句,得到 PreparedStatement 对象
        statement = connection.prepareStatement(sql);

        // 6. 执行 SQL 语句
        resultSet = statement.executeQuery();

        // 7. 多行数据内容,使用 while 循环结构
        while (resultSet.next()) {
            int id = resultSet.getInt(1);
            String username2 = resultSet.getString(2);
            String password2 = resultSet.getString(3);

            System.out.println("id:" + id);
            System.out.println("username:" + username2);
            System.out.println("password:" + password2);
            System.out.println("---------------------------------");
        }

    } catch (ClassNotFoundException | SQLException e) {
        e.printStackTrace();
    } finally {
        try {
            if (resultSet != null) {
                resultSet.close();
            }

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

            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
2. 元数据
2.1 元数据概念
MetaData
	一个对象一个数据的组成部分。

Connection 数据库连接对象:
	1. DriverClass 驱动类 ==> 明确连接的数据库是哪一个
	2. JdbcUrl JDBC 协议规范的数据库连接对应 统一资源定位符
	3. username 数据连接的用户名
	4. password 对应当时数据连接用户名的密码
	
	Connection 对象中一定是存在以上四个数据的蛛丝马迹~~~

思考问题:
	1. 是否可以通过 Connection 对象获取数据库版本
	2. 是否可以判断 当前数据库的 编码集
package com.qfedu.b_metadata;

import com.mysql.jdbc.Driver;
import org.junit.Test;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * 数据库连接对象 元数据内容
 *
 * @author Anonymous 2022/6/5 15:16
 */
public class Demo1 {
    @Test
    public void testSQLConnectionMetaData() throws ClassNotFoundException, SQLException {
        // 1. 准备数据库连接所需必要资源
        String username = "root";
        String password = "123456";
        String jdbcUrl = "jdbc:mysql://localhost:3306/javaee_2207?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false";

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

        Connection connection = DriverManager.getConnection(jdbcUrl, username, password);

        /*
        DatabaseMetaData 数据库元数据对象
         */
        DatabaseMetaData metaData = connection.getMetaData();
        System.out.println(metaData.getDriverVersion());
        System.out.println(metaData.getUserName());
        System.out.println(metaData.getURL());

        System.out.println(connection);
    }
}
2.2 SQL 语句元数据 ==> 参数个数
String sql = "insert into javaee_2207 student(name, age, gender, score) values(?, ?, ?, ?)";
String API
	split("?") ==> String[] arr ==> arr.length - 1 ==> ? count
	endsWith("?") ==> true 
				==> false 

请问:
	1. 参数英文 ==> Parameter
	2. 个数/计数/数量 ==> count
	3. 获取 get
	getParameterCount
package com.qfedu.b_metadata;

import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;

/**
 * SQL 语句元数据 获取 参数个数
 *
 * @author Anonymous 2022/6/5 15:50
 */
public class Demo2 {
    @Test
    public void testParameterMetaData() throws Exception {
        // 1. 准备数据库连接所需必要资源
        String username = "root";
        String password = "123456";
        String jdbcUrl = "jdbc:mysql://localhost:3306/javaee_2207?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false";

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

        Connection connection = DriverManager.getConnection(jdbcUrl, username, password);

        String sql = "select * from javaee_2207.student where id = ?";

        PreparedStatement statement = connection.prepareStatement(sql);

        /*
        ParameterMetaData 参数元数据对象
            通过 PreparedStatement 获取对应当前 SQL 语句的参数元数据对象
        通过 ParameterMetaData 参数元数据对象 获取 参数个数
            int getParameterCount();
         */
        // ParameterMetaData parameterMetaData = statement.getParameterMetaData();
        int parameterCount = statement.getParameterMetaData().getParameterCount();
        System.out.println("参数个数:" + parameterCount);

        statement.close();
        connection.close();
    }
}
2.3 结果集元数据 ==> 字段名,字段个数
package com.qfedu.b_metadata;

import org.junit.Test;

import java.sql.*;

/**
 * 结果集元数据
 *
 * @author Anonymous 2022/6/5 16:00
 */
public class Demo3 {
    @Test
    public void testResultSetMetaData() throws Exception {
        // 1. 准备数据库连接所需必要资源
        String username = "root";
        String password = "123456";
        String jdbcUrl = "jdbc:mysql://localhost:3306/javaee_2207?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false";

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

        Connection connection = DriverManager.getConnection(jdbcUrl, username, password);

        String sql = "select * from javaee_2207.student where id = 1";

        PreparedStatement statement = connection.prepareStatement(sql);

        ResultSet resultSet = statement.executeQuery();

        /*
        通过 ResultSet 结果集对象获取 结果集元数据对象 ResultSetMetaData
         */
        ResultSetMetaData metaData = resultSet.getMetaData();

        /*
        通过 ResultSetMetaData 结果集元数据对象 获取字段个数
        目前查询结果集字段内容
            id, name, age, score ==> 4 个字段/ 4 列数据
         */
        int columnCount = metaData.getColumnCount();
        System.out.println("字段个数:" + columnCount);

        /*
        可以从结果集元数据 ResultSetMetaData 获取字段名称,字段下标为 1 开始
        String getColumnName(int columnIndex);
            可以根据字段下标获取对应的字段名称
         */
        for (int i = 1; i <= columnCount; i++) {
            System.out.println("字段名" + i + ":" + metaData.getColumnName(i));
        }

        resultSet.close();
        statement.close();
        connection.close();
    }
}
2.4 元数据主要 API 总结
1. 参数元数据获取 SQL 语句参数格式
	通过 PreparedStatement 对象调用方法获取 参数元数据对象
		ParameterMetaData getParameterMetaData();
	通过 ParameterMetaData 对象调用方法 获取参数个数
		int getParameterCount();

2. 结果集元数据获取字段个数和字段名称
	通过 ResultSet 结果集对象调用方法获取结果集元数据对象
		ResultSetMetaData getMetaData();
	通过 ResultSetMetaData 结果集元数据对象获取字段个数
		int getColumnCount();
	通过 ResultSetMetaData 结果集元数据获取字段名称,【注意】字段下标从 1 开始
		String getColumnName(int columnIndex);
3. Jdbc操作封装
3.1 流程分析和封装分析
更新操作
	insert delete update
	流程:
		1. 数据库连接必要资源准备
			jdbcUrl username password
		2. 加载驱动
			com.mysql.jdbc.Driver
			com.mysql.cj.jdbc.Driver
		3. 获取数据库连接对象 Connection
		4. 准备 SQL 语句
		5. 通过 Connection 对象预处理 SQL 语句得到 PreparedStatement 对象
		6. 根据情况给予 SQL 参数赋值操作
		7. 执行 SQL 语句
		8. 关闭资源
	
查询操作
	select
	流程:
		1. 数据库连接必要资源准备
			jdbcUrl username password
		2. 加载驱动
			com.mysql.jdbc.Driver
			com.mysql.cj.jdbc.Driver
		3. 获取数据库连接对象 Connection
		4. 准备 SQL 语句
		5. 通过 Connection 对象预处理 SQL 语句得到 PreparedStatement 对象
		6. 根据情况给予 SQL 参数赋值操作
        7. 执行 SQL 语句 得到 ResultSet 结果集对象
        8. 针对于 ResultSet 结果集对象的处理方式
        9. 关闭资源

功能分类:
	1. 工具类
		针对于数据库操作资源的管理操作
		核心方法
			a. 数据库连接对象获取
            b. 资源关闭操作
    2. 业务逻辑相关的 BaseDao 【重点 复习 接口 反射】
    	针对于 SQL 语句任务目标处理方式
    	核心方法:
    		a. update 更新操作
    		b. query 查询操作
    			==> 利用接口规范完成针对于数据库查询结果的多种处理方式,完成【插件式编程】
3.2 JdbcUtils 工具类封装
工具类使用目标
	1. 对于用户,方便,简单,快捷
    2. 对于工具类开发者,全面!!!

核心方法
	a. 数据库连接对象获取
		DriverManager.getConnection(String url, String username, String password);
		
		static java.sql.Connection getConnection();
    b. 资源关闭操作
3.3 db.properties 配置文件

注意,需要工具版本修改 DriverClass,已经根据个人账号修改用户名和密码

# Properties Jdbc Connection MySQL Properties File
# location src directory
# MySQL JDBC Driver Package and Class Name
driverClass=com.mysql.jdbc.Driver
# JDBC Protocol URL
jdbcUrl=jdbc:mysql://localhost:3306/javaee_2207?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=123456
3.4 JdbcUtils 资源加载和 getConnection 数据库连接对象获取
package util;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

/**
 * JdbcUtils 工具类
 *
 *
 * @author Anonymous 2022/6/5 16:54
 */
public class JdbcUtils {
    /*
    必要的静态成员变量用于存储 db.properties 文件中的配置内容
     */
    private static String jdbcUrl;
    private static String username;
    private static String password;

    /*
    利用 static 修饰的静态代码块 在类文件加载阶段执行 db.properties 读取操作和驱动加载操作
     */
    static {
        /*
        db.properties 在 src 目录下
            JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
            JdbcUtils.class ==> 获取当前 JdbcUtils 工具类 Class<JdbcUtils> 对象
            getClassLoader() 获取类加载器对象
            getResourceAsStream("db.properties") 在当前 JdbcUtils 类对应的目录中,上下检索对应名称的文件内容,返回
                字节输入流对象
         */
        InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");

        /*
        Java 中的 Properties 属性类型可以用于存储对应的 Properties 文件内容,数据形式就是
        键值对形式,底层数据存储方式 Map(Key = Value) 方式
         */
        Properties properties = new Properties();

        try {
            /*
            加载对应文件,文件采用 InputStream 字节输入流方式加载到 Propertie 类内
             */
            properties.load(in);

            /*
            根据 Properties 文件内容中的 Key 获取对应的 value
            数据库连接对象获取必要的资源内容
             */
            jdbcUrl = properties.getProperty("jdbcUrl");
            username = properties.getProperty("username");
            password = properties.getProperty("password");

            /*
            读取 Properties 文件中的 driverClass 同时利用
            Class.forName 加载驱动
             */
            Class.forName(properties.getProperty("driverClass"));
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 获取 java.sql.Connection 数据库连接对象
     *
     * @return java.sql.Connection 数据库连接对象
     */
    public static Connection getConnection() {
        Connection connection = null;

        try {
            connection = DriverManager.getConnection(jdbcUrl, username, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return connection;
    }
}
        /*
        读取 Properties 文件中的 driverClass 同时利用
        Class.forName 加载驱动
         */
        Class.forName(properties.getProperty("driverClass"));
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    } finally {
        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

/**
 * 获取 java.sql.Connection 数据库连接对象
 *
 * @return java.sql.Connection 数据库连接对象
 */
public static Connection getConnection() {
    Connection connection = null;

    try {
        connection = DriverManager.getConnection(jdbcUrl, username, password);
    } catch (SQLException e) {
        e.printStackTrace();
    }

    return connection;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值