vlambda博客
学习文章列表

JCBC——各种连接池的使用

各种连接池的使用

0、 目录

这里整理一下主要目录

1、 自定义JDBC

2、c3p0

3、dpcp

4、druid

5、小结


  • 0、 目录

  • 前言

  • 1、 自定义JDBC

    • 1.1 配置文件和maven依赖

    • 1.2 创建mysql数据库

    • 1.3 创建对应模型beam类

    • 1.4 建立Dao层

    • 1.5 JDBC工具类

    • 1.6 mysql插入数据

    • 1.7 JDBC 查询数据

  • 2、c3p0

    • 2.1 配置文件和maven依赖

    • 2.2 c3p0Util类

    • 2.3 其它工作

    • 2.4 c3p0查询数据

  • 3、dbcp

    • 3.1 配置文件和maven依赖

    • 3.2 DBCPUtil类

    • 3.3 复制自定义JDBC

    • 3.4 dbcp查询数据

  • 4、druid

    • 4.1 配置文件和maven依赖

    • 4.2 DruidUtil类

    • 4.3 复制自定义JDBC

    • 4.4 druid查询数据

  • 5、 小结

    • 5.1 小结

    • 5.2 使用连接池步骤



前言

时隔了快一年的JDBC后文 (-_-!)

前文 ->


1、 自定义JDBC

1.1 配置文件和maven依赖

1.1.1 导入maven依赖

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.22</version>
</dependency>

1.1.2 配置文件

#db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/db_jdbc?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
user=root
password=yuyubuyu
minPoolSize=5

1.2 创建mysql数据库

1.3 创建对应模型beam类

public class User {
    private Integer id;  // 用户id
    private String name; // 用户姓名
    private Integer age; // 用户年龄
    
    //Getter() and Setter()
}

1.4 建立Dao层

1.4.1 接口

public interface UserDao {

    List<User> fetchUsers();

}

1.4.2 实现类

