JDBC10 - 工具类封装

Druid - 获取连接与回收连接封装

  • v1.0版本工具类
    • 内部包含一个连接池对象
    • 对外提供获取连接和回收连接的方法
  • 小建议:
    • 工具类的方法,写出静态,方便外部调用
  • 实现:
    • 属性 连接池对象 [实例化一次]
      • 单例模式
      • 静态代码块 static
    • 方法
      • 对外提供连接的方法
      • 回收外部传入连接的方法
public class JDBCUtils{

    private static DataSource dataSource = null; //连接池对象

    static{
        //初始化连接池对象
        Properties properties = new Properties();
        InputStream ips = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");

        try {
            properties.load(ips);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        try {
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 对外提供连接的方法
     * @return
     */
    public static Connection getConnection(){
        try {
            return dataSource.getConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void freeConnection(Connection connection) throws SQLException {
        connection.close();
    }

}

工具类的使用

public void testInsert() throws SQLException {

    //创建连接
    Connection connection = JDBCUtils.getConnection();

    //数据库CRUD

    //回收连接
    JDBCUtils.freeConnection(connection);
}

优化 v2.0 如何在一个线程的不同方法获取同一连接

在银行业务模拟中,BankService层将connection作为参数传入BankDao层,需要在实现方法时多设置一个参数。如何实现不用传参,在BankService层和BankDao层获取同一连接? 其中BankService层和BankDao层是同一个线程?

使用线程本地变量 ThreadLocal

可以为同一线程存储共享变量 -- 即将一个线程的connection设置为共享变量,在线程的每一处都可以随时使用

线程本地变量

/**
 * @author Ashen
 * @program atguigu-jdbc
 * @data 2023-01-13 15:23
 *
 * v2.0
 * TODO:
 *      利用线程本地变量,存储连接信息,确保一个线程的多个方法可以获取同一个connection
 *      原理:事物操作的时候 service 和 dao 属于同一个线程,不用再传递参数
 *      线程中所有方法都可以随时调用同一connection
 **/
public class JDBCUtilsV2 {

    private static DataSource dataSource = null; //连接池对象

    //线程本地变量 存放线程相应的connection
    private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();

    static{
        //初始化连接池对象
        Properties properties = new Properties();
        InputStream ips = JDBCUtilsV2.class.getClassLoader().getResourceAsStream("druid.properties");

        try {
            properties.load(ips);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        try {
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 对外提供连接的方法
     * @return
     */
    public static Connection getConnection(){

        //查看线程本地变量中是否存在
        Connection connection = threadLocal.get();

        //第一次没有创建connection
        if(connection == null){
            try {
                connection = dataSource.getConnection();

                //将创建的线程存入线程本地变量中
                threadLocal.set(connection);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public static void freeConnection() throws SQLException {
        //查看线程本地变量是否存在,若存在需要先清空
        Connection connection = threadLocal.get();

        if(connection != null) {
            threadLocal.remove();
            //事务状态回归
            connection.setAutoCommit(true);
            connection.close();
        }
    }
}
posted @   LaViez  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示