Skip to content

工具类封装

前面使用 JDBC 的过程中,可以发现每次都会有重复性的代码需要写,比如:

  • 创建连接池;
  • 获取连接;
  • 连接回收;

这时候就可以考虑将上面重复性的代码进行封装。

JDBC封装V1.0

封装采用软编码的方式,将配置信息存储在 db.properties 配置文件中。

java
public class JDBCUtil {
  private static DataSource dataSource;

  static {
    try {
      Properties properties = new Properties();
      InputStream resourceAsStream = JDBCUtil.class.getClassLoader().getResourceAsStream("db.properties");
      properties.load(resourceAsStream);

      // 创建 DruidDataSource 对象
      dataSource = DruidDataSourceFactory.createDataSource(properties);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  public static Connection getConnection() throws SQLException {
    return dataSource.getConnection();
  }

  public static void release(Connection connection) throws SQLException {
    connection.close();
  }
}
properties
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/atguigu
username=root
password=1234
initialSize=10
maxActive=20

V1.0 版本存在的缺点

每次使用 JDBCUtil.getConnection() 获取连接对象时,都会创建一个新的对象,导致频繁的创建和回收对象,影响性能;

ThreadLocal类

ThreadLocal 用于保存某个程序共享变量,简单来说,它可以让每个线程都拥有自己独立的变量副本,从而避免多线程并发访问时可能出现的问题。

原理

在 java 中,每一个线程对象都有一个 ThreadLocalMap<ThreadLocal, Object> ,其中 key 就是 ThreadLocal,而 Object 即为该线程的共享变量。

使用场景:

  • 在进行对象跨层传递的时候,使用 ThreadLocal 可以避免多次传递,打破层次间的约束;
  • 线程间数据隔离;
  • 进行事务操作,用于存储线程事务信息;
  • 数据库连接,Session 会话管理;
java
ThreadLocal<String> threadLocal = new ThreadLocal<>();

// 设置线程局部变量
threadLocal.set("Hello ThreadLocal");

// 获取线程局部变量
String value = threadLocal.get();

// 移除局部变量
threadLocal.remove();

JDBC封装V2.0

V2.0 的封装借助了 ThreadLocal 类,将第一次创建的 connection 进行缓存,后续直接使用缓存的对象,这样就避免了频繁的创建和回收连接对象。

java
public class JDBCUtilV2 {
  private static DataSource dataSource;
  private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();

  static {
    try {
      Properties properties = new Properties();
      InputStream resourceAsStream = JDBCUtil.class.getClassLoader().getResourceAsStream("db.properties");
      properties.load(resourceAsStream);

      // 创建 DruidDataSource 对象
      dataSource = DruidDataSourceFactory.createDataSource(properties);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  public static Connection getConnection() throws SQLException {
    Connection connection = threadLocal.get();
    if (connection == null) {
      connection = dataSource.getConnection();
      threadLocal.set(connection);
    }
    return connection;
  }

  public static void release() throws SQLException {
    Connection connection = threadLocal.get();
    if (connection != null) {
      connection.close();
      threadLocal.remove();
    }
  }
}

Released under the MIT License.