C3P0连接池和Druid(德鲁伊)连接池的使用

数据库连接池

使用传统的方式获取Connection对象

  • 使用传统的方式连接 5000 次数据库 ,看看连接-关闭 connection 对象会耗时多久 , 这种连接方式实实在在的和数据库连接了5000次 , 并且每次连接后还要关闭

C3P0连接池和Druid(德鲁伊)连接池的使用_第1张图片

代码实现

// 使用JDBCUtils的工具类
public void testCon() {
     
     long start = System.currentTimeMillis();
     System.out.println("开始连接.....");
     
     for (int i = 0; i < 5000; i++) {
         //使用传统的jdbc方式,得到连接对象
         Connection connection = JDBCUtils.getConnection();
         
         //做一些工作,比如得到 PreparedStatement ,发送 sql
         
         //这里必须连接完后必须要关闭 , 否则连接太多会造成服务器宕机
         JDBCUtils.close(null, null, connection);
     }
     
     long end = System.currentTimeMillis();
     
     //传统方式 5000 次 耗时=7099
     System.out.println("传统方式 5000 次 耗时=" + (end - start));
 }

使用数据库连接池技术获取Connection对象

  • 数据库连接池技术

    C3P0连接池和Druid(德鲁伊)连接池的使用_第2张图片i

  • 数据库连接池的种类

    • Druid连接池的优势在连接次数越多时越能体现 ,连接次数相对少的话使用C3P0连接池
    • 连接池创建的Connectio对象和数据库厂商创建的Connectio对象对javax.sql.DataSource接口的方法实现不一样
      • 连接池创建的Connectio对象的close方法是把连接对象放回连接池 (德鲁伊的Connection对象的运行类型com.alibaba.druid.pool.DruidPooledConnection)
      • 数据库厂商创建的Connectio对象的close方法是真正关闭程序和数据库之间的连接通道 (Connection对象的运行类型com.mysql.jdbc.JDBCConnection)

    C3P0连接池和Druid(德鲁伊)连接池的使用_第3张图片l

使用C3P0数据库连接池的两种方式

  • 导入c3p0-0.9.1.2.jar并添加到ClassPath下 ,这个**jar包中的ComboPooledDataSource类实现了javax.sql.DataSource接口 **

    • 方式一: 相关参数,在程序中指定 user, url , password等参数信息

      创建连接数据库的配置文件mysql.properties(文件名称和位置不固定 )

      user=root
      password=hsp
      #rewriteBatchedStatements=true表示支持批处理
      url=jdbc:mysql://localhost:3306/hsp_db02?rewriteBatchedStatements=true
      driver=com.mysql.jdbc.Driver
      

      代码实现

      @Test
      public void testC3P0_01() throws Exception {
          
          //1. 创建一个数据源对象
          ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
          
          //2. 通过配置文件 mysql.properties 获取相关连接的信息
          Properties properties = new Properties();
          properties.load(new FileInputStream("src\\mysql.properties"));
          
          //读取相关的属性值
          String user = properties.getProperty("user");
          String password = properties.getProperty("password");
          String url = properties.getProperty("url");
          String driver = properties.getProperty("driver");
          
          //给数据源 comboPooledDataSource 设置相关的参数
          //注意:连接管理是由 comboPooledDataSource来管理 , 所以连接池一定要知道连上数据库的相关信息
          comboPooledDataSource.setDriverClass(driver);
          comboPooledDataSource.setJdbcUrl(url);
          comboPooledDataSource.setUser(user);
          comboPooledDataSource.setPassword(password);
          
          //设置连接池创建的时候的初始化连接对象的个数
          comboPooledDataSource.setInitialPoolSize(10);
          
          //最大连接数  ,超过最大连接数 , 就需要进入等待队列
          comboPooledDataSource.setMaxPoolSize(50);
          
          //测试连接池的效率, 测试对 mysql 5000 次操作
          long start = System.currentTimeMillis();
          for (int i = 0; i < 5000; i++) {
              //getConnection方法就是 ComboPooledDataSource类 实现 DataSource接口用来获取连接对象的方法
              Connection connection = comboPooledDataSource.getConnection(); 
              
              //这个close方法只是把连接对象放回连接池 , 并不是真正的关闭和数据库连接的通道
              connection.close();
          }
          
          long end = System.currentTimeMillis();
          //使用c3p0的方式连接5000次mysql 耗时=391
          System.out.println("c3p0 5000 连接 mysql 耗时=" + (end - start));
      
      }    
      
    • 第二种方式使用配置文件模板来完成 , 创建c3p0-config.xml文件(文件的名称和位置是固定的)

      • 将 c3p0 提供的 c3p0.config.xml 拷贝到 src 类路径目录下 , 该文件指定了连接数据库的信息和初始化连接池的相关参数
      • 由于程序需要读取配置文件中的数据源的名称 , 然后根据数据源的参数信息创建连接池 , 所以就一定要知道文件的名称和位置
      <c3p0-config>
        
        <named-config name="hsp_edu">
            
            
            <property name="driverClass">com.mysql.jdbc.Driverproperty>
      
            
            <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/hsp_db02property>
      
            
            <property name="user">rootproperty>
      
            
            <property name="password">hspproperty>
      
            
            <property name="acquireIncrement">5property>
      
            
            <property name="initialPoolSize">10property>
      
            
            <property name="minPoolSize">5property>
      
            
            <property name="maxPoolSize">50property>
      
            
            <property name="maxStatements">5property> 
      
            
            <property name="maxStatementsPerConnection">2property>
            
        named-config>
      c3p0-config>
      

      使用C3P0的方式连接数据库

      @Test
      public void testC3P0_02() throws SQLException {
          
          //根据数据源的名称创建指定的连接池
          //程序需要读取配置文件中的数据源的名称 , 根据数据源的参数信息创建连接池 , 就一定要知道文件的名称和位置
          ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("hsp_edu");
          
          //测试 5000 次连接 mysql
          long start = System.currentTimeMillis();
          System.out.println("开始执行....");
          for (int i = 0; i < 500000; i++) {
              //因为连接池的参数的相关参数已经设值好了 , 所以可以直接从连接池中拿到连接对象
              Connection connection = comboPooledDataSource.getConnection();
              connection.close();
          }
          long end = System.currentTimeMillis();
        
          //使用c3p0连接数据库的第二种方式 耗时=413
          System.out.println("c3p0 5000 连接 mysql 耗时=" + (end - start));
      
      }    
      

