Java Web 03 — JDBC_02(数据库连接池_C3P0_Druid、JdbcTemplate)
文章目录
- 六:数据库连接池
- 6.1 概念
- 6.2 c3p0
- 6.3 Druid
- 6.4 DBCP(Apache)
- 6.5 DBUtils(快速创建对象,并以集合形式返回)
- 七、Spring JDBC _ JdbcTemplate
20190801更新:6.4 DBCP;6.5DBUtils
六:数据库连接池
6.1 概念
其实就是一个容器(集合),存放数据库连接的容器。
- 当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还为容器。
好处:
- 节约资源
- 用户访问高效
- 实现:
- 标准接口:
DataSource
javax.sql包下- 方法:
- 获取连接:
getConnection()
- 归还连接:如果连接对象
Connection
是从连接池获取的,那么调用Connection.close()
,则不会再关闭连接了,而是归还连接。
- 获取连接:
- 方法:
- 一般我们不去实现它,由数据库厂商来实现。
- c3p0:数据库连接池技术
- Druid:德鲁伊数据路连接池技术,由阿里巴巴提供
- 标准接口:
6.2 c3p0
步骤:
导入jar包(两个),
c3p0-0.9.5.2.jar
和mchange-commons-java-0.2.12.jar
(mysql的驱动jar包也要导入,不要忘记,mysql-connector-java-5.1.37-bin.jar
),所以一共是3个定义配置文件:
- 名称:
c3p0.properties
orc3p0-config.xml
<c3p0-config><!-- 使用默认的配置读取连接池对象 --><default-config><!-- 连接参数 --><property name="driverClass">com.mysql.jdbc.Driver</property><property name="jdbcUrl">jdbc:mysql://localhost:3306/db4</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/day25</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>
- 路径:直接将文件放在
src
目录下
- 名称:
创建核心对象:数据库连接对象
ComboPooledDataSource
获取连接:
getConnection()
package day03_JDBC;import com.mchange.v2.c3p0.ComboPooledDataSource;import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException;/*** C3P0演示*/ public class C3P0Demo01 {public static void main(String[] args) throws SQLException {//1. 创建数据库连接池对象DataSource ds = new ComboPooledDataSource();//2. 获取连接对象Connection conn = ds.getConnection();//3. 打印连接对象System.out.println(conn);} }
6.3 Druid
数据库连接池实现技术,由阿里巴巴提供
步骤
导入jar包:
druid-1.0.9.jar
定义配置文件:
- 是
properties
形式
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/db3 username=root password=root # 初始化连接数量 initialSize=5 # 最大连接数 maxActive=10 # 最长等待时间 maxWait=3000
- 可以叫任意名称,可以放在任意的目录下
- 是
加载配置文件。
Properties
获取数据库连接池对象:通过工厂类来获取
DruidDataSourceFctory
获取连接:
getConnection()
package day03_JDBC;import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.IOException; 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 rs = DruidDemo01.class.getClassLoader().getResourceAsStream("druid.properties");pro.load(rs);//4. 获取连接池对象DataSource ds = DruidDataSourceFactory.createDataSource(pro);//5. 获取连接Connection conn = ds.getConnection();System.out.println(conn);} }
定义工具类
- 定义一个类 JDBCUtils
- 提供静态代码块加载配置文件,初始化连接池对象
- 提供方法
- 获取连接方法:通过数据库连接池获取连接
- 释放资源
- 获取连接池的方法
package day03_JDBC.JDBCUtils;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_Druid {//1. 定义成员变量private static DataSource ds;static{try {//1. 加载配置文件Properties pro = new Properties();pro.load(JDBCUtils_Druid.class.getClassLoader().getResourceAsStream("druid.properties"));//2. 获取Datasourceds = DruidDataSourceFactory.createDataSource(pro);} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}/*** 获取连接的方法*/public static Connection getConnection() throws SQLException {return ds.getConnection();}/*** 释放资源*/public static void close(Statement stmt, Connection conn){close(null, stmt, conn);}public static void close(ResultSet rs, Statement stmt, Connection conn){if(rs != null){try {rs.close();} catch (SQLException e) {e.printStackTrace();}}if(stmt != null){try {stmt.close();} catch (SQLException e) {e.printStackTrace();}}if(conn != null){try {conn.close();//归还连接} catch (SQLException e) {e.printStackTrace();}}}/*** 获取连接池的方法*/public static DataSource getDataSource(){return ds;}
}
- 练习代码:一个添加操作
package day03_JDBC;import day03_JDBC.JDBCUtils.JDBCUtils_Druid;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;/*** 使用新的工具类*/
public class DruidDemo02 {public static void main(String[] args) {/*完成一个添加操作:给accout添加一条记录*/Connection conn = null;PreparedStatement pstmt = null;try {//1. 获取连接conn = JDBCUtils_Druid.getConnection();//2. 定义sqlString sql = "insert into account values(null,?,?)";//3. 获取pstmt对象pstmt = conn.prepareStatement(sql);//4. 给?赋值pstmt.setString(1,"王五");pstmt.setDouble(2, 3000);//5. 执行sqlint count = pstmt.executeUpdate();//执行成功的返回System.out.println(count);} catch (SQLException e) {e.printStackTrace();} finally {//6. 释放资源JDBCUtils_Druid.close(pstmt, conn);}}
}
6.4 DBCP(Apache)
需要导入两个
jar
包,分别为:commons-dbcp-1.4.jar
和commons-pool-1.5.6.jar
DBCP的连接池
DataSource
的实现类为BasicDataSource
,可以使用此实现类或使用工厂方法BasicDataSourceFactory.createDataSource(pro)
实现,但需要引入配置文件,具体实现方式如下:package day0801;import java.io.FileInputStream; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Properties;import javax.sql.DataSource;import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.dbcp.BasicDataSourceFactory;public class DBCPDemo01 {public static void main(String[] args) throws Exception{Properties pro = new Properties();pro.load(new FileInputStream(DBCPDemo01.class.getResource("dbcp.properties").getFile()));DataSource ds = BasicDataSourceFactory.createDataSource(pro);Connection conn = ds.getConnection();String sql = "select * from account";PreparedStatement pstmt = conn.prepareStatement(sql);ResultSet rs = pstmt.executeQuery();while(rs.next()) {int id = rs.getInt(1);String name = rs.getString(2);int balance = rs.getInt(3);System.out.println(id + "---" + name + "---" + balance);}} }
6.5 DBUtils(快速创建对象,并以集合形式返回)
核心类:
QueryRunner
- 使用:
QueryRunner qr = new QueryRunner(连接池对象ds);
List<Person> list = qr.query(sql, new BeanListHandler<Person>(Person.class));
返回集合
- 使用:
核心参数:
ResultSetHandler
(接口),创建对象所必须- 注意事项:
- 实体类构造器必须是无参构造器,且不能省略
- 注意事项:
实际操作:
配置文件(
C3P0
为例)<?xml version="1.0" encoding="UTF-8"?> <c3p0-config><default-config><property name="driverClass">com.mysql.jdbc.Driver</property><property name="jdbcUrl">jdbc:mysql://localhost/db2</property><property name="user">root</property><property name="password">root</property><property name="initialPoolSize">5</property><property name="maxPoolSize">20</property></default-config><named-config name="oracle"> <property name="driverClass">com.mysql.jdbc.Driver</property><property name="jdbcUrl">jdbc:mysql:///web_07</property><property name="user">root</property><property name="password">123</property></named-config></c3p0-config>
主程序
package day0801;import java.sql.SQLException; import java.util.ArrayList; import java.util.List;import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanListHandler;import com.mchange.v2.c3p0.ComboPooledDataSource;public class DBuUtilsDemo {public static void main(String[] args) throws Exception {List<Person> persons = findAll();for(Person p : persons) {System.out.println(p);}}//1. 创建查询的方法,返回存Person的Listpublic static List<Person> findAll() throws Exception {ComboPooledDataSource ds = new ComboPooledDataSource();QueryRunner qr = new QueryRunner(ds);String sql = "select * from emp";List<Person> list = qr.query(sql, new BeanListHandler<Person>(Person.class));return list;} }
实体类
package day0801;import java.util.Date;public class Person {private int id;private String name;private String gender;private double salary;private Date join_date;private int dept_id;public Person() {//无参构造器十分重要,必须是无参构造器}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}public Date getJoin_date() {return join_date;}public void setJoin_date(Date join_date) {this.join_date = join_date;}public int getDept_id() {return dept_id;}public void setDept_id(int dept_id) {this.dept_id = dept_id;}@Overridepublic String toString() {return "Person [id=" + id + ", name=" + name + ", gender=" + gender + ", salary=" + salary + ", join_date="+ join_date + ", dept_id=" + dept_id + "]";} }
七、Spring JDBC _ JdbcTemplate
- Spring框架对JDBC的简单封装。提供了
JdbcTemplate
对象,简化JDBC的开发 - 步骤
- 导入jar包(5个),并且依赖数据库连接池的jar包和驱动包。
- 创建JDBCTemplate对象。依赖于数据源
DataSource
JdbcTemplate template = new JdbcTemplate(ds);
- 调用JDBCTemplate的方法来完成CRUD的操作。
update()
:执行DML语句。增删改语句queryForMap()
:查询结果,将结果集封装为map
集合,将列名作为key
,将值作为value
,将这条记录封装为一个Map
集合。- 注意:这个方法查询的结果集长度只能是1
queryForList()
:查询结果封装为list
集合。- 将每一条记录封装为一个
Map
集合,再将Map
集合装在到List
集合
- 将每一条记录封装为一个
query()
:查询结果,将结果封装为JavaBean
对象。query
的参数:RowMapper- 一般使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装
new BeanPropertyRowMapper<Emp>(Emp.class)
queryForObject
:查询结果,将结果封装为对象。- 一般用于聚合函数的查询。
package day03_JDBC;import day03_JDBC.JDBCUtils.JDBCUtils_Druid;
import org.springframework.jdbc.core.JdbcTemplate;public class JDBCTemplateDemo01 {public static void main(String[] args) {//1. 导入jar包//2. 创建JDBCJdbcTemplate template = new JdbcTemplate(JDBCUtils_Druid.getDataSource());//3. 调用方法String sql = "update account set balance = 500 where id = ?";int count = template.update(sql, 3);System.out.println(count);}
}
- 练习:
- 需求
- 修改1号数据的salary 为10000
- 添加一条记录
- 删除刚才添加的记录
- 查询id为1的记录,将其封装为
Map
集合 - 查询所有记录,将其封装为
List
- 查询所有记录,将其封装为
Emp
对象的List
- 查询总记录数
- 需求
package day03_JDBC;import day03_JDBC.JDBCUtils.JDBCUtils_Druid;
import org.junit.Test;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;public class JdbcTemplateDemo02 {//Junit单元测试,可以让方法独立执行/*修改1号数据的salary 为10000*/private JdbcTemplate template = new JdbcTemplate(JDBCUtils_Druid.getDataSource());@Testpublic void test01(){JdbcTemplate template = new JdbcTemplate(JDBCUtils_Druid.getDataSource());String sql = "update emp set salary = 10000 where id = ?";int count = template.update(sql, 1);System.out.println(count);}/*添加一条记录*/@Testpublic void test02(){String sql = "insert into emp(id,name,dept_id) values(?,?,?)";int count = template.update(sql, 6, "文泽路", 1);System.out.println(count);}/*删除刚才添加的记录*/@Testpublic void test03(){String sql = "delete from emp where id = ?";int count = template.update(sql, 6);System.out.println(count);}/*查询id为1的记录,将其封装为`Map`集合注意:这个方法查询的结果集长度只能是1*/@Testpublic void test04(){String sql = "select * from emp where id = ? ";Map<String, Object> map = template.queryForMap(sql, 1);System.out.println(map);}/*查询所有记录,将其封装为`List*/@Testpublic void test05(){String sql = "select * from emp";List<Map<String, Object>> list = template.queryForList(sql);for(Map<String, Object> map : list){System.out.println(map);}}/*查询所有记录,将其封装为`Emp`对象的`List`*/@Testpublic void test06(){String sql = "select * from emp";List<Emp> list = template.query(sql, new RowMapper<Emp>() {@Overridepublic Emp mapRow(ResultSet resultSet, int i) throws SQLException {int id = resultSet.getInt("id");String name = resultSet.getString("name");String gender = resultSet.getString("gender");double salary = resultSet.getDouble("salary");Date join_date = resultSet.getDate("join_date");int dept_id = resultSet.getInt("dept_id");Emp emp = new Emp(id, name, gender, salary, join_date, dept_id);return emp;}});for(Emp emp : list){System.out.println(emp);}}/*简化操作!!!*/@Testpublic void test06_1(){String sql = "select * from emp";List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));for(Emp emp : list){System.out.println(emp);}}/*查询总记录数*/@Testpublic void test07(){String sql = "select count(id) from emp";Long total = template.queryForObject(sql, Long.class);System.out.println(total);}
}
Java Web 03 — JDBC_02(数据库连接池_C3P0_Druid、JdbcTemplate)相关推荐
- JDBC学习笔记03【JDBC事务管理、数据库连接池、JDBCTemplate】
黑马程序员-JDBC文档(腾讯微云)JDBC笔记.pdf:https://share.weiyun.com/Kxy7LmRm JDBC学习笔记01[JDBC快速入门.JDBC各个类详解.JDBC之CR ...
- Java JDBC篇4——数据库连接池
Java JDBC篇4--数据库连接池 1.DBCP 1.1.依赖jar包 官网:https://mvnrepository.com/artifact/org.apache.commons/commo ...
- Java中Semaphore(信号量) 数据库连接池
计数信号量用来控制同时访问某个特定资源的操作数或同时执行某个指定操作的数量 A counting semaphore.Conceptually, a semaphore maintains a set ...
- java简单模拟实现数据库连接池
为什么要使用数据库连接池 这个问题在一开始学习线程池或者整合ssm框架的时候经常会问自己这个问题,只知道这样使用可以在一定程度上优化程序的性能,提升系统的资源利用率,至于为什么这样使用一直没有搞明白. ...
- ASP.NET 例程完全代码版(5)——通过web.config配置数据库连接池
下面讲述在VS2005中如何使用web.config配置文件,进行数据库的连接操作,并启用SQL Server数据库的连接池,相信对于已经熟悉VS2003的.刚进入05的环境的朋友会有些帮助. ...
- Java中几个主流的数据库连接池
池(Pool)技术在一定程度上可以明显优化服务器应用程序的性能,提高程序执行效率和降低系统资源开销.这里所说的池是一种广义上的池,比如数据库连接池.线程池.内存池.对象池等.其中,对象池可以看成保存对 ...
- javaweb学习总结(三十九)——数据库连接池
javaweb学习总结(三十九)--数据库连接池 一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10 ...
- javaweb学习总结(三十九):数据库连接池
一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大 ...
- 如何在Tomcat中设置JNDI数据库连接池-Spring教程示例
在Spring和Tomcat中设置JNDI数据库连接池非常容易. Tomcat服务器文档提供了有关如何在Tomcat 5.6或7中设置连接池的足够信息.在这里,我们将结合使用Tomcat 7和Spri ...
最新文章
- 使用U盘装系统步骤详解
- web记录文章浏览数_内网渗透 -- 获取内网浏览器历史记录等相关信息
- 2022年全球及中国豪华商业墙纸行业运营规模状况与投资产值预测报告
- OpenGL tunnel隧道的实例
- 可以自动撑起的html样式,好好玩:CSS3抖动样式CSS Shake让你的网页酷炫起来
- html:(40):块级元素和内联块级元素
- axure web组件_AXURE原型设计:移动端选择器的应用
- 车辆销售系统用例_使用OpenCV和Python构建自己的车辆检测模型
- 网络助手之NABCD
- indexOf 和 lastIndexOf 使用
- 微信打飞机java代码
- 企业微信商户号是什么?如何开通?
- 计算机等级考试的资料,计算机等级考试(资料).pdf
- 计算机和小学科课题,《小学信息技术课堂有效教学的探索》课题研究方案
- Labview实现信号频域分析
- python笛卡尔坐标系_THREE笛卡尔右手坐标系详解
- 3D打印成型技术:看得见摸得着的真实
- java 排名算法_排行榜的算法
- Java中如何打印出一个数组中所有元素呢?
- 桂林山水甲天下,阳朔山水甲桂林