JDBC(八)—— 数据库连接池

连接池

c3p0连接池操作

  1. 导入c3p0和mysql驱动需要的包

  2. 在src目录下创建c3p0-config.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <c3p0-config>
    <!-- This app is massive! -->
    <named-config name="mysql">
       <!--   连接MySQL基本的配置-->
       <property name="jdbcUrl">jdbc:mysql://localhost:3306/mvcproject?serverTimezone=Asia/Shanghai</property>
       <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
       <property name="user">root</property>
       <property name="password">root</property>

       <!--       若数据库中的连接数量不足时,向数据库申请的连接数量-->
       <property name="acquireIncrement">5</property>
       <!--       初始化数据库连接池时链接的数量-->
       <property name="initialPoolSize">10</property>
       <!--       数据库连接池中最小的数据库链接数-->
       <property name="minPoolSize">5</property>
       <!--       数据库连接池中最大的数据库链接数-->
       <property name="maxPoolSize">100</property>

       <!-- intergalactoApp adopts a different approach to configuring statement caching -->
       <!--       c3p0数据库连接池可维护的Statement数量-->
       <property name="maxStatements">2</property>
       <!--       每个连接同时可使用的Statement数量-->
       <property name="maxStatementsPerConnection">5</property>

    </named-config>
    </c3p0-config>
  3. 创建JdbcUtils

    import com.mchange.v2.c3p0.ComboPooledDataSource;

    import javax.sql.DataSource;
    import java.sql.Connection;
    import java.sql.SQLException;

    /**
    * jdbc工具类
    *
    * @author why
    */
    public class JdbcUtils {

       //数据库连接池,C3P0
       private static DataSource dataSource = null;
       static {//静态代码块只会被执行一次
           dataSource = new ComboPooledDataSource();
      }

       /**
        * 获取到mysql的数据库连接对象
        *
        * @return conn
        */
       public static Connection getConnection(){
           Connection conn = null;
           try {
               conn = dataSource.getConnection();
          } catch (SQLException e) {
               e.printStackTrace();
          }
           return conn;
      }
       
       /**
        * 通用的关闭数据库连接对象的方法
        * @param conn
        */
       public static void closeConn(Connection conn){
           if (conn != null){
               try {
                   conn.close();
              } catch (SQLException e) {
                   e.printStackTrace();
              }
          }
      }
    }
  4. 创建BaseDao

    package com.why.study2.dao;

    import com.why.study2.utils.JdbcUtils;
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.handlers.BeanHandler;
    import org.apache.commons.dbutils.handlers.BeanListHandler;
    import org.apache.commons.dbutils.handlers.ScalarHandler;

    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;

    /**
    * 这是一个dao层中的基本类,在于被具体的dao类继承,不能直接new BasesDao()来直接使用
    *
    * @author why
    * @param <T>   针对要操作各章数据包映射到java工程里的java类
    */
    public class BaseDao<T> {

       QueryRunner queryRunner = new QueryRunner();

       private Class<T> Clazz;

       /**
        * 反射拿到T.class
        */
       public BaseDao() {
           //用BaseDao的构造器初始化aClass属性
           //拿到User类
           Type superType = this.getClass().getGenericSuperclass();//getGenericSuperclass()拿到调用者的父类的类型
           //拿到User.class
           if (superType instanceof ParameterizedType){
               ParameterizedType pt = (ParameterizedType) superType;
               Type[] tarry = pt.getActualTypeArguments();//返回类型数组,其第一个元素是我们需要的T.class
               if (tarry[0] instanceof Class){
                   Clazz = (Class<T>) tarry[0];
              }
          }
      }

       /**
        * 查询数据表,取出结果sql语句的结果集的第一条数据,封装成一个类对象返回,不支持事务
        * 用到dbutils工具类
        * @param sql
        * @param args
        * @return
        */
       public T get(String sql,Object... args){
           Connection conn = null;
           T entity = null;

           //拿到conn
           try {
               conn = JdbcUtils.getConnection();
               entity = queryRunner.query(conn,sql, new BeanHandler<T>(Clazz),args);
          } catch (Exception e) {
               e.printStackTrace();
          } finally {
               JdbcUtils.closeConn(conn);
          }
           return entity;
      }

       /**
        * 重写查询数据表方法,取出结果sql语句的结果集的第一条数据,封装成一个类对象返回,支持事务
        * @param sql
        * @param args
        * @return
        */
       public T get(Connection conn,String sql,Object... args){
           T entity = null;
           try {
               entity = queryRunner.query(conn,sql, new BeanHandler<T>(Clazz),args);
          } catch (Exception e) {
               e.printStackTrace();
          } finally {

          }
           return entity;
      }

       /**
        * 获取多条记录的通用方法
        * @return
        */
       List<T> getList(String sql,Object... args){
           Connection conn = null;
           List<T> list = null;

           //拿到conn
           try {
               conn = JdbcUtils.getConnection();
               list = queryRunner.query(conn,sql, new BeanListHandler<T>(Clazz),args);
          } catch (Exception e) {
               e.printStackTrace();
          } finally {
               JdbcUtils.closeConn(conn);
          }
           return list;
      }

       /**
        * 实现insert,update,delete通用的更新方法
        * @param sql
        * @param args
        * @return
        */
       int update(String sql,Object... args){
           Connection conn = null;
           int rows = 0;

           //拿到conn
           try {
               conn = JdbcUtils.getConnection();
               rows = queryRunner.update(conn,sql,args);
          } catch (Exception e) {
               e.printStackTrace();
          } finally {
               JdbcUtils.closeConn(conn);
          }
           return rows;
      }

       /**
        * 通用的sql语句的结果只有一个数值的类型的查询,用户个数或其他计数
        * @param sql
        * @param args
        * @return
        */
       Object getValue(String sql,Object... args){
           Connection conn = null;
           Object obj = null;

           //拿到conn
           try {
               conn = JdbcUtils.getConnection();
               obj = queryRunner.query(conn,sql, new ScalarHandler<>(),args);
          } catch (Exception e) {
               e.printStackTrace();
          } finally {
               JdbcUtils.closeConn(conn);
          }
           return obj;

      }
    }
  5. 创建工厂类,解耦

    package com.why.dao;

    import com.why.dao.impl.UserDaoImpl;

    /**
    * @Description TODO
    * @Author why
    * @Date 2020/10/14 10:17
    * Version 1.0
    **/
    public class FactoryDao {
       private UserDaoImpl userDao;
       public UserDaoImpl getUserDao(){
           return userDao;
      }
    }

