○●○ 数据库连接池
本质: 存放数据库连接的容器(集合)。
原理: 容器中会申请一些连接对象。当用户来访问数据库时,从容器中获取连接对象;访问结束,归还连接对象给容器。
优点 不言而喻:
- 降低资源消耗(减少了创建和销毁连接的次数,每个连接可以重复使用)
- 提高相应速度(用户不用等待连接创建,而是直接从连接池中获取)
实现:
连接池是个javax.sql包下的DataSource接口
getConnection() 获取连接
close() 归还连接(这种语境下,不是"关闭",而是"归还")
注: 这个接口不是由sun公司实现,而是由数据库厂商提供实现类(驱动): 1. C3P0 2. Druid (阿里巴巴提供)
----------------------------------------- C3P0 数据库连接池技术 -------------------------------------------------
1. 导入两个jar包 (复制到libs目录,然后添加到目录), 数据库驱动jar包也要提前导入
2. 定义配置文件 (配置文件会被自动寻找到):
* 名称: c3p0.properties 或者 c3p0-config.xml
* 路径:直接将文件放在src目录下
DataSource pool = new ComboPooledDataSource(); // 文件中默认配置
DataSource pool = new ComboPooledDataSource("otherc3p0"); // 指定文件中的其他配置
Connection conn = pool.getConnection();
conn.close();
----------------------------------------- Druid 数据库连接池技术 ------------------------------------------------
1. 导入jar包
2. 定义配置文件:properties形式的,任意名称,可以放在任意目录下; 需要手动加载
// 因为配置文件的位置是任意的,因此需要手动加载配置文件
// 但这个加载很简单,不需要分别获取配置文件的键值对,然后注册驱动;作为一个流直接传给工厂就可以了
Properties pro = new Properties();
InputStream stream = Demo.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(stream);
DataSource pool = DruidDataSourceFactory.createDataSource(pro);
Connection conn = pool.getConnection();
conn.close();
○●○ Spring JDBC
▶ Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发。
1. 导入jar包
2. 创建JdbcTemplate对象。依赖于数据源DataSource
* JdbcTemplate template = new JdbcTemplate(pool); // 传入一个DataSourse连接池对象
3. 调用JdbcTemplate的方法来完成CRUD的操作
* update() 执行DML语句
* queryForMap() DQL结果集封装为Map
* queryForList() DQL结果集封装为List (每个元素是一个Map)
* query() DQL结果封装为JavaBean对象(参数为"new BeanPropertyRowMapper<>(类型.class)",返回指定类型的集合)
* queryForObject() DQL结果封装为对象(用来执行带有聚合函数的sql)
---------------------------------------- 5种方法 测试Test ------------------------------------------------------
public class Test {
// 创建JdbcTemplate对象(传入一个DataSource连接池)
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSourse());
@Test
public void test1(){
String sql = "delete from loliTable where id= ?";
template.update(sql, 1);
}
// 执行DML语句(返回受影响的行数)
@Test
public void test2(){
String sql = "select * from loliTable where loliName = ?";
Map<String, Object> map = template.queryForMap(sql, "Alice");
System.out.println(map);
}
// {id=1, loliName=Alice, loliAge=12}
// 注:要保证查询结果集只有一行
@Test
public void test5(){
String sql = "select * from loliTable";
List<Map<String, Object>> list = template.queryForList(sql);
System.out.println(list);
}
// [{id=1, loliName=Alice, loliAge=12}, {id=2, loliName=Chino, loliAge=10}, {id=3, loliName=Hana, loliAge=11}]
// 多行Map结果集的List集合.
@Test
public void test6(){
String sql = "select * from loliTable";
List<Loli> lolis = template.query(sql, new BeanPropertyRowMapper<>(Loli.class));
System.out.println(lolis);
}
// [Loli{id=null, loliName='null', loliAge=null}, Loli{id=null, loliName='null', loliAge=null}, Loli{id=null, loliName='null', loliAge=null}]
// 对象的集合. 与上面的相比,这是最常见的写法.
// BeanPropertyRowMapper是RowMapper接口的实现类,帮我完成了【转化成对象】的工作;
// 我们也可以手动实现RowMapper接口,覆盖mapRow(ResultSet, int)方法————这个方法会迭代执行,完成结果集→对象的转化
@Test
public void test7(){
String sql = "select count(id) from loliTable";
Long total = template.queryForObject(sql, Long.class);
System.out.println(total);
}
// 返回3. queryForObject一般用于执行带有聚合函数的sql
}
♬ End