by konley
mysql进阶第二篇,c3p0连接池、Druid连接池和Spring JDBCTemplate
一、连接池
1.1 概念
连接池就是一个容器(集合),存放数据库连接的容器。
当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。
1.2 优点
- 节约资源
- 访问高效
1.3 实现
官方提供了一个标准接口javax.sql.DataSource
DataSource
接口提供以下方法:
- 获取连接:
Connection getConnection()
- 归还连接:
Connection.close()
- 注意:如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会关闭连接,而是归还连接
一般不需要自己去实现,由数据库厂商实现
常用的数据库连接池技术
-
C3P0:数据库连接池技术,Hibernate默认提供
-
Druid:数据库连接池技术,由阿里巴巴提供的(更高效)
二、C3P0
2.1 使用步骤
- 导入Jar包(两个):
c3p0-0.9.5.2.jar
,mchange-commons-java-0.2.12.jar
- 数据库驱动包也需要导入
- 定义配置文件,xml格式或者properties格式
- 名称:
c3p0.properties
或者c3p0-config.xml
- 路径:将文件放在src目录下
- 名称:
- 创建数据库连接池对象:
DataSource ComboPooledDataSource(filename)
- 获取连接:
DataSource.getConnection()
2.2 代码示范
<!--
文件名必须为c3p0-config.xml
文件目录必须为:src下
-->
<c3p0-config>
<!-- 使用默认的配置读取连接池对象 -->
<default-config>
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc_test</property>
<property name="user">root</property>
<property name="password">123456</property>
<!-- 连接池参数 -->
<!--初始化连接数-->
<property name="initialPoolSize">5</property>
<!--最大连接数-->
<property name="maxPoolSize">10</property>
<!--等待时间(超时时间)-->
<property name="checkoutTimeout">3000</property>
</default-config>
</c3p0-config>
/**
* @author konley
* @date 2020-07-07 21:36
* c3p0简单入门
*/
public class C3P0Demo1 {
public static void main(String[] args) throws SQLException {
//1.创建数据库连接池对象,c3p0-config.xml或properties必须放在src目录下,自动加载
DataSource ds = new ComboPooledDataSource();
//2.获取连接对象
Connection connection = ds.getConnection();
System.out.println(connection);
}
}
三、Druid
3.1 使用步骤
- 导入Jar包:
druid-1.0.9.jar
- 数据库驱动包也需要导入
- 定义配置文件,只能为properties格式
- 名称:任意
- 路径:任意
- 加载配置文件,需要先读取properties,用inputsteam、fileReader都可以
- 获取连接池对象:
DataSource ds = DruidDataSourceFactory.createDataSource(properties);
- 获取连接:
DataSource.getConnection()
3.2 代码示范
/**
* @author konley
* @date 2020-07-07 21:48
* Druid简单入门
*/
public class DruidDemo1 {
public static void main(String[] args) throws Exception {
//加载配置文件 druid.properties位置随意
Properties pro = new Properties();
/*
* 可以用inputstream、fileread和class.getClassLoader().getResourceAsStream
* */
//InputStream in = new FileInputStream("src/JDBCDataSource/druid.properties");
//FileReader in = new FileReader("src/JDBCDataSource/druid.properties");
InputStream in = DruidDemo1.class.getClassLoader().getResourceAsStream("JDBCDataSource/druid.properties");
pro.load(in);
//获取连接池
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
//获取连接对象
Connection conn = ds.getConnection();
System.out.println(conn);
}
}
3.3 改进JDBCUtils工具类
/**
* @author konley
* @date 2020-07-07 22:24
* 使用连接池的JDBC工具类
*/
public class JDBCUtils {
private static DataSource ds;
//获取DataSource
static {
try {
//获取properties
Properties pro = new Properties();
pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("JDBCDataSource/druid.properties"));
//加载properties并创建连接池
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//获取connection连接
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
//额外的获取连接池的方法
public static DataSource getDataSource(){
return ds;
}
//释放DQL操作的资源
public static void close(Statement stmt, Connection con, ResultSet rs){
try {
if(con!=null){
con.close();
}
if(stmt!=null){
stmt.close();
}
if(rs!=null){
rs.close();
}
}catch (SQLException e){
System.out.println("关闭Connection失败:"+e.getMessage());
}
}
//释放DML操作的资源
public static void close(Statement stmt,Connection con){
close(stmt,con,null);
}
}
四、JDBCTemplate
4.1 概念
JDBCTemplate是Spring框架对JDBC的简单封装。
提供了一个JDBCTemplate对象简化JDBC的开发。
4.2 使用步骤
- 导入Jar包:Spirng的相关包
- 数据库驱动包也需要导入
- 创建JdbcTemplate对象,依赖数据源DataSource
JdbcTemplate template = new JdbcTemplate(DataSource)
- 使用JdbcTemplate直接完成CRUD操作
4.3 DML(增删改)操作
update()方法
此方法可以执行DML语句,完成增删改操作。
代码示范
/**
* @author konley
* @date 2020-07-08 7:53
* JdbcTemplate完成CUD
*/
public class SpringJDBCTemplateDML {
//修改操作:修改dept表中的id=10的记录
@Test
public void update(){
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
String sql = "update dept set loc=? where id=?";
int count = template.update(sql, "天津", 10);
System.out.println(count);
}
//添加操作:添加一条记录到user表
@Test
public void insert(){
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
String sql = "insert into user value(null,?,?)";
int count = template.update(sql, "jojo", "112233");
System.out.println(count);
}
//删除操作:删除user表中id=3的记录
@Test
public void delete(){
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
String sql = "delete from user where id=?";
int count = template.update(sql, 3);
System.out.println(count);
}
}
4.4 DQL (查询)操作
1. queryFroMap(sql,[占位符?参数])方法
用途:查询结果,将结果集封装为map集合,将列名作为key,将值作为value
注意:这个方法只能查一条记录
//查询id为1,封装为map集合,查找的长度只能为1
@Test
public void queryForMap(){
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
String sql = "select * from emp where id = ?";
Map<String, Object> map = template.queryForMap(sql,1001);
/*
key=字段名,value=数据库对应的值
*/
System.out.println(map);
}
2. queryForList((sql,[占位符?参数])方法
用途:查询结果,将结果集封装为list集合
注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
//查询所有记录,封装为list集合,里面存放map
@Test
public void queryFroList(){
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
String sql = "select * from emp";
List<Map<String, Object>> maps = template.queryForList(sql);
/*
返回map集合
*/
for (Map<String, Object> map : maps) {
System.out.println(map);
}
}
3. query(sql,RowMapper,[占位符?参数])方法
用途:查询结果,将结果封装为JavaBean对象
RowMapper参数:
- 一般使用
BeanPropertyRowMapper
实现类,实现自动封装 - 用法:
new BeanPropertyRowMapper<类型>(类型.class)
- 例子:
new BeanPropertyRowMapper<emp>(emp.class)
- 注意:使用自动封装必须满足javabean中的属性名与数据库的列名一致
//查询记录,封装为javaBean对象
@Test
public void qeury(){
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
String sql = "select * from emp where id > ?";
//使用BeanPropertyRowMapper<指定Bean>(指定Bean.clss) 要求Bean的字段名和数据库字段名一样
List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class),1005);
for (Emp emp : list) {
System.out.println(emp);
}
}
4. queryForObject(sql,返回值类型.class,[占位符?参数])方法
用途:一般用于聚合函数的查询
//查询总记录,返回值是Integer对象
@Test
public void queryForObject(){
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
String sql = "select count(id) from emp";
//queryForObject(sql, 接收的数据类型.class)
Integer total = template.queryForObject(sql, Integer.class);
System.out.println(total);
}