JDBC-Util

JDBC-Util

JDBC连接池工具类的封装 V1.0

package com.xiaobai.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class JDBCUtil {
    //JDBC工具类 V1.0
    //创建一个连接池引用,提供给当前项目的全局使用
    private static DataSource dataSource;

    //static代码块中的内容随项目启动而加载,当项目启动时,自动建立连接池
    static {
        try {
            Properties properties = new Properties();
            InputStream resourceAsStream = JDBCUtil.class.getClassLoader().getResourceAsStream("db.properties");
            properties.load(resourceAsStream);
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //对外开放一个获取连接的方法
    public static Connection getConnection() {
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    //对外开放一个回收链接的方法
    public static void close(Connection conn) {
        try {
            conn.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

TreadLocal

java.lang.TreadLocal,为解决多线程程序的并发问题的工具类

通常用来在多线程中管理、共享数据库连接、Session等

在Java中,每一个线程对象都有TreadLocalMap<Threadlocal, Object> ,其key是ThreadLocal,Object为该线程的共享对象


JDBC连接池工具类的封装 V2.0

使用Treadlocal改写工具类的意义就是:

同一个线程在多次操作数据库的过程中,用到的是同一个连接

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * JDBC工具类 V2.0
 * 创建一个连接池引用,提供给当前项目的全局使用
 * 同时,维护了一个线程绑定变量的ThreadLocal对象
 * 后续,加入了对事务回收线程的判定,方便事务的使用
 */
public class JDBCUtilV2 {
    private static DataSource dataSource;
    private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
    ;

    /*
      static代码块中的内容随项目启动而加载,当项目启动时,自动建立连接池
     */
    static {
        try {
            Properties properties = new Properties();
            InputStream resourceAsStream = JDBCUtilV2.class.getClassLoader().getResourceAsStream("jdbc.properties");
            properties.load(resourceAsStream);
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 对外开放一个获取连接的方法
     *
     * @return 返回一个从连接池中获取到的连接
     */
    public static Connection getConnection() {
        try {
            //在threadlocal中获取Connection
            Connection connection = threadLocal.get();
            if (connection == null) {
                //此时,threadLocal中没有连接,是第一次获取
                connection = dataSource.getConnection();
                threadLocal.set(connection);
            }
            return connection;
            //如果是第一次获取,则从连接池中拿一个连接,先放到threadlocal中,再把该连接返回
            //如果不是第一次获取,则从threadlocal中获取到这个连接,把该链接返回
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 这是一个回收连接的方法
     */
    public static void close() {
        try {
            //从theadlocal中获取到连接,判断是否有线程
            //如果有,该连接回收到连接池,并将threadlocal中的连接移除
            Connection connection = threadLocal.get();
            if (connection != null) {
                connection.close();
                threadLocal.remove();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}