使用Druid(德鲁伊)数据库连接池

  • 导入Druid的 jar 包 druid-1.1.10.jar并添加到classpath下 , 这个**jar包中的DataSource类实现了javax.sql.DataSource接口 **

  • **创建配置文件 druid.properties , 并将该文件放到项目的 src 类路径下 **

    • 这个配置文件的名称和位置是不固定的 , 但大家一般都这样做
    #key=value
    #驱动类
    driverClassName=com.mysql.jdbc.Driver
    #url
    url=jdbc:mysql://localhost:3306/hsp_db02?rewriteBatchedStatements=true
    #用户名
    username=root
    #密码
    password=hsp
    
    #initial connection Size (初始化连接数)
    initialSize=10
    
    #min idle connecton size(最小空闲连接对象个数)
    minIdle=5
    
    #max active connection size(最大连接对象个数)
    maxActive=50
    
    #max wait time (5000 mil seconds)(最大等待时间 , 如果规定时间内等不到就会放弃等下次再来)
    maxWait=5000
    

    使用德鲁伊的方式连接数据库

    public void testDruid() throws Exception {
        
        //创建 Properties 对象, 读取配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\druid.properties"));
        
        //根据配置文件的相关参数初始化一个数据库连接池, Druid 连接池
        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
        
        //测试 5000 次连接 mysql
        long start = System.currentTimeMillis();
        for (int i = 0; i < 500000; i++) {
            //从连接池中拿到连接对象
            Connection connection = dataSource.getConnection();
            connection.close();
        }
        long end = System.currentTimeMillis();
        
        //druid连接池操作5000次连接, 耗时=412
        System.out.println("druid 连接池 操作 500000 耗时=" + (end - start));
    }    
    

使用德鲁伊封装JBDCUtils工具类

  • 将 JDBCUtils 工具类改成 由Druid(德鲁伊)数据库连接池获取连接对象

    public class JDBCUtilsByDruid {
        
        	private static DataSource;
        
            //在静态代码块完成数据源(连接池)的初始化
            static {
           		Properties properties = new Properties();
            	try {
                	properties.load(new FileInputStream("src\\druid.properties"));
                    //创建连接池
                	ds = DruidDataSourceFactory.createDataSource(properties);
            	} catch (Exception e) {
                	e.printStackTrace();
            	  }
        }
    
        //编写 getConnection 方法
        public static Connection getConnection() throws SQLException {
            return ds.getConnection();
        }
        
        //关闭连接, 在数据库连接池技术中,close 不是真的断掉连接而是把使用的 Connection 对象放回连接池 
        //由连接池创建的连接对象的close方法是把连接对象放回连接池 , 由数据库厂商创建的Connectio对象的close方法是真正关闭程序和数据库的连接通道
        public static void close(ResultSet resultSet, Statement statement, Connection connection) 
            try {
                
                if (resultSet != null) {
                        resultSet.close();
                }
                
                if (statement != null) {
                    statement.close();
                }
                
                if (connection != null) {
                    connection.close();
                }
                
            } catch (SQLException e) {
                throw new RuntimeException(e);
              }
    	}
    }
    

    测试封装的工具类

    @Test
    public void testSelect() {
        //1. 得到连接
        Connection connection = null;
        
        //2. 组织一个 sql
        String sql = "select * from actor where id >= ?";
        PreparedStatement preparedStatement = null;
        ResultSet set = null;
        
        //3. 创建 PreparedStatement 对象
        try {
            
            connection = JDBCUtilsByDruid.getConnection();
            
            //德鲁伊实现DataSource后拿到的Connection对象的运行类型com.alibaba.druid.pool.DruidPooledConnection
            //不使用数据库连接池获得的Connection对象的运行类型com.mysql.jdbc.JDBCConnection
            System.out.println(connection.getClass());
            
            preparedStatement = connection.prepareStatement(sql);
            
            //给?号赋值
            preparedStatement.setInt(1, 1);
            
            //执行, 得到结果集
            set = preparedStatement.executeQuery();
            
            //遍历该结果集
            while (set.next()) {
                int id = set.getInt("id");
                String name = set.getString("name");//getName()
                String sex = set.getString("sex");//getSex()
                Date borndate = set.getDate("borndate");
                String phone = set.getString("phone");
                System.out.println(id + "\t" + name + "\t" + sex + "\t" + borndate + "\t" + phone);
            }
        } catch (SQLException e) {
            e.printStackTrace();
          } finally {
            //关闭资源
            JDBCUtilsByDruid.close(set, preparedStatement, connection);
        }
    }
    

你可能感兴趣的:(数据库,mysql,java)