JDBC连接工具类-多线程

上篇文章中介绍的JDBC连接工具类在单线程下可以正常跑,但是如果有多线程同时访问,将会出现线程安全问题。下面介绍使用ThreadLocal类来完成一个线程安全的数据库工具类。

db.properties配置文件:

className=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/day16
user=root
password=123456

DBUtil类代码:

public class DBUtil {
  private static ThreadLocal<Connection> connContainer = 
    new ThreadLocal<>();

    private static String className;
    private static String url;
    private static String user;
    private static String password;
    static{
      try{
        InputStream in = DBUtil.class.getClassLoader()
             .getResourceAsStream("db.properties");
        Properties props = new Properties();
        props.load(in);
        className = props.getProperty("className");
        url = props.getProperty("url");
        user = props.getProperty("user");
        password = props.getProperty("password");
        Class.forName(className);
      }catch(Exception e){
        e.printStackTrace();
      }
    }
    // 创建连接,并放入到当前线程的本地变量中
    public static Connection getConnection() {
      Connection conn = connContainer.get();
      try {
        if (null == conn) {
          Class.forName(className);
          conn = DriverManager.getConnection(url, user, password);
        }
      } catch (Exception e) {
        e.printStackTrace();
      } finally {
      connContainer.set(conn);
    }
    return conn;
  }
  // 关闭连接,从当前线程的本地变量中获取连接
  public static void closeConn() {
    Connection conn = connContainer.get();
    try {
      if (null != conn) {
        conn.close();
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      connContainer.remove();
    }
  }
}

注意:以上工具类可以用在访问量不高的多线程环境中,但是如果是高并发的访问场景,上述方式将会存在性能瓶颈,即:获取连接的时候。每次连接如果不存在,需要去连接MySQL,创建连接。如果高并发的场景,可能需要引入JDBC连接池,目前有许多开源的连接池可供选择,比如:Durid,c3p0,dbcp等。

注:文章属作者原创,如果转发,请务必标注出处:https://www.jinnianshizhunian.vip