MySQL进阶(二):连接池和JDBCTemplate
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); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具