搜索 K
Appearance
博客正在加载中...
Appearance
JDBC Template 是用来简化我们的代码的。例如我们只关心 SQL 怎么写,怎么执行,但是封装为对象的时候要一个个手工封装,非常麻烦。
即使我们使用了连接池和工具类,可以很方便地获取连接、释放连接。
但是在操作数据库时还是存在问题:每一次操作数据库(增删改查),都要定义 SQL,设置参数,执行操作,处理结果;特别是处理结果这里非常麻烦,要一步步地封装为对象(参考 ResultSet 结果封装为对象的时候)。
其实我们应该只关心 SQL 怎么写,怎么封装成对象,这纯粹是体力活,没什么技术含量。为此,有个叫 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
queryForObject:查询结果,将结果封装为对象。一般用于聚合函数的查询
总共需要 5 个 jar 包:
commons-logging-1.2.jar
spring-beans-5.0.0.RELEASE.jar
spring-core-5.0.0.RELEASE.jar
spring-jdbc-5.0.0.RELEASE.jar
spring-tx-5.0.0.RELEASE.jar 可以从我的 GitHub 仓库里下载 jar 包:
Gitee:lib · /LearnJavaEE - Gitee
GitHub:LearnJavaEE/lib at master · Peter-JXL/LearnJavaEE
或者去官网 Spring | Home 下载。
举个例子,我们要更新一个 SQL,可以这样做:
JdbcTemplate template = new JdbcTemplate(DruidUtils.getDataSourse());
String sql = "update students set name = ? where id = ?";
int count = template.update(sql, "PeterJXL", 1);
System.out.println(count);我们不用再申请和释放连接了!我们只需要关心 SQL 语句怎么写,怎么赋值。
懂得 JdbcTemplate 的基本使用后,我们做一些练习:
每个小点我们用一个方法来完成,由于要测试的方法比较多,我们使用 Junit 框架
这里先演示前 3 个方法:
package chapter2JDBC;
import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
import java.sql.*;
public class JDBCDemo17TemplateDML {
private JdbcTemplate template = new JdbcTemplate(DruidUtils.getDataSourse());
@Test
public void testUpdateStuname(){
String sql = "update students set name = ? where id = ?";
int caixukun = template.update(sql, "caixukun", 1);
System.out.println(caixukun);
}
@Test
public void testInsertStu(){
String sql = "insert into students (id, grade, name, gender, score) values (?, ?,?,?,?)";
int caixukun = template.update(sql, 666, 1, "caixukun", 1, 99);
System.out.println(caixukun);
}
@Test
public void testDelStu(){
String sql = "delete from students where id = ?";
int count = template.update(sql,666);
System.out.println(count);
}
}
继续完成以下练习:
queryForMap:查询一条数据并封装 queryForMap():查询结果将结果集封装为 map 集合,将列名作为 key,将值作为 value 将这条记录封装为一个 map 集合。注意:这个方法查询的结果集长度只能是 1
@Test
public void testSelect1(){
String sql = "select * from students where id = ?";
Map<String, Object> stringObjectMap = template.queryForMap(sql, 1);
System.out.println(stringObjectMap);
} 运行结果:
{id=1, name=caixukun, gender=true, grade=1, score=88} 注意:queryForMap() 只能封装一条数据的情况,如果有多条数据或者 0 条,则会报错,假设我们这样写:
String sql = "select * from students";
Map<String, Object> stringObjectMap = template.queryForMap(sql);
System.out.println(stringObjectMap);运行结果:
org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expected 1, actual 13
......
queryForList:封装为 list 集合 queryForList():查询结果将结果集封装为 list 集合。注意:将每一条记录封装为一个 Map 集合,再将 Map 集合装载到 List 集合中
public void testSelect1(){
String sql = "select * from students where id = ?";
Map<String, Object> stringObjectMap = template.queryForMap(sql, 1);
System.out.println(stringObjectMap);
} 运行结果:
{id=1, name=caixukun, gender=true, grade=1, score=88}
{id=2, name=小红, gender=true, grade=1, score=95}
{id=3, name=小军, gender=false, grade=1, score=93}
{id=4, name=小白, gender=false, grade=1, score=100}
{id=5, name=小牛, gender=true, grade=2, score=96}
{id=6, name=小兵, gender=true, grade=2, score=99}
{id=7, name=小强, gender=false, grade=2, score=86}
{id=8, name=小乔, gender=false, grade=2, score=79}
{id=9, name=小青, gender=true, grade=3, score=85}
{id=10, name=小王, gender=true, grade=3, score=90}
{id=11, name=小林, gender=false, grade=3, score=91}
{id=12, name=小贝, gender=false, grade=3, score=77}
{id=1011, name=caixukun, gender=true, grade=1, score=99}
query:封装对象 query():查询结果,将结果封装为 JavaBean 对象。query 的参数:RowMapper 对象
@Test
public void testQuery(){
String sql = "select * from students ";
List<Student> stus = template.query(sql, new RowMapper<Student>() {
@Override
public Student mapRow(ResultSet rs, int i) throws SQLException {
Student stu = new Student();
int id = rs.getInt("id");
String name = rs.getString("name");
int gender = rs.getInt("gender");
int grade = rs.getInt("grade");
int score = rs.getInt("score");
stu.setId(id);
stu.setName(name);
stu.setGender(gender);
stu.setGrade(grade);
stu.setScore(score);
return stu;
}
});
for (Student stu : stus) {
System.out.println(stu);
}
} 但这样好像并没简化多少代码?我们之前也是这样写的。先别急,我们可以用默认的实现类,而不是自己实现 RowMapper 匿名内部类,简化了大量的代码:
@Test
public void testQuery2(){
String sql = "select * from students ";
List<Student> stus = template.query(sql, new BeanPropertyRowMapper<>(Student.class));
for (Student stu : stus) {
System.out.println(stu);
}
} 我们来看看 BeanPropertyRowMapper 的源码:可以看到 BeanPropertyRowMapper 已经实现了 RowMapper 接口。
public class BeanPropertyRowMapper<T> implements RowMapper<T> {queryForObject:查询总记录数 queryForObject:查询结果,将结果封装为对象。一般用于聚合函数的查询
@Test
public void testQuerySum(){
String sql = "select count(id) from students ";
Long aLong = template.queryForObject(sql, Long.class);
System.out.println(aLong);
}第二个参数的意思是,返回的类型要用什么类型来接受,这里我们用 Long。
使用 JDBCTemplate,可以大大简化我们的代码,我们只需关心 SQL 怎么写。