JDBC连接池Durid连接池、c3p0连接池

JDBC连接池概述

数据库连接池是一个用来存放数据库连接的容器。

当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。
在这里插入图片描述

Java给开发者提供了数据库连接池的标准接口DataSource在javax.sql包下。有很多公司对数据库连接池接口规范进行实现。这里我们介绍两种
1. C3P0:数据库连接池技术
2. Druid:数据库连接池实现技术,由阿里巴巴提供的。

准备数据库数据

先准备一些数据,在account表中添加2条记录,sql语句如下。方便后面代码演示

# 创建数据库
CREATE DATABASE db5;

# 创建account表
CREATE TABLE account(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(20),
	balance INT
);
# 添加2条记录
INSERT INTO  account(id,NAME,balance) VALUES(1,"张三",1000);
INSERT INTO  account(id,NAME,balance) VALUES(2,"李四",1000);

C3P0连接池使用步骤

导入j相关jar包
c3p0连接池需要下载jar包下载地址

导入c3p0两个jar包如图所示,当然不要忘了MySQL数据库驱动包

在这里插入图片描述

定义配置文件
配置文件用来定义数据库连接池要访问的数据库地址、用户名、和密码以及最大连接数、超时时间等等。

名称: c3p0.properties 或者 c3p0-config.xml 两种格式都可以
路径:直接将文件放在src目录下即可。

c3p0-config.xml 格式

<c3p0-config>
  <!-- 使用默认的配置读取连接池对象 -->
  <default-config>
  	<!--  连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/db5</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>
</c3p0-config>

c3p0-config.properties 格式

# 数据库驱动类
c3p0.driverClass=com.mysql.jdbc.Driver
# 数据库url地址
c3p0.jdbcUrl=jdbc:mysql://localhost:3306/db5
# 数据库用户名
c3p0.user=root
# 数据库密码
c3p0.password=root
# 初始化连接数量
c3p0.initialPoolSize=5
# 最大的连接数量
c3p0.maxPoolSize=10
# 连接超时时间
c3p0.checkoutTimeout=3000

创建数据库连接池对象,获取连接

使用默认的配置获取连接池对象

//创建数据库连接池对象
DataSource ds  = new ComboPooledDataSource();
//最大连接数为10个,可以获取10个Connection连接对象
for (int i = 0; i < 10; i++) {
  Connection conn = ds.getConnection();
  System.out.println(conn);
}
//获取第11个连接对象
Connection conn=ds.getConnection();

当获取到第11个连接对象时就会连接超时,如图所示
在这里插入图片描述

但是采用c3p0-config.xml格式配置,可以提供多个数据源服务,提供default-config和named-config两种配置方式。

<c3p0-config>
  <!-- 使用默认的配置读取连接池对象 -->
  <default-config>
  	<!-- 连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/db5</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>

  <!--指定名称的连接池配置 mySource -->
  <named-config name="mySource">
    <property name="user">root</property>
    <property name="password">java</property>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/db5</property>
    <property name="initialPoolSize">10</property>
    <property name="maxPoolSize">100</property>
    <property name="minPoolSize">10</property>
  </named-config>
</c3p0-config>

使用指定的名称配置获取连接池对象

//创建指定名的数据库连接池对象
DataSource ds  = new ComboPooledDataSource("mySource");
//获取连接对象
Connection conn = ds.getConnection();

Druid连接池使用步骤

Druid数据库连接池实现技术,由阿里巴巴提供的。使用步骤如下

导入jar包 druid-1.0.9.jar
在libs目录下,导入下面jar包
在这里插入图片描述
定义druid.properties配置文件

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost/db5
username=root
password=root
# 初始化连接数量
initialSize=5
# 最大连接数
maxActive=10
# 最大等待时间
maxWait=3000

加载配置文件Properties

//加载配置文件
Properties pro = new Properties();
pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));

创建数据库连接池对象,获取连接

//获取DataSource
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
Connection conn = ds.getConnection();

封装JDBCUtil工具类封装

为了方便调用,我们可以把获取连接的操作封装成一个工具类JDBCUtils,代码如下。

