JavaWeb--数据库连接池,SpringJDBC
JavaWeb-- 数据库连接池,SpringJDBC
JavaWeb-- 数据库连接池
概述
-
其实就是一个容器 (集合),存放数据库连接的容器。
-
当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。
-
好处
- 节约资源
- 用户访问高效
实现
- 标准接口:DataSoure,java sql 包下
Interface DataSource -- 一个连接到这个DataSource对象所代表的物理数据源的工厂
-- 基本实现 - 生成标准的Connection对象
连接池实现 - 生成将自动参与连接池的Connection对象。 此实现与中间层连接池管理器配合使用。
分布式事务实现 - 生成可用于分布式事务的Connection对象,并且几乎总是参与连接池。 此实现与中间层事务管理器一起工作,并且几乎总是使用连接池管理器。
-
方法:
-
getConnection() -- 获取连接
-
归还连接:Connection.close()。如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接
-
-
一般我们不去实现它,有数据库厂商来实现
-
C3P0:数据库连接池技术
-
Druid:数据库连接池实现技术,由阿里巴巴提供的
-
数据库连接池 C3P0-- 基本使用
步骤
- 导入 jar 包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,
- 不要忘记导入数据库驱动 jar 包
- 定义配置文件:
- 名称: c3p0.properties 或者 c3p0-config.xml
* 路径:直接将文件放在 src 目录下即可。
- 名称: c3p0.properties 或者 c3p0-config.xml
- 创建核心对象 数据库连接池对象 ComboPooledDataSource
- 获取连接: getConnection
public class C3P0Demo01 {
public static void main(String[] args) throws SQLException {
// 创建数据库连接池
DataSource ds = new ComboPooledDataSource();
// 获取连接对象
Connection conn = ds.getConnection();
// 打印连接对象
System.out.println(conn);
}
}
- 成功后会返回日志数据和连接对象地址
数据库连接池 C3P0-- 配置演习
配置文件
<c3p0-config>
<!-- 使用默认的配置读取连接池对象 -->
<default-config>
<!-- 连接参数 -->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db4</property>
<property name="user">root</property>
<property name="password">123456</property>
<span class="hljs-comment"><!-- 连接池参数 --></span>
<span class="hljs-comment"><!-- 初始化申请的连接数量--></span>
<span class="hljs-tag"><<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"initialPoolSize"</span>></span>5<span class="hljs-tag"></<span class="hljs-name">property</span>></span>
<span class="hljs-comment"><!-- 最大的连接数量--></span>
<span class="hljs-tag"><<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"maxPoolSize"</span>></span>10<span class="hljs-tag"></<span class="hljs-name">property</span>></span>
<span class="hljs-comment"><!-- 超时时间3s报错--></span>
<span class="hljs-tag"><<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"checkoutTimeout"</span>></span>3000<span class="hljs-tag"></<span class="hljs-name">property</span>></span>
</default-config>
<named-config name="otherc3p0">
<!-- 连接参数 -->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db4</property>
<property name="user">root</property>
<property name="password">123456</property>
<span class="hljs-comment"><!-- 连接池参数 --></span>
<span class="hljs-tag"><<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"initialPoolSize"</span>></span>5<span class="hljs-tag"></<span class="hljs-name">property</span>></span>
<span class="hljs-tag"><<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"maxPoolSize"</span>></span>8<span class="hljs-tag"></<span class="hljs-name">property</span>></span>
<span class="hljs-tag"><<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"checkoutTimeout"</span>></span>2000<span class="hljs-tag"></<span class="hljs-name">property</span>></span>
</named-config>
</c3p0-config>
演示代码
public class C3P0Demo02 {
public static void main(String[] args) throws SQLException {
// 获取 datasoure, 什么都没有传的话使用配置文件的默认设置 default-config
// DataSource ds = new ComboPooledDataSource();
// 使用指定名称的配置
DataSource ds = new ComboPooledDataSource("otherc3p0");
// 获取连接
for (int i = 1; i <= 7; i++) {
Connection conn = ds.getConnection();
System.out.println(i + ":" + conn);
}
}
}
数据库连接池 Druid-- 基本使用
- 步骤:
- 步骤:
1. 导入 jar 包 druid-1.0.9.jar
2. 定义配置文件:
* 是 properties 形式的
* 可以叫任意名称,可以放在任意目录下
3. 加载配置文件。Properties
4. 获取数据库连接池对象:通过工厂来来获取 DruidDataSourceFactory
5. 获取连接:getConnection
- 步骤:
配置文件
-
由于出现 -- 严重: testWhileIdle is true, validationQuery not set 的错误,在配置文件添加
-
driverClassName=com.mysql.cj.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/db4 username=root password=123456 # 初始化连接数 initialSize=5 # 最大连接数 maxActive=10 maxWait=3000
-- 添加
filters=stat
timeBetweenEvictionRunsMillis=60000
minEvictableIdleTimeMillis=300000
validationQuery=SELECT 1
testWhileIdle=true
testOnBorrow=false
testOnReturn=false
poolPreparedStatements=false
maxPoolPreparedStatementPerConnectionSize=200
演示代码
//druid 演示
public class DruidDemo01 {
public static void main(String[] args) throws Exception {
// 导入 jar 包
// 定义配置文件
// 加载配置文件
Properties pro = new Properties();
InputStream is = DruidDemo01.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
// 获取连接池
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
// 获取连接
<span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">1</span>; i <=<span class="hljs-number">10</span> ; i++) {
<span class="hljs-type">Connection</span> <span class="hljs-variable">conn</span> <span class="hljs-operator">=</span> ds.getConnection();
System.out.println(i+<span class="hljs-string">":"</span>+conn);
}
}
}
数据库连接池 Druid-- 工具类
定义工具类
-
定义一个类 JDBCUtils
2. 提供静态代码块加载配置文件,初始化连接池对象
3. 提供方法
1. 获取连接方法:通过数据库连接池获取连接
2. 释放资源
3. 获取连接池的方法 -
Druid 工具类
/** * Druid 连接池的工具类 */ public class DruidUtils { // 定义成员变量 DataSoure private static DataSource ds;
<span class="hljs-comment">//加载配置文件</span> <span class="hljs-keyword">static</span>{ <span class="hljs-type">Properties</span> <span class="hljs-variable">pro</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Properties</span>(); <span class="hljs-type">InputStream</span> <span class="hljs-variable">is</span> <span class="hljs-operator">=</span> DruidUtils.class.getClassLoader().getResourceAsStream(<span class="hljs-string">"druid.properties"</span>); <span class="hljs-keyword">try</span> { pro.load(is); ds = DruidDataSourceFactory.createDataSource(pro); } <span class="hljs-keyword">catch</span> (IOException e) { e.printStackTrace(); } <span class="hljs-keyword">catch</span> (Exception e) { e.printStackTrace(); }<span class="hljs-keyword">finally</span> { <span class="hljs-keyword">try</span> { is.close(); } <span class="hljs-keyword">catch</span> (IOException e) { e.printStackTrace(); } } } <span class="hljs-comment">//获取连接方法</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Connection <span class="hljs-title function_">getConnection</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> SQLException { <span class="hljs-keyword">return</span> ds.getConnection(); } <span class="hljs-comment">//释放资源2个方法</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">close</span><span class="hljs-params">(Statement ste,Connection conn)</span>{
// if (ste!=null){
// try {
// ste.close();
// } catch (SQLException e) {
// e.printStackTrace();
// }
// }
//
// if (conn!=null){
// try {
// conn.close();
// } catch (SQLException e) {
// e.printStackTrace();
// }
// }
// 简化书写
close(null,ste,conn);} <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">close</span><span class="hljs-params">(ResultSet rs,Statement ste, Connection conn)</span>{ <span class="hljs-keyword">if</span> (rs!=<span class="hljs-literal">null</span>){ <span class="hljs-keyword">try</span> { rs.close(); } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } } <span class="hljs-keyword">if</span> (ste!=<span class="hljs-literal">null</span>){ <span class="hljs-keyword">try</span> { ste.close(); } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } } <span class="hljs-keyword">if</span> (conn!=<span class="hljs-literal">null</span>){ <span class="hljs-keyword">try</span> { conn.close(); } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } } } <span class="hljs-comment">//获取返回连接池对象方法</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> DataSource <span class="hljs-title function_">getDataSoure</span><span class="hljs-params">()</span>{ <span class="hljs-type">DataSource</span> <span class="hljs-variable">dss</span> <span class="hljs-operator">=</span> <span class="hljs-literal">null</span>; <span class="hljs-keyword">if</span> (ds!=<span class="hljs-literal">null</span>){ dss = ds; } <span class="hljs-keyword">return</span> dss; }
}
工具类测试
/**
* 使用 druid 工具类完成更改 sql 数据库数据
*/
public class DruidDemo02 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pste = null;
// 获取连接对象
try {
conn = DruidUtils.getConnection();
// 定义 sql
String sql = "UPDATE account SET balance = ? where name = ?";
// 获取 prepareStatement,防止 sql 注入
pste = conn.prepareStatement(sql);
// 给?赋值
pste.setDouble(1,2000);
pste.setString(2,"zhangsan");
// 执行 sql 语句
pste.executeUpdate();
} <span class="hljs-keyword">catch</span> (SQLException e) {
e.printStackTrace();
}<span class="hljs-keyword">finally</span> {
<span class="hljs-comment">//归还连接对象</span>
DruidUtils.close(pste,conn);
}
}
}
SpringJDBC--JDBCTemplate
介绍
- Spring 框架对 JDBC 的简单封装。提供了一个 JDBCTemplate 对象简化 JDBC 的开发
步骤
-
导入 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< 类型 >(类型.class)
- query 的参数:RowMapper
- queryForObject:查询结果,将结果封装为对象
- 一般用于聚合函数的查询
- queryForMap(): 查询结果将结果集封装为 map 集合,将列名作为 key,将值作为 value 将这条记录封装为一个 map 集合
-
-
//JdbcTemplate 快速入门
public class JdbcTempLateDemo01 {
public static void main(String[] args) {
// 导入 jar 包
// 创建 JDBCTemplate 对象
JdbcTemplate jt = new JdbcTemplate(DruidUtils.getDataSoure());
// 调用方法
String sql = "UPDATE account SET balance = 5000 where name = ?";
int count = jt.update(sql, "zhangsan");
System.out.println("修改成功,已影响"+count+"行数据");
}
}
SpringJDBC--JDBCTemplate 练习
需求
private static JdbcTemplate jt = new JdbcTemplate(DruidUtils.getDataSoure());
-
修改 1 号数据的 salary 为 10000
/** * 修改 1 号数据的 salary 为 10000 */ @Test public void test1(){ // 调用方法 String sql = "UPDATE emp SET salary = ? where id = ?"; int count = jt.update(sql, 10000,1001); System.out.println("修改成功,已影响"+count+"行数据"); }
-
添加一条记录
/** * 添加一条记录 1015 郭靖 */ @Test public void test2(){ String sql = "insert into emp (id,ename) value (?,?)"; int count = jt.update(sql, 1015, "郭靖"); System.out.println("修改成功,已影响"+count+"行数据"); }
-
删除刚才添加的记录
/** * 删除刚才的数据 */ @Test public void test3(){ String sql = "delete from emp where id = ?"; int count = jt.update(sql, 1015); System.out.println("修改成功,已影响"+count+"行数据"); }
-
查询 id 为 1 的记录,将其封装为 Map 集合
/** * 查询 id 为 1 的记录,将其封装为 Map 集合 */ @Test public void test4(){ String sql = "select * from emp where id = ?"; Map<String, Object> som = jt.queryForMap(sql, 1001); System.out.println(som); }
-
查询所有记录,将其封装为 List
/** * 查询所有记录,将其封装为 List */ @Test public void test5(){ String sql = "select * from emp"; List<Map<String, Object>> maps = jt.queryForList(sql); for (Map<String, Object> map : maps) { System.out.println(map); } }
-
查询所有记录,将其封装为 Emp 对象的 List 集合
/** * 查询所有记录,将其封装为 Emp 对象的 List 集合 */ @Test public void test6(){ String sql = "select * from emp";// 使用封装好的方法传入类的字节码对象 List<Emp> query = jt.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class)); for (Emp emp : query) { System.out.println(emp); } }
-
查询总记录数
/** * 查询总记录数 */ @Test public void test7(){ String sql = "select count(id) from emp";//count 返回的是 long 类型数据 Long total = jt.queryForObject(sql, long.class); System.out.println(total); }