public class UserDaoImpl implements UserDao {
    @Override
    public List<User> fetchUsers() {
        try {
            String sql = "select * from tb_user";
            Connection connection = JDBCUtil.getConnection();
            List<Map<String, Object>> data =
                    JDBCUtil.query(connection, sql);
            if(data==nullreturn null;
            List<User> list = new ArrayList<>();
            for (Map<String, Object> datum : data) {
                User user = new User();
                user.setId((Integer) datum.get("id"));
                user.setName((String) datum.get("name"));
                user.setAge((Integer) datum.get("age"));
                list.add(user);
            }
            return list;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}

1.4.3 代理

public class UserDaoProxy implements UserDao{
    UserDao userDao = new UserDaoImpl();

    @Override
    public List<User> fetchUsers() {
        return userDao.fetchUsers();
    }

}

1.4.4 工厂

public class DaoFactory {
    public static UserDaoProxy newUserDao(){
        return new UserDaoProxy();
    }
}

1.5 JDBC工具类

public class JDBCUtil {

    private static String driver;
    private static String url;
    private static String user;
    private static String password;
//    private static int    maxPoolSize;
    private static int    minPoolSize;

    private static LinkedList<Connection> connections = new LinkedList<>();

    static{
        try {
            Properties properties = new Properties();
            properties.load(JDBCUtil.class.getClassLoader().getResourceAsStream("db.properties"));
            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            user = properties.getProperty("user");
            password = properties.getProperty("password");
            if(properties.getProperty("minPoolSize")==null||"".equals(properties.getProperty("minPoolSize")))
                minPoolSize = 5;
            else minPoolSize = Integer.parseInt(properties.getProperty("minPoolSize"));

            Class.forName(driver);

            forint i = 0; i < minPoolSize; i++ ){
                connections.addLast(DriverManager.getConnection(url, user, password));
            }

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

    private JDBCUtil(){}

    public static int update(Connection connection, PreparedStatement ps, String sql, Object... objects){
        if(connection==null||sql==null||"".equals(sql)){
            return 0;
        }
        try {
            ps = connection.prepareStatement(sql);
            forint i = 0; i < objects.length; i++ ){
                ps.setObject(i+1, objects[i]);
            }
            int count = ps.executeUpdate();
            release(null, ps, null);
            return count;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static List<Map<String, Object>> query(Connection connection, String sql, Object... objects){
        try {
            List<Map<String, Object>> list = new ArrayList<>();
            PreparedStatement ps = connection.prepareStatement(sql);
            forint i = 0; i < objects.length; i++ ){
                ps.setObject(i+1, objects[i]);
            }
            ResultSet rs = ps.executeQuery();
            ResultSetMetaData metaData = rs.getMetaData();
            int cols_len = metaData.getColumnCount();
            while (rs.next()) {
                Map<String, Object> map = new HashMap<>();
                for (int i = 0; i < cols_len; i++) {
                    String cols_name = metaData.getColumnName(i + 1);
                    Object cols_value = rs.getObject(cols_name);
                    map.put(cols_name, cols_value);
                }
                list.add(map);
            }
            release(null, ps, rs);
            return list;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Connection getConnection() throws SQLException {
        if( connections.size() > 0 ) {
            return connections.removeFirst();
        }
        return DriverManager.getConnection(url, user, password);
    }

    public static void release(Connection connection, PreparedStatement ps, ResultSet rs){
        try {
            
            if(connection!=null){
                connections.addLast(connection);
            }

            if(ps!=null)
                ps.close();

            if(rs!=null)
                rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void release(){
        while(!connections.isEmpty()){
            try {
                connections.removeFirst().close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

}

1.6 mysql插入数据

JCBC——各种连接池的使用

1.7 JDBC 查询数据

1.7.1 程序

@Test
public void test(){
    System.out.println("MyJDBC: " + DaoFactory.newUserDao().fetchUsers());
}

1.7.2 结果

JCBC——各种连接池的使用

2、c3p0

2.1 配置文件和maven依赖

2.1.1 导入maven依赖

<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.4</version>
</dependency>

2.1.2 配置文件

<!-- c3p0-config.xml  -->
<?xml version="1.0" encoding="utf-8" ?>
<c3p0-config>
    <default-config>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/db_jdbc?useSSL=false&amp;allowPublicKeyRetrieval=true&amp;serverTimezone=UTC</property>
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="user">root</property>
        <property name="password">yuyubuyu</property>

        <property name="acquireIncrement">3</property>
        <property name="initialPoolSize">5</property>
        <property name="minPoolSize">2</property>
        <property name="maxPoolSize">20</property>
    </default-config>
</c3p0-config>

2.2 c3p0Util类

public class c3p0Util {

    private static DataSource dataSource;

    static {
        dataSource = new ComboPooledDataSource();
    }

    public static Connection getConnection(){
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void release(Connection connection, PreparedStatement ps, ResultSet rs){
        if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(ps!=null){
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

}

有点麻烦,好浪费时间,所以导入DBUtils

<dependency>
    <groupId>commons-dbutils</groupId>
    <artifactId>commons-dbutils</artifactId>
    <version>1.7</version>
</dependency>

2.3 其它工作

其它没有写的部分copy自前文代码,没有修改

2.3.1 改写c3p0Util

public class c3p0Util {

    private static DataSource dataSource;

    static {
        dataSource = new ComboPooledDataSource();
    }

    public static QueryRunner getQueryRunner(){
        return new QueryRunner(dataSource);
    }

    /**
     * @author LOS
     * @deprecated 已改用DBUtils
     * @return fetch from dataSource
     */

    public static Connection getConnection(){
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @deprecated 已改用DBUtils
     * @param connection 连接
     * @param ps         PreparedStatement
     * @param rs         ResultSet
     */

    public static void release(Connection connection, PreparedStatement ps, ResultSet rs){
        if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(ps!=null){
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

}

2.3.2 UserDao实现类

public class UserDaoImpl implements UserDao {
    @Override
    public List<User> fetchUsers() {
        QueryRunner qr = c3p0Util.getQueryRunner();
        String sql = "select * from tb_user";
        try {
            return qr.query(sql, new BeanListHandler<>(User.class));
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

2.4 c3p0查询数据

JCBC——各种连接池的使用

3、dbcp

3.1 配置文件和maven依赖

3.1.1 导入maven依赖

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-dbcp2</artifactId>
    <version>2.8.0</version>
</dependency>
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.22</version>
</dependency>

3.1.2 配置文件

########DBCP配置文件##########
#驱动名
driverClassName=com.mysql.cj.jdbc.Driver
#url
url=jdbc:mysql://localhost:3306/db_jdbc?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
#用户名
username=root
#密码
password=yuyubuyu
#初试连接数
initialSize=30
#最大活跃数
maxTotal=30
#最大idle数
maxIdle=10
#最小idle数
minIdle=5
#最长等待时间(毫秒)
maxWaitMillis=1000
#程序中的连接不使用后是否被连接池回收(该版本要使用removeAbandonedOnMaintenance和removeAbandonedOnBorrow)
#removeAbandoned=true
removeAbandonedOnMaintenance=true
removeAbandonedOnBorrow=true
#连接在所指定的秒数内未使用才会被删除(秒)(为配合测试程序才配置为1秒)
removeAbandonedTimeout=1

3.2 DBCPUtil类

public class DBCPUtil {

    private static DataSource dataSource;

    static{
        try {
            Properties properties = new Properties();
            properties.load(DBCPUtil.class.getClassLoader().getResourceAsStream("dbcp.properties"));
            dataSource = BasicDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private DBCPUtil(){}

    public static int update(Connection connection, PreparedStatement ps, String sql, Object... objects){
        if(connection==null||sql==null||"".equals(sql)){
            return 0;
        }
        try {
            ps = connection.prepareStatement(sql);
            forint i = 0; i < objects.length; i++ ){
                ps.setObject(i+1, objects[i]);
            }
            int count = ps.executeUpdate();
            release(null, ps, null);
            return count;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static List<Map<String, Object>> query(Connection connection, String sql, Object... objects){
        try {
            List<Map<String, Object>> list = new ArrayList<>();
            PreparedStatement ps = connection.prepareStatement(sql);
            forint i = 0; i < objects.length; i++ ){
                ps.setObject(i+1, objects[i]);
            }
            ResultSet rs = ps.executeQuery();
            ResultSetMetaData metaData = rs.getMetaData();
            int cols_len = metaData.getColumnCount();
            while (rs.next()) {
                Map<String, Object> map = new HashMap<>();
                for (int i = 0; i < cols_len; i++) {
                    String cols_name = metaData.getColumnName(i + 1);
                    Object cols_value = rs.getObject(cols_name);
                    map.put(cols_name, cols_value);
                }
                list.add(map);
            }
            release(null, ps, rs);
            return list;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    public static void release(Connection connection){
        if (connection!=null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public static void release(Connection connection, PreparedStatement ps, ResultSet rs){
        try {

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

            if(ps!=null)
                ps.close();

            if(rs!=null)
                rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

}

3.3 复制自定义JDBC

从自定义JDBC项目下复制以下包:

1、dao包

2、proxy包

3、factory包

4、model包

3.4 dbcp查询数据

JCBC——各种连接池的使用

4、druid

4.1 配置文件和maven依赖

4.1.1 导入maven依赖

感觉用的还是有点早,其实c3p0和dbcp够学了

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.5</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.22</version>
</dependency>

4.1.2 配置文件

# druid.properties
url=jdbc:mysql://localhost:3306/db_jdbc?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
driverClassName=com.mysql.cj.jdbc.Driver
username=root
password=yuyubuyu

##初始连接数,默认0
initialSize=10
#最大连接数,默认8
maxActive=30
#最小闲置数
minIdle=10
#获取连接的最大等待时间,单位毫秒
maxWait=2000
#缓存PreparedStatement,默认false
poolPreparedStatements=true
#缓存PreparedStatement的最大数量,默认-1(不缓存)。大于0时会自动开启缓存PreparedStatement,所以可以省略上一句设置
maxOpenPreparedStatements=20

4.2 DruidUtil类

public class DruidUtil {

    private static DataSource dataSource;

    static{
        try {
            Properties properties = new Properties();
            properties.load(DruidUtil.class.getClassLoader().getResourceAsStream("druid.properties"));
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private DruidUtil(){}

    public static int update(Connection connection, PreparedStatement ps, String sql, Object... objects){
        if(connection==null||sql==null||"".equals(sql)){
            return 0;
        }
        try {
            ps = connection.prepareStatement(sql);
            forint i = 0; i < objects.length; i++ ){
                ps.setObject(i+1, objects[i]);
            }
            int count = ps.executeUpdate();
            release(null, ps, null);
            return count;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static List<Map<String, Object>> query(Connection connection, String sql, Object... objects){
        try {
            List<Map<String, Object>> list = new ArrayList<>();
            PreparedStatement ps = connection.prepareStatement(sql);
            forint i = 0; i < objects.length; i++ ){
                ps.setObject(i+1, objects[i]);
            }
            ResultSet rs = ps.executeQuery();
            ResultSetMetaData metaData = rs.getMetaData();
            int cols_len = metaData.getColumnCount();
            while (rs.next()) {
                Map<String, Object> map = new HashMap<>();
                for (int i = 0; i < cols_len; i++) {
                    String cols_name = metaData.getColumnName(i + 1);
                    Object cols_value = rs.getObject(cols_name);
                    map.put(cols_name, cols_value);
                }
                list.add(map);
            }
            release(null, ps, rs);
            return list;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    public static void release(Connection connection){
        if (connection!=null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public static void release(Connection connection, PreparedStatement ps, ResultSet rs){
        try {

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

            if(ps!=null)
                ps.close();

            if(rs!=null)
                rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

}

4.3 复制自定义JDBC

从自定义JDBC项目下复制以下包:

1、dao包

2、proxy包

3、factory包

4、model包

4.4 druid查询数据

5、 小结

5.1 小结

我也是刚知道DruidhiKaryCP这些连接池,也是兴冲冲一头扎进了相关文档啃了半天,琢磨了半天之后也得出了一件意义重大的结论:

学了这么多没什么卵用。

它们也只是连接池,知乎上也经常有人吹:

得到的工具可以随时改换,学到的技术却是不分高低

所以本文最大篇幅还是集中于自定义JDBC中,知道传统的JDBC如何工作,又有什么麻烦的地方,才能知道工具带来什么便利。

5.2 使用连接池步骤

  1. 导入相关依赖
  2. 编辑配置文件
  3. 读取配置文件并生成 DataSource实例
  4. DataSource实例获取 Connection
  5. 数据库读写操作
  6. 回收 Connection