public class JDBCUtils {
    private static DataSource dataSource;
    //加载配置文件,获取数据库连接池
    static{
        try {
            //读取配置文件到Properties集合
            InputStream ins = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
            Properties pro=new Properties();
            pro.load(ins);

            //通过配置文件获取数据库连接池
            dataSource = DruidDataSourceFactory.createDataSource(pro);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //获取连接
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    //获取连接池
    public static DataSource getDataSource(){
        return dataSource;
    }
    //释放资源
    public static void close(Connection conn,Statement stmt,ResultSet rs){
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stmt!=null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    //释放资源
    public static void close(Connection conn,Statement st){
        close(conn,st,null);
    }

}

使用JBDCUtils工具类,往account表中插入一条记录,代码如下

public class DruidDemo1 {
    public static void main(String[] args) {
        try {
            //获取数据库连接
            Connection conn = JDBCUtils.getConnection();
            //定义sql语句
            String sql="INSERT INTO  account(id,NAME,balance) VALUES(null,?,?)";
            //获取PreparedStatement对象
            PreparedStatement pstam = conn.prepareStatement(sql);
            //给第一个?赋值
            pstam.setString(1,"王五");
            //给第二个?赋值
            pstam.setInt(2,2000);
            //执行sql语句
            int count = pstam.executeUpdate();
            System.out.println(count);
            //释放资源
            JDBCUtils.close(conn,pstam);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

执行完结果,查看account表中数据,多了一条记录。
在这里插入图片描述

Spring JDBC

Spring框架对JDBC的简单封装,提供了一个JDBCTemplate对象简化JDBC的开发。

需要导入Spring jdbc相关的jar包,如图所示
在这里插入图片描述

使用步骤

1. 导入Spring框架Jar包
2. 创建JdbcTemplate对象。依赖于数据源DataSource
   DataSource ds=JDBCUtils.getDataSource();
   JdbcTemplate template = new JdbcTemplate(ds);
3. 调用JdbcTemplate的方法来完成CRUD的操作
    update():执行DML语句。增、删、改语句
    query():查询结果,将结果封装为JavaBean对象
    queryForMap():查询结果,将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合
    queryForList():查询结果,将结果集封装为list集合
    queryForObject():查询结果,将结果封装为对象,一般用作聚合函数查询

JdbcTemplate代码演示

/*
1. 修改1号数据的 salary 为 10000
2. 添加一条记录
3. 删除刚才添加的记录
4. 查询id为1的记录,将其封装为Map集合
5. 查询所有记录,将其封装为List
6. 查询所有记录,将其封装为Emp对象的List集合
7. 查询总记录数
 */
public class JDBCTemplateDemo {
    public static void main(String[] args) {
        //获取数据源
        DataSource ds = JDBCUtils.getDataSource();
        //创建JdbcTemplate对象
        JdbcTemplate jdbcTemplate=new JdbcTemplate(ds);

        //1. 修改1号数据的 salary 为 1500
        String sql1="UPDATE account SET balance=? WHERE id=?";
        int count = jdbcTemplate.update(sql1,1500,1);
        System.out.println(count>0?"修改成功":"修改失败");

        //2. 添加一条记录
        String sql2="INSERT INTO  account(id,NAME,balance) VALUES(null ,?,?)";
        count = jdbcTemplate.update(sql2,"赵六",1000);
        System.out.println(count>0?"添加成功":"添加失败");

        //3. 删除刚才添加的记录
        String sql3 = "DELETE FROM account where name=?";
        count = jdbcTemplate.update(sql3,"赵六");
        System.out.println(count>0?"删除成功":"删除失败");


        //4. 查询id为1的记录,将其封装为Map集合
        //注意:只能获取指定的一条记录,并把字段当做Map的Key,字段对应的值,作为Map的value
        String sql4="select * from account where id=?";
        Map<String, Object> map = jdbcTemplate.queryForMap(sql4, 1);
        System.out.println("------4. 查询id=1的记录,结果封装为Map集合");
        System.out.println(map);

        System.out.println("------5. 查询所有记录,将每条记录封装为一个Map集合,并将Map集合存入List集合");
        //5. 查询所有记录,将其封装为List
        String sql5="select * from account";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql5);
        for (Map<String, Object> element : list) {
            System.out.println(element);
        }

        System.out.println("------6. 查询所有记录,将每条记录封装为一个JavaBean并存入List集合");
        //6.1 查询所有记录,将其封装为Emp对象的List集合
        String sql6="select * from account";
        List<Account> list2 = jdbcTemplate.query(sql6, new RowMapper<Account>() {
            @Override
            public Account mapRow(ResultSet resultSet, int i) throws SQLException {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                int balance = resultSet.getInt("balance");
                Account account = new Account(id, name, balance);
                return account;
            }
        });

        for (Account account : list2) {
            System.out.println(account);
        }

        System.out.println("-------------");

        //6.2 上面的代码可以简化为下面的写法
        list2 = jdbcTemplate.query(sql6, new BeanPropertyRowMapper<Account>(Account.class));
        for (Account account : list2) {
            System.out.println(account);
        }
				//7. 查询总记录数
        System.out.println("------7. 查询总记录数");
        String sql7="select count(id) from account";
        Long total = jdbcTemplate.queryForObject(sql7, Long.class);
        System.out.println("总记录数:"+total);
    }
}

执行上面代码,结果如下
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值