今日内容
- 数据库连接池
- Spring JDBC: JDBC Template
数据库连接池
-
概念:其实就是个容器(集合),存放数据库连接的容器。
当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后·,会将连接对象还给容器。 -
好处:
- 节约资源;
- 用户访问高效
-
实现
- 标准接口:DataSource javax.sql包下的
-
方法:
- 获取连接:getconenection();
- 归还连接:connection.close();
如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接
-
一般不去实现,由数据库厂商实现
- C3P0:数据库连接池技术
- Druid:数据库连接池实现技术,由阿里巴巴提供
-
- 标准接口:DataSource javax.sql包下的
-
C3P0:数据库连接池技术
* 步骤:
1. 导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,
* 不要忘记导入数据库驱动jar包
2. 定义配置文件:
* 名称: c3p0.properties 或者 c3p0-config.xml
* 路径:直接将文件放在src目录下即可。<c3p0-config> <!-- 使用默认的配置读取连接池对象 --> <default-config> <!-- 连接参数 --> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/db3</property> <property name="user">root</property> <property name="password">CR123123</property> <!-- 连接池参数 --> <!--初始化申请的连接数量--> <property name="initialPoolSize">5</property> <property usee="initialPoolSize">5</property> <!--最大的连接数量--> <property name="maxPoolSize">10</property> <!--超时时间--> <property name="checkoutTimeout">3000</property> </default-config>
3. 创建核心对象 数据库连接池对象 CombopooedDataSource 4. 获取连接:getConnection
//1.创建数据库连接池对象 DataSource ds = new ComboPooledDataSource(); //2. 获取连接对象 Connection conn = ds.getConnection(); ```
-
Druid:数据库连接池实现技术,由阿里巴巴提供
- 步骤
- 导入jar包 druid-1.0.9.jar
- 定义配置文件
-
是properties形式的
-
可以叫任意名称,可以放在任意目录下
-
加载配置文件,properties
-
获取数据库连接池对象:通过工厂DruidDataSourceFactory
-
获取连接:getConnnection
public static void main(String[] args) throws Exception { //3.加载配置文件 Properties pro = new Properties(); InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties"); pro.load(is); //4.获取连接池对象 DataSource ds = DruidDataSourceFactory.createDataSource(pro); //5.获取连接 Connection conn = ds.getConnection(); }
-
- 定义工具类
- 定义一个类 JDBCUtils
- 提供静态代码块加载配置文件,初始化连接池对象
- 提供方法
- 获取连接方法:通过数据库连接池获取连接
- 释放资源
- 获取连接池的方法
- 定义一个类 JDBCUtils
- 步骤
public class JDBCutils {
private static DataSource ds;
public JDBCutils() {
}
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
public static DataSource getDataSource() {
return ds;
}
public static void close(Statement st, Connection c, ResultSet rs) {
if (c != null) {
try {
c.close();
} catch (SQLException var6) {
var6.printStackTrace();
}
}
if (st != null) {
try {
st.close();
} catch (SQLException var5) {
var5.printStackTrace();
}
}
if (rs != null) {
try {
rs.close();
} catch (SQLException var4) {
var4.printStackTrace();
}
}
}
static {
try {
Properties p = new Properties();
p.load(JDBCutils.class.getClassLoader().getResourceAsStream("druid.properties"));
ds = DruidDataSourceFactory.createDataSource(p);
} catch (IOException var1) {
var1.printStackTrace();
} catch (Exception var2) {
var2.printStackTrace();
}
}
}
Spring JDBC
Spring框架对于JDBC的简单封装,提供了一个JDBCTemplate对象简化JDBC的开发
步骤
- 导入jar包
- 创建JDBCTemplate对象。依赖于数据渊DataSource
JdbcTemplate template = new JdbcTemplate(ds); - 调用JDBCTemplate的方法来完成CRUD的操作
1. update();执行DML语句 增删改
2. queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为Value将这条记录封装为一个map
注意:这个方法结果集长度只能是1
3. queryForlist():查询结果j将结果集封装为list集合
注意:将每一条记录封装为一个map集合,然后list中的元素就是这些map
4. query():查询结果,将结果封装为JavaBean对象
new BeanPropertyRowMapper<类型>(类型.class)
5. queryForObject:查询结果,将结果封装为对象
* 一般用于聚合函数的查询如count(id)
单行单列
//update();执行DML语句 增删改
public void test2() {
String sql = "insert into emp(id,ename,dept_id) values(?,?,?)";
int count = template.update(sql, 1015, "cr", 10);
System.out.println(count);
Assert.assertEquals(1, count);
}
输入:
1
代表了实际上受到影响的行数
可以把template理解为一个statement
/**queryForMap():查询结果将结果集封装为map集合,
将列名作为key,将值作为Value将这条记录封装为一个map
注意是单条记录
**/
public void test10() {
String sql = "Select * from emp where id=? ";
Map<String, Object> map = template.queryForMap(sql, 1001);
System.out.println(map);
}
输出:一条记录 以map形式
{id=1001, ename=孙悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20}
/**
queryForlist():
查询结果j将结果集封装为list集合
注意:将每一条记录封装为一个map集合,
然后list中的元素就是这些map
*//
public void test4() {
String sql = "Select * from emp where id=? or id=?";
List<Map<String, Object>> maps = template.queryForList(sql, 1001, 1002);
for (Map map : maps) {
System.out.println(map);
}
}
输入:
{id=1001, ename=孙悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20}
{id=1002, ename=卢俊义, job_id=3, mgr=1006, joindate=2001-02-20, salary=16000.00, bonus=3000.00, dept_id=30}
由于遍历了map中的内容,该处的list中有两个map
/*
query():查询结果,将结果封装为JavaBean对象
new BeanPropertyRowMapper<类型>(类型.class)
*/
public void test6() {
String sql = "Select * from emp ";
List<Emp> emps = template.query(sql, new RowMapper<Emp>() {
@Override
public Emp mapRow(ResultSet rs, int i) throws SQLException {
Emp emp = new Emp();
int id = rs.getInt("id");
String ename = rs.getString("ename");
int job_id = rs.getInt(3);
int mgr = rs.getInt(4);
Date date = rs.getDate(5);
double salary = rs.getDouble(6);
double bonus = rs.getDouble(7);
int dept_id = rs.getInt(8);
emp.setId(id);
emp.setEname(ename);
emp.setJob_id(job_id);
emp.setMgr(mgr);
emp.setJoindate(date);
emp.setSalary(salary);
emp.setBonus(bonus);
emp.setDept_id(dept_id);
return emp;
}
});
for (Emp emp : emps) {
System.out.println(emp);
}
}
输出:
Emp{id=1001, ename='孙悟空', job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.0, bonus=0.0, dept_id=20}
Emp{id=1002, ename='卢俊义', job_id=3, mgr=1006, joindate=2001-02-20, salary=16000.0, bonus=3000.0, dept_id=30}
Emp{id=1003, ename='林冲', job_id=3, mgr=1006, joindate=2001-02-22, salary=12500.0, bonus=5000.0, dept_id=30}
注意参数中第二个是RowMapper接口需要重写
mapRow(ResultSet rs, int i) 方法
参数rs代表着查询后得到的结果集
第二个参数是实际上在数据库中受到影响的行数,此处为查询的条数
// query():查询结果,将结果封装为JavaBean对象
// new BeanPropertyRowMapper<类型>(类型.class)
实际上在编程中不需要自己重写RowMapper()方法,jdbctemplate给了一个已经实现的实现类参数为需要封装的Java Bean对象的字节码对象
BeanPropertyRowMapper<类型>(类型.class)
public void test7() {
String sql = "Select * from emp ";
List<Emp> emps = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));
for (Emp emp : emps) {
System.out.println(emp);
}
}
输入:
Emp{id=1001, ename='孙悟空', job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.0, bonus=0.0, dept_id=20}
Emp{id=1002, ename='卢俊义', job_id=3, mgr=1006, joindate=2001-02-20, salary=16000.0, bonus=3000.0, dept_id=30}
Emp{id=1003, ename='林冲', job_id=3, mgr=1006, joindate=2001-02-22, salary=12500.0, bonus=5000.0, dept_id=30}
/**
queryForObject:查询结果,将结果封装为对象
* 一般用于聚合函数的查询如count(id)
单行单列
**/
public void test8() {
String sql = "Select count(id) from emp ";
Long l = template.queryForObject(sql, long.class);//执行聚合函数
System.out.println(l);
}
一般应用于单行单列的结果。如聚合函数count();