Druid连接池配置

  1. 引入依赖jar包

  2. xml进行配置

  3. 创建properties文件配置数据库信息

    # JDBC
    # MySQL 8.x: com.mysql.cj.jdbc.Driver
    jdbc.driverClass=com.mysql..cj.jdbc.Driver
    jdbc.connectionURL=jdbc:mysql://127.0.0.1:3306/mvcproject?useUnicode=true&characterEncoding=utf-8&useSSL=false
    jdbc.username=root
    jdbc.password=root

    # JDBC Pool
    #连接池建立时创建的初始化连接数
    jdbc.pool.init=1
    #连接池中最小空闲连接数
    jdbc.pool.minIdle=3
    #连接池中最大的活跃连接数
    jdbc.pool.maxActive=20

    # JDBC Test
    jdbc.testSql=SELECT 'x' FROM DUALurl=jdbc:mysql://localhost:3306/mvcproject?serverTimezone=Asia/Shanghai
    driverClassName=com.mysql.cj.jdbc.Driver
    username=root
    password=root
  4. 在Spring配置文件中使用标签引入外部属性文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:context="http://www.springframework.org/schema/context"
          xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

       <!-- 加载配置属性文件 -->
       <context:property-placeholder ignore-unresolvable="true" location="classpath:jdbc.properties"/>

       <!-- 数据源配置, 使用 Druid 数据库连接池 -->
       <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
           <!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
           <property name="driverClassName" value="${jdbc.driverClass}"/>

           <!-- 基本属性 url、user、password -->
           <property name="url" value="${jdbc.connectionURL}"/>
           <property name="username" value="${jdbc.username}"/>
           <property name="password" value="${jdbc.password}"/>

           <!-- 配置初始化大小、最小、最大 -->
           <property name="initialSize" value="${jdbc.pool.init}"/>
           <property name="minIdle" value="${jdbc.pool.minIdle}"/>
           <property name="maxActive" value="${jdbc.pool.maxActive}"/>

           <!-- 配置获取连接等待超时的时间 -->
           <property name="maxWait" value="60000"/>

           <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
           <property name="timeBetweenEvictionRunsMillis" value="60000"/>

           <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
           <property name="minEvictableIdleTimeMillis" value="300000"/>

           <property name="validationQuery" value="${jdbc.testSql}"/>
           <property name="testWhileIdle" value="true"/>
           <property name="testOnBorrow" value="false"/>
           <property name="testOnReturn" value="false"/>

           <!-- 配置监控统计拦截的filters -->
           <property name="filters" value="stat"/>
       </bean>
    </beans>
  5.  

posted @ 2020-12-14 20:12  笔落惊风  阅读(219)  评论(0编辑  收藏  举报