池化技术是提供系统资源利用率必不可少的,接下来接受数据库连接池。

数据库连接池技术

1. 引入

  • 在对数据库进行操作的时候,每次执行不同操作,都要去申请连接对象,这样频繁地向系统申请资源会花费大量时间。因此人们引入了池子的概念:一开始就申请多个连接对象,并把这些连接对象放在池子中(容器),每次用的时候就从池子中拿,用完就放回池子中。

2. 概念

  • 本质上就是一个存放了多个连接对象的容器(集合)。

3. 好处

  1. 节约系统资源
  2. 用户获取连接对象更加高效

4. 标准

  • Java对连接池定义了规范(即是接口),那就是javax.sql.DataSource接口

  • DataSource:A factory for connections to the physical data source that this DataSource object represents. An alternative to the DriverManager facility, a DataSource object is the preferred means of getting a connection. An object that implements the DataSource interface will typically be registered with a naming service based on the Java™ Naming and Directory (JNDI) API.

  • 连接池:一个DataSource对象代表了一个物理的连接数据库的连接的生产工厂。除了DriverManager功能外,DataSource是首选。

    • Connection getConnection():Attempts to establish a connection with the data source that this DataSource object represents.
    • Connection.close():从连接池中获取到的Connection对象在调用close方法的时候会把该对象归还到连接池中。

5. 实现

  • 一般我们不会实现,有数据库厂商实现。
  • 有很多开源的连接池技术:C3P0、Druid(阿里巴巴提供)

6. 第三方连接池的使用:C3P0

  • 开发步骤

    1. 导入c3p0提供的实现jar包、依赖jar包、数据库驱动包
      • c3p0-0.9.5.2.jar:实现jar包
      • mchange-commons-java-0.2.12.jar:依赖jar包
      • mysql-connector-java-5.1.37-bin.jar:数据库驱动包
    2. 定义配置文件
      • c3p0-config.xml
    3. 创建核心对象:
    4. 获取连接
  1. 在项目中新建libs文件夹用于存放jar包。

  2. 将配置文件放在classpath下,即是项目的src目录下。

  3. 修改配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <c3p0-config>
    <!-- 使用默认的配置读取连接池对象 -->
    <default-config>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <!--连接数据库的url-->
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/db8100</property>
    <!--用户名-->
    <property name="user">root</property>
    <!--密码-->
    <property name="password">root</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/db8100</property>
    <property name="user">root</property>
    <property name="password">root</property>
    <property name="initialPoolSize">5</property>
    <property name="maxPoolSize">8</property>
    <property name="checkoutTimeout">1000</property>
    </named-config>
    </c3p0-config>
  4. 创建核心对象

  5. 获取连接

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    package top.tobing.c3p0;

    import com.mchange.v2.c3p0.ComboPooledDataSource;

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

    public class JdbcPoolDemo01 {
    public static void main(String[] args) throws SQLException {
    // 创建核心对象ComboPooledDataSource
    // 使用默认配置
    //DataSource ds = new ComboPooledDataSource();
    // 指定配置
    DataSource ds = new ComboPooledDataSource("otherc3p0");

    // 获取连接对象
    Connection conn = ds.getConnection();

    System.out.println(conn);
    }
    }

7. Druid的使用

  • 开发步骤

    1. 导入jar包
      • druid-1.0.9.jar
      • mysql-connector-java-5.1.37-bin.jar:数据库驱动包
    2. 定义配置文件
      • druid.properties
    3. 加载配置文件
    4. 获取连接池对象:通过工厂类DruidDataSourceFactory获取
    5. 获取连接
  1. 创建项目,创建libs目录,导入jar包

  2. 编写配置文件

    1
    2
    3
    4
    5
    6
    7
    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql://127.0.0.1:3306/db3
    username=root
    password=root
    initialSize=5
    maxActive=10
    maxWait=3000
  3. 获取连接池对象

  4. 获取连接

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    package top.tobing.druid;

    import com.alibaba.druid.pool.DruidDataSourceFactory;

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

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

8.Druid工具类的抽取

  • 考虑到即使使用类连接池技术,但在回去连接的时候步骤仍然比较繁琐,因此将其封装为工具类

    1. 定义JDBCUtils类
    2. 提供静态代码块用于加载配置文件,初始化连接池对象
    3. 提供方法
      1. 获取连接
      2. 释放资源
      3. 获取连接池
  • 工具类代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    package top.tobing.utils;

    import com.alibaba.druid.pool.DruidDataSourceFactory;

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

    public class JDBCUtils {
    private static DataSource ds = null;

    static{
    try {
    // 加载配置文件
    Properties pro = new Properties();
    pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
    ds = DruidDataSourceFactory.createDataSource(pro);
    } catch (IOException e) {
    e.printStackTrace();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    /**
    * 获取连接对象
    * @return
    * @throws SQLException
    */
    public static Connection getConnection() throws SQLException {
    return ds.getConnection();
    }

    /**
    * 释放资源
    * @param conn
    * @param stat
    * @param rs
    */
    public static void close(Connection conn, Statement stat, ResultSet rs){
    if(conn!=null){
    try {
    conn.close(); // 归还连接
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    if(stat!=null){
    try {
    stat.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    if(rs!=null){
    try {
    rs.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    }
    public static void close(Connection conn,Statement stat){
    close(conn,stat,null);
    }

    }

  • 测试工具类代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    package top.tobing.druid;

    import top.tobing.utils.JDBCUtils;

    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;

    public class DruidDemo02 {
    public static void main(String[] args) throws SQLException {
    //1.获取连接
    Connection conn = JDBCUtils.getConnection();
    //2.定义sql语句
    String sql = "insert into account values(null,?,?)";
    //3.获取pstat对象
    PreparedStatement pstat = conn.prepareStatement(sql);
    //4.配置参数
    pstat.setString(1,"rongon");
    pstat.setDouble(2,199900);
    //5.执行查询
    int row = pstat.executeUpdate();
    System.out.println(row);
    }
    }

评论