JDBC CRUD 操作和必要工具类分析

JDBC CRUD 操作和必要工具类分析

1. Driver 驱动类分析

Class.forName("完整的包名.类名");
	可以获取到对应的 Class 对象,是否可以认为对应数据类型已经在内存【方法区】加载

static 修饰的静态代码块在类文件加载过程中,一定执行,有且只执行一次。
static {
	
}
package com.mysql.jdbc;

import java.sql.SQLException;

/*
interface java.sql.Driver
	JDBC 规范对应的驱动标准接口
*/
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    /*
     Register ourselves with the DriverManager
    
    通过 DriverManager 驱动管理类注册当前 Driver 类对象
     静态代码块会在类文件加载阶段执行一次。
     静态代码块执行任务
     	java.sql.DriverManager.registerDriver(new Driver());
    	通过 JDBC 驱动管理类 DriverManager registerDriver 注册驱动
    		registerDriver(java.sql.Driver driver);
    		interface java.sql.Driver当前方法所需的实际参数是对应接口的实现类对象。
    		
    		当前 com.mysql.jdbc.Driver implements java.sql.Driver 
    		可以提供给 registerDriver方法 com.mysql.jdbc.Driver 实例化对象。
   
   	利用 static 静态代码块 配合注册方法,完成了类加载自动注册过程。
    */
    static {
        try {
            java.sql.DriverManager.registerDriver(new Driver());
        } catch (SQLException E) {
            throw new RuntimeException("Can't register driver!");
        }
    }

    /**
     * Construct a new driver and register it with DriverManager
     * 
     * @throws SQLException
     *             if a database error occurs.
     */
    public Driver() throws SQLException {
        // Required for Class.forName().newInstance()
    }
}

2. JDBC 核心 API 【重点】

class java.sql.DriverManager 
	JDBC规范驱动管理类,可以通过指定方法注册驱动,或者获取 java.sql.Connection 数据库连接对象
	
	static void registerDriver(java.sql.Driver driver);
		JDBC对应数据库厂商自行完成的驱动类对应 java.sql.Driver 并且在加载过程中自行完成注册
	static java.sql.Connection getConnection(String jdbcUrl, String username, 
			String password);
		根据提供的 JDBC 规范数据库连接 url,对应用户名和密码,获取数据库 java.sql.Connection 数据库连接
		对象

interface java.sql.Connection
	JDBC 规范数据库连接规范接口 可以通过数据库 Connection 连接对象,获取数据库 SQL 语句搬运工对象
	
	java.sql.Statement createStatement();
		通过数据库 Connection 连接对象 获取 SQL 语句搬运工对象 java.sql.Statement
	java.sql.PreparedStatement prepareStatement(String sql);
		通过数据库 Connection 连接对象 获取 SQL 语句【预处理搬运工对象】 java.sql.PreparedStatement

interface java.sql.Statement
	JDBC 规范 SQL 语句搬运工对象,可以通过搬运工对象将 SQL 语句交给数据库执行,同时得到数据反馈,包含执行 
	insert update delete 操作对应数据库影响行数,和 select 操作查询结果集对象。
	
	int executeUpdate(String sql);
		执行目标 SQL 语句,可以执行的 SQL 类型(insert update delete),返回值是受到影响行数
	java.sql.ResultSet executeQuery(String sql);
		执行目标 SQL 语句,可以执行的 SQL 类型(select), 返回值类型是查询结果集对象 java.sql.ResultSet
	
interface java.sql.PreparedStatement extends java.sql.Statement
	JDBC 规范 SQL 语句【预处理搬运工对象】,可以通过搬运工对象将 SQL 语句交给数据库执行,同时得到数据反馈,包
	含执行 insert update delete 操作对应数据库影响行数,和 select 操作查询结果集对象。
	
	void setObject(int index, Object obj); 
		给予预处理 SQL 语句进行参数赋值操作。index 是参数下标,obj 是参数数据内容
	int executeUpdate();
		执行目标 SQL 语句,可以执行的 SQL 类型(insert update delete),返回值是受到影响行数
	java.sql.ResultSet executeQuery();
		执行目标 SQL 语句,可以执行的 SQL 类型(select), 返回值类型是查询结果集对象 java.sql.ResultSet
		
