Java JDBC数据库连接池

第三章 数据库连接池

1.1 概述

我们需要一个容器,来提前保存连接对象,而这个东西就叫做数据库线程池

数据库连接池: 其实就是一个容器(集合),存放数据库连接的容器

当系统初始化好之后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库的时候,从容器中获取连接对象;用户访问完之后,就将连接对象归还;

优点
  • 节约资源
  • 用户访问高效(如果自己getConnection的话就要对底层获取资源,比较没有效率)
注意:

数据库连接池的实现,使用标准接口:DataSource (在javax.sql包下)
  1.方法:
    ①获取连接:getConnection()
    ②归还连接:Connection.close()

​ 2.一般我们不去实现它,有数据库厂商来实现:Druid

基本实现

使用标准接口javax.sql.DataSource(接口的实现类由数据库的厂商提供),对于DriverManager设备的替代方案,这个接口是获取连接的首选方法

方法:

//获取连接
Connection getConnection() //尝试建立与此 DataSource对象所代表的数据源的连接。  
    
Connection getConnection(String username, String password) //尝试建立与此 DataSource对象所代表的数据源的连接。   
    
//归还连接:如果连接对象是从连接池中获取,那么调用Connection.close()方法,就不会再关闭连接,而是归还连接
connecion.close();
几种常用的数据库连接池技术

C3P0: 比较老
Druid(德鲁伊): 比较新的数据库连接池实现技术,由阿里巴巴提供的,非常高效,号称全世界最好的数据库连接池技术之一

1.2 C3P0技术

使用步骤:

  • 导入jar包: c3p0-0.9.5.5-sources.jar 和 mchange-commons-java-0.2.19-sources.jar (注意,数据库的jar包也记得要导mysql-connector-java-8.0.13-bin.jar)

  • 定义配置文件
    名称:c3p0.peoperties 或者 c3p0-config.xml
    路径: src源目录文件下

    自动配置,无需手动

  • 创建核心对象: 数据库连接池对象: new ComboPooledDataSource()

  • 获取连接: getConnection()

配置文件
<c3p0-config>
  <!-- 使用默认的配置读取连接池对象 -->
  <default-config>
   <!--  连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/javademo</property>
    <property name="user">root</property>
    <property name="password">bpqbfq769</property>
    
    <!-- 连接池参数 -->
    <property name="initialPoolSize">5</property>
    <property name="maxPoolSize">10</property>
    <property name="checkoutTimeout">3000</property>
  </default-config>

  <named-config name="otherc3p0"> 
    <!--  连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/javademo</property>
    <property name="user">root</property>
    <property name="password">123456</property>
    
    <!-- 连接池参数 -->
    <property name="initialPoolSize">5</property>
    <property name="maxPoolSize">8</property>
    <property name="checkoutTimeout">1000</property>
  </named-config>
</c3p0-config>

例子:
public static void main(String[] args) throws SQLException {
        //1.创建数据库连接池对象 使用默认配置
        ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
        //不使用默认配置
//        ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("otherc3p0");
        //2.获取连接对象,可以在配置文件中设定连接池中最大数量
        for (int i = 0; i <=10 ; i++) {
            Connection connection = comboPooledDataSource.getConnection();
            System.out.println(i+":"+connection);
            
        }
    }
1.3 Druid技术

使用步骤

  • 导入jar包( mysql-connector-java-8.0.13-bin.jar和druid-1.0.9.jar)
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </dependency>

        <!--druid连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.9</version>
        </dependency>

  • 定义配置文件:(.peoperties形式的)
    可为任意名称,可以放在任意目录下,需手动读取这个配置文件
  • 加载配置文件:properties
  • 获取数据库连接池对象: 通过工厂类 DruidDataSourceFactory
  • 获取连接: getConnection()
配置文件
url = jdbc:mysql:///door?serverTimezone=GMT%2B8
username = root
password = bpqbfq769
initialSize = 5	//初始化连接数
maxActive = 10	//最大连接数
maxWait = 3000	//最大等待时间
  
//再添加一些
  
filters=stat
// 初始化连接数量
initialSize=6
// 最大连接数
maxActive=10
// 最大等待时间
maxWait=3000
// 每30秒运行一次空闲连接回收器
timeBetweenEvictionRunsMillis=30000
// 池中的连接空闲30分钟后被回收,默认值就是30分钟。
minEvictableIdleTimeMillis=1800000
// 验证连接是否可用,使用的SQL语句
validationQuery=SELECT 1
// 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除.
testWhileIdle=true
// 借出连接时不要测试,否则很影响性能
testOnBorrow=false
testOnReturn=false
poolPreparedStatements=false
maxPoolPreparedStatementPerConnectionSize=200

例子:
public static void main(String[] args) throws Exception {
        //1.导入jar包
        //2.定义配置文件
        //3.加载配置文件
        Properties pro = new Properties();
        InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
        pro.load(is);
        //4.获取连接池对象
        DataSource ds = DruidDataSourceFactory.createDataSource(pro);
        //5.获取连接
        Connection conn = ds.getConnection();
        System.out.println(conn);
    }

