zoukankan      html  css  js  c++  java
  • 【Java】JDBC Part5 DataSource 连接池操作

    JDBC Part5 DataSource 连接池操作

    - javax.sql.DataSource 接口,通常由服务器实现

    - DBCP  Tomcat自带相对C3P0速度较快,但存在BUG,已经不更新了

    - Proxool  没听过、能监控连接池状态,稳定性差

    - C3P0  速度较慢,但是稳定

    - Druid  阿里巴巴提供,集成上面的所有优点,

    - Hikari  目前最快的连接池依赖,据说有安全问题。。。

    DataSource被称为数据源,包含连接池和连接池管理2部分


    C3P0实现

    官方文档:  https://blog.csdn.net/wangwei_cq/article/details/8930667

    Maven依赖

    <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
    <dependency>
        <groupId>com.mchange</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.5.5</version>
    </dependency>

    第一种,硬编码的连接池

    package connector;
    
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    import org.junit.Test;
    
    import java.beans.PropertyVetoException;
    import java.sql.Connection;
    import java.sql.SQLException;
    
    /**
     * @author ArkD42
     * @file Jdbc
     * @create 2020 - 04 - 24 - 17:49
     */
    public class C3P0Test {
    
        @Test
        public void dataSourceByC3p0() throws PropertyVetoException, SQLException {
            // 获取池对象
            ComboPooledDataSource dataSource = new ComboPooledDataSource();
            // 配置连接信息
            dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
            dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/jdbc_db?serverTimezone=Asia/Shanghai");
            dataSource.setUser("root");
            dataSource.setPassword("123456");
            //设置初始的连接数
            dataSource.setInitialPoolSize(10); 
            //获取连接
            Connection connection = dataSource.getConnection();
            System.out.println(connection);
        }
    }

    测试结果

    第二种 XML配置文件

    配置XML配置文件的信息

    <?xml version="1.0" encoding="UTF-8" ?>
    <c3p0-config>
        <!-- 自定义的配置命名-->
        <named-config name="c3p0 XML config">
    
            <!-- 四个基本信息 -->
            <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
            <!-- 默认本地可以省略 jdbc:mysql:///jdbc_db?serverTimezone=Asia/Shanghai -->
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc_db?serverTimezone=Asia/Shanghai</property>
            <property name="user">root</property>
            <property name="password">123456</property>
    
            <!-- 连接池管理信息 -->
    
            <!-- 连接对象数不够时,每次申请 迭增的连接数 -->
            <property name="acquireIncrement">5</property>
            <!-- 初始池大小存放的连接对象数 -->
            <property name="initialPoolSize">10</property>
            <!-- 最小连接对象数 -->
            <property name="minPoolSize">10</property>
            <!-- 最大连接对象数,不可超出的范围 -->
            <property name="maxPoolSize">100</property>
            <!-- 最多维护的SQL编译对象个数-->
            <property name="maxStatements">50</property>
            <!-- 每个连接对象最多可使用的SQL编译对象的个数 -->
            <property name="maxStatementsPerConnection">2</property>
        </named-config>
    </c3p0-config>

    注意获取配置名

    如果密码错误,其他配置问题,连接池运行一段时间获取不到连接自动超时退出,报异常


    封装JdbcForC3P0Util工具类

    import java.sql.*;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author ArkD42
     * @file Jdbc
     * @create 2020 - 04 - 24 - 18:23
     */
    public class JdbcForC3p0Util {
    
        // 池对象只需要一个即可
        private static final ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("c3p0 XML config");
    
        // 获取连接对象,从池对象获取的对象可允许多个
        public static Connection getConnection(){
            try {
                return comboPooledDataSource.getConnection();
            } catch (SQLException sqlException) {
                sqlException.printStackTrace();
            }
            return null;
        }
    
        // 释放资源 对象没有的情况直接null注入
        public static void releaseResource(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet){
            try{
                if (resultSet != null) resultSet.close();
                if (preparedStatement != null) preparedStatement.close();
                if (connection != null) connection.close();
            } catch (SQLException sqlException){
                sqlException.printStackTrace();
            }
        }
    
        // 增删改
        public static int update(String sql,Object[] args) {
            Connection connection = null;
            PreparedStatement preparedStatement = null;
            try {
                connection = getConnection();
                preparedStatement = connection.prepareStatement(sql);
                if (args != null ) for (int i = 0; i < args.length; i++) preparedStatement.setObject(i+1,args[i]);
                int i = preparedStatement.executeUpdate();
                return i;
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                releaseResource(connection,preparedStatement,null);
            }
            return 0;
        }
        
        // 查询
        public static <T> List<T> queryList(Class<T> tClass, String sql, Object[] args){
            Connection connection = null;
            PreparedStatement preparedStatement = null;
            ResultSet resultSet = null;
            try{
                connection = getConnection();
                preparedStatement = connection.prepareStatement(sql);
                if (args != null) for (int i = 0; i < args.length; i++) preparedStatement.setObject(i+1,args[i]);
                resultSet = preparedStatement.executeQuery();
                ResultSetMetaData metaData = resultSet.getMetaData();
                int columnCount = metaData.getColumnCount();
                List<T> tList = new ArrayList<T>();
                while(resultSet.next()){
                    T t = tClass.newInstance();
                    for (int i = 0; i < columnCount; i++) {
                        Object columnValue = resultSet.getObject(i + 1);
                        String columnLabel = metaData.getColumnLabel(i + 1);
                        Field field = tClass.getDeclaredField(columnLabel);
                        field.setAccessible( true );
                        field.set(t,columnValue);
                    }
                    tList.add(t);
                }
                return tList;
            } catch (Exception e){
                e.printStackTrace();
            } finally {
                releaseResource(connection,preparedStatement,resultSet);
            }
            return null;
        }
    }

    测试,Blob不可封装为实体类对象,所以大文件的字段我删除了


    DBCP 连接池操作

    Maven依赖

    <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-dbcp2</artifactId>
      <version>2.7.0</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
      <version>2.8.0</version>
    </dependency>

    连接实现一,硬编码连接

    public class DBCP {
    
        @Test
        public void dbcp() throws Exception{
            // 创建连接池
            BasicDataSource dataSource = new BasicDataSource();
    
            // 配置信息
            dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
            dataSource.setUrl("jdbc:mysql:///jdbc_db?serverTimezone=Asia/Shanghai");
            dataSource.setUsername("root");
            dataSource.setPassword("123456");
    
            // 连接池管理设置
            //dataSource.setInitialSize(10);  //  初始化池种的连接对象个数
            //dataSource.setMaxIdle(10);      //  最大空闲连接对象个数
            //dataSource.setMinIdle(2);       //  最小空闲连接对象个数
            
            // 获取连接对象
            Connection connection = dataSource.getConnection();
    
            System.out.println(connection);
            connection.close();
        }
    }

    测试结果


    连接实现二,读取配置文件

    dbcp.properties配置文件的信息

    # 注意这个driverClassName 
    driverClassName = com.mysql.cj.jdbc.Driver
    url = jdbc:mysql:///jdbc_db?serverTimezone=Asia/Shanghai
    # 注意这个username
    username = root
    password = 123456

    测试单元

        @Test
        public void dbcp2() throws Exception{
            InputStream inputStream = DBCP.class.getClassLoader().getResourceAsStream("dbcp.properties");
            Properties properties = new Properties();
            properties.load(inputStream);
            BasicDataSource dataSource = BasicDataSourceFactory.createDataSource(properties);
            Connection connection = dataSource.getConnection();
            System.out.println(connection);
            connection.close();
        }

    第一种获取方式【通用】

    InputStream inputStream = DBCP.class.getClassLoader().getResourceAsStream("dbcp.properties");

    第二种获取方式

    // Maven工程的读取路径
    InputStream inputStream = new FileInputStream(new File("src/main/resources/dbcp.properties"));
    
    // 普通工程的读取路径
    InputStream inputStream = new FileInputStream(new File("src/dbcp.properties"));

    第三种获取方式【通用,防空格中文编码不读取】

    String file = DBCP.class.getClassLoader().getResource("dbcp.properties").getFile();
    String decode = URLDecoder.decode(file, "utf-8");
    
    //System.out.println(file);
    //System.out.println(decode);
    
    InputStream inputStream = new FileInputStream(decode);

    测试结果

    JdbcDbcpUtil 工具类封装

    public class JdbcDbcpUtil {
    
        private static DataSource dataSource = null;
        
        static {
            String path = JdbcDbcpUtil.class.getClassLoader().getResource("dbcp.properties").getFile();
            System.out.println(path);
            try {
                String decode = URLDecoder.decode(path, "utf-8");
                InputStream inputStream = new FileInputStream(decode);
                Properties properties = new Properties();
                properties.load(inputStream);
                dataSource = BasicDataSourceFactory.createDataSource(properties);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static Connection getConnection(){
            try {
                return dataSource.getConnection();
            } catch (SQLException sqlException) {
                sqlException.printStackTrace();
            }
            return null;
        }
    
    }

    测试结果


     

    Druid连接池实现

    Maven依赖

    <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.22</version>
    </dependency>

    硬编码连接

        @Test
        public void dt1() throws SQLException {
            DruidDataSource dataSource = new DruidDataSource();
    
            dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
            dataSource.setUrl("jdbc:mysql:///jdbc_db?serverTimezone=Asia/Shanghai");
            dataSource.setUsername("root");
            dataSource.setPassword("123456");
    
            DruidPooledConnection connection = dataSource.getConnection();
            System.out.println(connection);
            connection.close();
        }

    读取配置文件,读取方式跟DBCP几乎一样,配置文件都不需要改

        @Test
        public void dt2() throws Exception {
            String path = DruidTest.class.getClassLoader().getResource("dbcp.properties").getFile();
            String decode = URLDecoder.decode(path, "utf-8");
            FileInputStream inputStream = new FileInputStream(decode);
            Properties properties = new Properties();
            properties.load(inputStream);
            DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
            Connection connection = dataSource.getConnection();
            System.out.println(connection);
            connection.close();
        }

    JdbcDruidUtils 工具类封装

    【对着DBCP的直接改连接池工厂就完事了】

    public class JdbcDruidUtil {
    
        private static DataSource dataSource = null;
    
        static {
            String path = JdbcDbcpUtil.class.getClassLoader().getResource("druid.properties").getFile();
            System.out.println(path);
            try {
                String decode = URLDecoder.decode(path, "utf-8");
                InputStream inputStream = new FileInputStream(decode);
                Properties properties = new Properties();
                properties.load(inputStream);
                dataSource = DruidDataSourceFactory.createDataSource(properties);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static Connection getConnection(){
            try {
                return dataSource.getConnection();
            } catch (SQLException sqlException) {
                sqlException.printStackTrace();
            }
            return null;
        }
    }
  • 相关阅读:
    密码学常用解码网站
    macOS VMware Fusion 中 vmtools为灰色
    XSS-Payloads
    Tomcat 漏洞总结
    mac 更新完Big Sur需重新配置项目
    sqlmap的使用 ---- 自带绕过脚本tamper
    FTP 日志分析
    CentOS Java环境问题
    Nginx 学习
    英语学习-邮件表达方法 例句
  • 原文地址:https://www.cnblogs.com/mindzone/p/12769276.html
Copyright © 2011-2022 走看看