interface java.sql.ResultSet
	JDBC 规范数据查询结果集对象,针对于 query 方法存储对应查询数据内容
	
	boolean next();
		判断当前查询结果集是否还有可以继续进行解析的数据行内容,在进行 ResultSet 结果集数据解析过程中,必须首
		先调用 next 方法
	XXX getXXX(String fieldName/columnName)
		根据指定的字段名称或者查询结果集列名称,获取指定数据类型数据内容
	XXX getXXX(int columnCount)
		根据指定的结果集列下标,获取指定数据类型数据内容

3. Statement 完成数据库 CRUD 操作

3.1 Statement insert 操作
public static void testInsert() {
    // 1. 准备必要数据操作相关对象
    Connection connection = null;
    Statement statement = null;

    try {
        // 2. 加载驱动 Ctrl + Shift + ? 移动代码
        Class.forName("com.mysql.jdbc.Driver");

        // 3. 准备数据库连接对象获取使用的必要数据内容
        String jdbcUrl = "jdbc:mysql://localhost:3306/javaee_2203?useSSL=false";
        String username = "root";
        String password = "123456";

        /*
        4. 通过 DriverManager 获取数据库 Connection 连接对象
        static java.sql.Connection getConnection(String jdbcUrl, String username,
		String password);
	        根据提供的 JDBC 规范数据库连接 url,对应用户名和密码,获取数据库 java.sql.Connection 数据库连接
	        对象
         */
        connection = DriverManager.getConnection(jdbcUrl, username, password);

        /*
        5. 通过 Connection 数据库连接对象获取 SQL 语句搬运工对象 Statement
        java.sql.Statement createStatement();
	        通过数据库 Connection 连接对象 获取 SQL 语句搬运工对象 java.sql.Statement
         */
        statement = connection.createStatement();

        /*
        1. Alt + Enter
        2. 选择菜单 Inject Language or reference
        3. 输入 mysql 回车,当前字符串对应提示为 MySQL 提示
         */
        // 6. 准备执行任务的 SQL 语句
        String sql = "insert into javaee_2203.student(name, age, score) VALUES ('老黑', 56, 5.5)";

        /*
        7. 执行 SQL 语句
        int executeUpdate(String sql);
	        执行目标 SQL 语句,可以执行的 SQL 类型(insert update delete),返回值是受到影响行数
         */
        int affectedRows = statement.executeUpdate(sql);
        System.out.println("执行 SQL 语句数据表受到影响的行数:" + affectedRows);

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

            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
3.2 Statement update 操作
public static void testUpdate() {
    // 1. 准备数据库操作必要的对象
    Connection connection = null;
    Statement statement = null;

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

        // 3. 准备数据库连接必要的参数 jdbcUrl username password
        String jdbcUrl = "jdbc:mysql://localhost:3306/javaee_2203?useSSL=false";
        String username = "root";
        String password = "123456";

        /*
        4. 通过 DriverManager 对象获取 Connection 数据库连接对象
        static java.sql.Connection getConnection(String jdbcUrl, String username,
		String password);
	        根据提供的 JDBC 规范数据库连接 url,对应用户名和密码,获取数据库 java.sql.Connection 数据库连接
	        对象
         */
        connection = DriverManager.getConnection(jdbcUrl, username, password);

        /*
        5. 通过数据库连接 Connection 对象获取 数据库搬运工对象 Statement
        java.sql.Statement createStatement();
	        通过数据库 Connection 连接对象 获取 SQL 语句搬运工对象 java.sql.Statement
         */
        statement = connection.createStatement();

        // 6. 准备 SQL 语句
        String sql = "update javaee_2203.student set name = '老邢' where id = 3";
        
        /*
        7. 通过数据库搬运工对象 Statement 搬运 SQL 语句到数据库执行
        int executeUpdate(String sql);
	        执行目标 SQL 语句,可以执行的 SQL 类型(insert update delete),返回值是受到影响行数
         */
        int affectedRows = statement.executeUpdate(sql);
        System.out.println(affectedRows);

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

            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
3.3 Statement delete 操作
public static void testDelete() {
    // 1. 准备数据库操作必要的对象
    Connection connection = null;
    Statement statement = null;

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

        // 3. 准备数据库连接必要的参数 jdbcUrl username password  CTRL + X 删除
        String jdbcUrl = "jdbc:mysql://localhost:3306/javaee_2203?useSSL=false";
        String username = "root";
        String password = "123456";

        /*
        4. 通过 DriverManager 对象获取 数据库连接 Connection 对象
        static java.sql.Connection getConnection(String jdbcUrl, String username,
		String password);
            根据提供的 JDBC 规范数据库连接 url,对应用户名和密码,获取数据库 java.sql.Connection 数据库连接
            对象
         */
        connection = DriverManager.getConnection(jdbcUrl, username, password);

        // 5. 准备 执行目标 SQL 语句
        String sql = "delete from javaee_2203.student where id = 3";

        /*
        6. 获取数据库 SQL 语句搬运工 Statement 对象
        java.sql.Statement createStatement();
	        通过数据库 Connection 连接对象 获取 SQL 语句搬运工对象 java.sql.Statement
         */
        statement = connection.createStatement();

        /*
        7. 执行 SQL 语句,得到数据表针对当前 SQL 操作受到影响的行数
        int executeUpdate(String sql);
	        执行目标 SQL 语句,可以执行的 SQL 类型(insert update delete),返回值是受到影响行数
         */
        int affectedRows = statement.executeUpdate(sql);
        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();
        }
    }
}
3.4 Statement select 一行数据操作
public static void testSelectOne() {
    // 1. 准备必要的操作数据变量
    Connection connection = null;
    Statement statement = null;
    // java.sql.ResultSet 结果集对象
    ResultSet resultSet = null;

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

        // 3. 准备数据库连接必要的参数 jdbcUrl username password  CTRL + X 删除
        String jdbcUrl = "jdbc:mysql://localhost:3306/javaee_2203?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false";
        String username = "root";
        String password = "123456";

        /*
        4. 利用 DriverManager 对象获取数据库连接 Connection 对象
        static java.sql.Connection getConnection(String jdbcUrl, String username, String password);
            根据提供的 JDBC 规范数据库连接 url,对应用户名和密码,获取数据库 java.sql.Connection 数据库连接
            对象
         */
        connection = DriverManager.getConnection(jdbcUrl, username, password);

        // 5. 准备执行 SQL 语句
        String sql = "select * from javaee_2203.student where id = 2";

        /*
        6. 通过 Connection 数据连接对象 获取 Statement 数据库 SQL 语句搬运工对象
        java.sql.Statement createStatement();
	        通过数据库 Connection 连接对象 获取 SQL 语句搬运工对象 java.sql.Statement
         */
        statement = connection.createStatement();

        /*
        7. 通过 Statement 搬运 SQL 语句到 MySQL 数据库,同时得到查询结果集对象 java.sql.ResultSet
            java.sql.ResultSet executeQuery(String sql);
	            执行目标 SQL 语句,可以执行的 SQL 类型(select),
	            返回值类型是查询结果集对象 java.sql.ResultSet
	        executeQuery 方法返回值永不为 null,需要通过其他方式判断当前查询结果集中是否有数据存在
	            boolean next() 方法
         */
        resultSet = statement.executeQuery(sql);

        /*
        8. 解析结果集数据
        boolean next();
        	判断当前查询结果集是否还有可以继续进行解析的数据行内容,
        	在进行 ResultSet 结果集数据解析过程中,必须首先调用 next 方法
         */
        if (resultSet.next()) {
            /*
            9. 根据字段名称/columnName 获取对应的数据,数据类型根据选择方法情况决定
            XXX getXXX(String fieldName/columnName)
	            根据指定的字段名称或者查询结果集列名称,获取指定数据类型数据内容
             */
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            int age = resultSet.getInt("age");
            float score = resultSet.getFloat("score");

            System.out.println("id = " + id);
            System.out.println("name = " + name);
            System.out.println("age = " + age);
            System.out.println("score = " + score);
        }

    } catch (ClassNotFoundException | SQLException e) {
        e.printStackTrace();
    } finally {
        /*
        10. 关闭资源
         */
        try {
            // java.sql.ResultSet 也是一个资源,也需要关闭!!!
            if (resultSet != null) {
                resultSet.close();
            }

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

            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
3.5 Statement select 多行数据操作
public static void testSelectAll() {
    // 1. 准备数据库操作必要的类型
    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;

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

        // 3. 准备数据库连接必要的参数 jdbcUrl username password  CTRL + X 删除
        String jdbcUrl = "jdbc:mysql://localhost:3306/javaee_2203?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false";
        String username = "root";
        String password = "123456";

        /*
        4. 通过 DriverManager 对象获取数据库连接对象
        static java.sql.Connection getConnection(String jdbcUrl, String username, String password);
            根据提供的 JDBC 规范数据库连接 url,对应用户名和密码,获取数据库 java.sql.Connection 数据库连接
            对象
         */
        connection = DriverManager.getConnection(jdbcUrl, username, password);

        // 5. 准备执行 SQL 语句 Ctrl + Enter
        String sql = "select * from javaee_2203.student";

        /*
        6. 通过数据库 Connection 连接对象 获取 数据库 SQL 语句搬运工对象 java.sql.Statement
        java.sql.Statement createStatement();
	            通过数据库 Connection 连接对象 获取 SQL 语句搬运工对象 java.sql.Statement
         */
        statement = connection.createStatement();

        /*
        7. 通过 Statement 执行 SQL 语句 得到结果集对象 java.sql.ResultSet;
        java.sql.ResultSet executeQuery(String sql);
	        执行目标 SQL 语句,可以执行的 SQL 类型(select), 返回值类型是查询结果集对象 java.sql.ResultSet
         */
        resultSet = statement.executeQuery(sql);

        /*
        8. 解析 ResultSet
        boolean next();
	        判断当前查询结果集是否还有可以继续进行解析的数据行内容,在进行
	        ResultSet 结果集数据解析过程中,必须首先调用 next 方法
         */
        ArrayList<Student> list = new ArrayList<>();
        while (resultSet.next()) {
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            int age = resultSet.getInt("age");
            float score = resultSet.getFloat("score");

            Student student = new Student();
            student.setId(id);
            student.setName(name);
            student.setAge(age);
            student.setScore(score);

            /*
            Ctrl + shift + Enter 可以补齐分号
             */
            list.add(student);
        }

        /*
        Stream + forEach方法 + 匿名内部类 ALT + Enter

        list.stream().forEach(new Consumer<Student>() {
            @Override
            public void accept(Student student) {
                System.out.println(student);
            }
        });
		*/
        /*
        Stream + forEach方法 + Lambda 表达式

        list.stream().forEach(student -> System.out.println(student));
        */
        /*
        Stream + forEach方法 + 方法引用

        list.stream().forEach(System.out::println);
        */
        /*
        forEach方法 + 方法引用
        List 集合方法
            void forEach(Consumer<T> con); 处理集合中每一个元素的方式
                void accept(T t); ==> Lambda 有参无返回 ==> 方法引用同理
        */
        list.forEach(System.out::println);

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

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

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

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

4. 模块分析

1. 准备必要的操作数据变量
2. 加载驱动
3. 准备数据库连接必要的参数 jdbcUrl username password 
4. 利用 DriverManager 对象获取数据库连接 Connection 对象

5. 准备执行 SQL 语句
6. 通过 Connection 数据连接对象 获取 Statement 数据库 SQL 语句搬运工对象
7. 执行 解析

8. 关闭资源

cmd 中操作数据库
	1. 打开连接
	2. SQL 语句
	3. 关闭连接

1. 数据库连接对象获取可以封装成一个模块,提供给方法使用
2. 数据库相关资源关闭封装成一个模块

中间的业务逻辑后面再去划分,分析,封装,实现。

5. JDBC 数据库资源工具类封装

package com.qfedu.uitl;

import java.sql.*;
import java.util.Arrays;
import java.util.Objects;

/**
 * @author Anonymous 2022/4/1 16:11
 *
 * 核心方法:
 *      1. 获取数据库连接对象 java.sql.Connection 方法
 *      2. 关闭数据库操作相关资源方法 java.sql.Connection java.sql.Statement, java.sql.ResultSet
 */
public class JdbcUtilsOld {
    /*
    所有成员变量全部 静态修饰 因为对外提供的方法 是通过类名直接调用静态成员方法
     */
    /**
     * 数据库连接 jdbc规范 url 明确数据库所在ip地址,对应端口号,项目选择的数据库名称,和必要连接参数
     */
    private static String jdbcUrl = "jdbc:mysql://localhost:3306/javaee_2203?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false";
    /**
     * 用户名
     */
    private static String username = "root";
    /**
     * 密码
     */
    private static String password = "123456";

    /*
    利用静态代码块在类文件加载阶段完成整个项目的初始化操作,代码块针对于 数据库连接操作所需的驱动执行加载,
    方便后期操作。
     */
    static {
        try {
            /*
            Class.forName 驱动加载
             */
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * JdbcUtils 工具类获取数据库连接对象方法,简化操作流程,获取数据库连接对象
     * 必要参数为当前 JdbcUtils 工具类的成员变量,可以在方法内部使用,用户执行
     * getConnection 无需传入参数信息
     *
     * @return java.sql.Connection 数据库连接对象,如果获取操作失败返回 null
     */
    public static Connection getConnection() {
        Connection connection = null;

        try {
            /*
            通过 DriverManager.getConnection(String url, String username, String passwoed)
            获取数据库连接对象
             */
            connection = DriverManager.getConnection(jdbcUrl, username, password);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

        return connection;
    }

    /**
     * 关闭数据库连接 java.sql.Connection 对象
     *
     * @param connection java.sql.Connection 数据连接对象
     */
    public static void close(Connection connection) {
        close(connection, null, null);
    }

    /**
     * 关闭数据库连接 java.sql.Connection 对象和数据库 SQL 语句搬运工 java.sql.Statement 对象
     *
     * @param connection java.sql.Connection 数据库连接对象
     * @param statement  java.sql.Statement 数据库SQL语句搬运工对象
     */
    public static void close(Connection connection, Statement statement) {
        close(connection, statement, null);
    }

    /**
     * 关闭数据库连接 java.sql.Connection 对象,数据库 SQL 语句搬运工 java.sql.Statement  对象
     * 和 数据库查询结果就 java.sql.ResultSet 对象
     *
     * @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) {
        /*
        Connection  close 方法来自于 interface AutoCloseable
        Statement   close 方法来自于 interface AutoCloseable
        ResultSet   close 方法来自于 interface AutoCloseable
            1. 都有 close 方法!!!
            2. 他们是不是都是数据库相关的!!!
         */

        close(resultSet, statement, connection);
    }

    /**
     * 私有化 close 方法,处理关闭数据库操作相关资源,数据操作为不定长参数,底层代码方式为数组形式。
     * 所有的数据库相关资源都是 AutoCloseable 接口的实现类,可以利用多态思想,整合所有资源,统一关闭
     * 处理
     *
     * @param source AutoCloseable 可关闭资源的不定长参数。
     */
    private static void close(AutoCloseable... source) {
        /*
        集合/数组.iter 快捷键
        for (AutoCloseable autoCloseable : source) {
            try {
                if (autoCloseable != null) {
                    autoCloseable.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

         数组也可以搞 Stream 流,通过 Arrays 数组工具类,调用 stream(T[] t) 获取 Stream 流对象
         这才是现在的代码风格,真的没有 if 和 for
        */
        Arrays.stream(source).filter(Objects::nonNull).forEach(s-> {
            try {
                s.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

    }
}

6. 配置文件方式

package com.qfedu.uitl;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Arrays;
import java.util.Objects;
import java.util.Properties;

/**
 * @author Anonymous 2022/4/1 16:11
 *
 * 核心方法:
 *      1. 获取数据库连接对象 java.sql.Connection 方法
 *      2. 关闭数据库操作相关资源方法 java.sql.Connection java.sql.Statement, java.sql.ResultSet
 */
public class JdbcUtils {
    /*
    所有成员变量全部 静态修饰 因为对外提供的方法 是通过类名直接调用静态成员方法
     */
    /**
     * 数据库连接 jdbc规范 url 明确数据库所在ip地址,对应端口号,项目选择的数据库名称,和必要连接参数
     */
    private static String jdbcUrl;
    /**
     * 用户名
     */
    private static String username;
    /**
     * 密码
     */
    private static String password;

    /*
    利用静态代码块,在加载程序中的过程中,读取 db.properties 文件,解析内容,用于数据库连接必要参数获取
     */
    static {
        try {
            /*
            java.util.Properties Java 属性类 属性存储的方式就是 Key=Value 键值对模型
             */
            // 1. 实例化 Properties 对象
            Properties properties = new Properties();

            /*
             2. 获取配置文件输入流对象 getClassLoader 获取类加载器,在项目中检索指定文件获取对应文件的输入流对象
             */
            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");

            // 3.Properties 对象 load 方法加载对应文件输入流,获取文件信息
            properties.load(in);

            // 4. 读取 Properties 数据内容,对应文件信息
            jdbcUrl = properties.getProperty("jdbcUrl");
            username = properties.getProperty("username");
            password = properties.getProperty("password");

            // 5. 加载驱动
            Class.forName(properties.getProperty("driverClass"));

            // 6. 断言判断,关闭资源
            assert in != null;
            in.close();
        } catch (ClassNotFoundException | IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * JdbcUtils 工具类获取数据库连接对象方法,简化操作流程,获取数据库连接对象
     * 必要参数为当前 JdbcUtils 工具类的成员变量,可以在方法内部使用,用户执行
     * getConnection 无需传入参数信息
     *
     * @return java.sql.Connection 数据库连接对象,如果获取操作失败返回 null
     */
    public static Connection getConnection() {
        Connection connection = null;

        try {
            /*
            通过 DriverManager.getConnection(String url, String username, String passwoed)
            获取数据库连接对象
             */
            connection = DriverManager.getConnection(jdbcUrl, username, password);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

        return connection;
    }

    /**
     * 关闭数据库连接 java.sql.Connection 对象
     *
     * @param connection java.sql.Connection 数据连接对象
     */
    public static void close(Connection connection) {
        close(connection, null, null);
    }

    /**
     * 关闭数据库连接 java.sql.Connection 对象和数据库 SQL 语句搬运工 java.sql.Statement 对象
     *
     * @param connection java.sql.Connection 数据库连接对象
     * @param statement  java.sql.Statement 数据库SQL语句搬运工对象
     */
    public static void close(Connection connection, Statement statement) {
        close(connection, statement, null);
    }

    /**
     * 关闭数据库连接 java.sql.Connection 对象,数据库 SQL 语句搬运工 java.sql.Statement  对象
     * 和 数据库查询结果就 java.sql.ResultSet 对象
     *
     * @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) {
        /*
        Connection  close 方法来自于 interface AutoCloseable
        Statement   close 方法来自于 interface AutoCloseable
        ResultSet   close 方法来自于 interface AutoCloseable
            1. 都有 close 方法!!!
            2. 他们是不是都是数据库相关的!!!
         */

        close(resultSet, statement, connection);
    }

    /**
     * 私有化 close 方法,处理关闭数据库操作相关资源,数据操作为不定长参数,底层代码方式为数组形式。
     * 所有的数据库相关资源都是 AutoCloseable 接口的实现类,可以利用多态思想,整合所有资源,统一关闭
     * 处理
     *
     * @param source AutoCloseable 可关闭资源的不定长参数。
     */
    private static void close(AutoCloseable... source) {
        /*
        集合/数组.iter 快捷键
        for (AutoCloseable autoCloseable : source) {
            try {
                if (autoCloseable != null) {
                    autoCloseable.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

         数组也可以搞 Stream 流,通过 Arrays 数组工具类,调用 stream(T[] t) 获取 Stream 流对象
         这才是现在的代码风格,真的没有 if 和 for
        */
        Arrays.stream(source).filter(Objects::nonNull).forEach(s-> {
            try {
                s.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

    }
}

# driverClass 驱动对应的完整的包名.类名
driverClass=com.mysql.jdbc.Driver

# jdbc 规范 URL 信息
jdbcUrl=jdbc:mysql://localhost:3306/javaee?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false

# 用户名
username=root

# 密码
password=123456
posted @ 2022-05-16 23:40  qtyanan  阅读(71)  评论(0编辑  收藏  举报