小试牛刀

import com.alibaba.druid.pool.DruidDataSourceFactory;
import demo12.util.JDBCUtils;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

public class DataSource {
    public static void main(String[] args) throws Exception {
      	//1.手动配置加载文件
    		ClassLoader cll = DataSource.class.getClassLoader();
    		InputStream rs = cll.getResourceAsStream("druid.properties");
    		pro.load(rs);

        //2.创建连接对象,这里参数要一个Properties
    		javax.sql.DataSource dataSource = 		DruidDataSourceFactory.createDataSource(pro);
				//3.获取数据库连接对象
    		Connection conn = dataSource.getConnection();
				//4.获取执行sql的对象Statement
    		Statement stmt = conn.createStatement();
				//5.定义sql语句
    		String sql = "select * from buyer";

    		// 6.执行sql
    		ResultSet res = stmt.executeQuery(sql);

    		//7. 处理结果
    		while (res.next()){
        		System.out.println(res.getInt(1) + " \t" + res.getString(2) + "\t" +  res.getDouble(3));
    		}

    		//8. 释放资源
   		 JDBCUtils.close(stmt,conn);
      	//或 8.释放资源
    		//statement.close();
    		//con.close();
		}
}
//处理结果
422, 2021 11:39:13 上午 com.alibaba.druid.pool.DruidDataSource info
信息: {dataSource-1} inited
1 	zhangsan	2000.0
2 	lisi	6000.0
1.4 Druid工具类

我们发现这个过程还是有点麻烦,所以我们打算通过自己写一个改良版的工具类来简化这个过程.

步骤

  • 定义一个工具类JDBCUtils

  • 提供静态代码块加载配置文件,同时初始化连接池对象

  • 提供方法:

    ​ 获取连接对象,

    ​ 释放资源

    ​ 获取连接池对象的方法

工具类

import com.alibaba.druid.pool.DruidDataSourceFactory;

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

/**

 * JDBC工具类
   */

public class JDBCDruidUtils {
    //1.定义成员变量 DataSource
		private static final Properties pro;
		private static DataSource dataSource;
		//配置文件的读取,只需要一次就可以了,用静态代码块
		static {
       //手动加载配置文件
    		pro = new Properties();
    		ClassLoader cl = JDBCDruidUtils.class.getClassLoader();
    		InputStream is = cl.getResourceAsStream("druid.properties");
    		try {
        		pro.load(is);
    		} catch (IOException e) {
        		e.printStackTrace();
    		}
    		//初始化连接池对象
    		try {
        		dataSource = DruidDataSourceFactory.createDataSource(pro);
    		} catch (Exception e) {
        		e.printStackTrace();
    		}
		}
		//获取连接对象
		public static Connection getConnection() throws Exception {
				return dataSource.getConnection();
		}

		//关闭资源
		public static void close(Statement stmt, Connection conn) {
    		judge(stmt, conn);
    }

		public static void judge(Statement stmt, Connection conn) {
    		if (stmt != null) {
        		try {
            		stmt.close();
        		} catch (SQLException throwables) {
            		throwables.printStackTrace();
        		}
    		}
    		if (conn != null) {
        		try {
           			conn.close();
        		} catch (SQLException throwables) {
            		throwables.printStackTrace();
        		}
    		}
		}
		//获取连接池的方法
		public static DataSource getDataSource(){
    		return dataSource;
		}
}

代码测试1

import demo12.util.JDBCDruidUtils;
import demo12.util.JDBCUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;


public class DataSource {
    public static void main(String[] args) throws Exception {    
				Connection conn = JDBCDruidUtils.getConnection();

    		Statement stmt = conn.createStatement();

    		String sql = "select * from account";

    		// 执行sql
    		ResultSet res = stmt.executeQuery(sql);

    		//7 处理结果
    		while (res.next()){
        		System.out.println(res.getInt(1) + " \t" + res.getString(2) + "\t" +  	res.getDouble(3));
    		}

    		//8 释放资源
    		JDBCUtils.close(stmt,conn);

		}
}
//运行结果
422, 2021 12:38:17 下午 com.alibaba.druid.pool.DruidDataSource info
信息: {dataSource-1} inited
1 	zhangsan	2000.0
2 	lisi	6000.0

代码测试2

public static void main(String[] args) {

        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            //1.获取连接
            conn = JDBCutils.getConnection();
            //2.定义sql
            String sql = "insert into student3 values(null,?,?,?,?,?,?)";
            //3.获取执行sql语句的对象
            pstmt = conn.prepareStatement(sql);
            //4.给?赋值
            pstmt.setString(1,"小白龙");
            pstmt.setInt(2,19);
            pstmt.setString(3,"男");
            pstmt.setString(4,"大唐");
            pstmt.setInt(5,66);
            pstmt.setInt(6,99);
            //5.执行sql
            int count = pstmt.executeUpdate();
            System.out.println(count);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //6.释放资源
            JDBCutils.close(pstmt,conn);
        }
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值