描述
使用
例子
插入
修改
删除
查询
queryForMap():查询结果,将结果集封装为map集合
queryForList():查询结果,将结果集封装为list集合
query():查询结果,将结果集封装为JavaBean对象
queryForObject:查询结果,将结果集封装为对象
描述
JdbcTemplate是Spring框架对JDBC的简单封装,依赖于数据源DataSource
使用
要是用得先导包
调用JdbcTemplate的方法来完成CRUD的操作
- update():执行DML语句。增、删、改语句
- queryForMap():查询结果,将结果集封装为map集合
- queryForList():查询结果,将结果集封装为list集合
- query():查询结果,将结果集封装为JavaBean对象
- queryForObject:查询结果,将结果集封装为对象
例子
下面我们用一个例子说明,为何封装方便,例子用到:
- druid连接池以及Jdbc工具类
- 单元测试
package com.lingaolu;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* @author 林高禄
* @create 2020-06-28-9:43
*/
public class TemplateDemo {
private JdbcTemplate template = new JdbcTemplate(JdbcUtils.getDataSource());
}
用到的数据库表
- 学生表
- 班级表
插入
@Test
public void insert() {
String sql = "insert into student(name,class_id,ageNum) values('王帅',2,22)";
int update = template.update(sql);
System.out.println(update);
}
运行输出:
1
运行后学生表中的数据多了一条王帅
修改
@Test
public void update(){
String sql = "update student set name=? where name=?";
int update = template.update(sql,"王丑","王帅");
System.out.println(update);
}
运行输出:
1
运行后表中的数据,王帅变成了王丑
删除
@Test
public void delete(){
String sql = "delete from student where name=?";
int delete = template.update(sql, "王丑");
System.out.println(delete);
}
运行输出:
1
运行后表中的数据,王丑删除了
查询
queryForMap():查询结果,将结果集封装为map集合
@Test
public void queryForMap(){
String sql = "select * from student";
Map<String, Object> stringObjectMap = template.queryForMap(sql);
System.out.println(stringObjectMap);
}
运行输出:
org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expected 1, actual 3
......
......
因为queryForMap()只能需要一条结果,而我们查出来的是3条,所以报错,所以我们修改一下sql,值查出一条
@Test
public void queryForMap(){
String sql = "select * from student limit 0,1";
Map<String, Object> stringObjectMap = template.queryForMap(sql);
System.out.println(stringObjectMap);
}
运行输出:
{id=1, name=林帅, class_id=2, ageNum=23}
queryForList():查询结果,将结果集封装为list集合
@Test
public void queryForList(){
String sql = "select * from student";
List<Map<String, Object>> maps = template.queryForList(sql);
maps.forEach(System.out::println);
}
运行输出:
{id=1, name=林帅, class_id=2, ageNum=23}
{id=2, name=徐帅, class_id=2, ageNum=24}
{id=3, name=吴帅, class_id=1, ageNum=27}
query():查询结果,将结果集封装为JavaBean对象
我们先把学生表的字段和值修改一下,原来的ageNum改为num_age,并且把“徐帅”的num_age置为null
再来一个实体类StudentVo
package com.lingaolu;
/**
* @author 林高禄
* @create 2020-06-28-10:54
*/
public class StudentVo {
private int id;
private String name;
private int ageNum;
private String classname;
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 int getAgeNum() {
return ageNum;
}
public void setAgeNum(int ageNum) {
this.ageNum = ageNum;
}
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
}
@Override
public String toString() {
return "StudentVo{" +
"id=" + id +
", name='" + name + '\'' +
", ageNum=" + ageNum +
", classname='" + classname + '\'' +
'}';
}
}
@Test
public void query() {
String sql = "select t.*,c.name class_name from student t left join class c on t.class_id = c.id";
List<StudentVo> query = template.query(sql, new BeanPropertyRowMapper<StudentVo>(StudentVo.class));
query.forEach(System.out::println);
}
运行输出:
org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'null' to required type 'int' for property 'ageNum'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [null] to type [int] for value 'null'; nested exception is java.lang.IllegalArgumentException: A null value cannot be assigned to a primitive type
......
......
A null value cannot be assigned to a primitive type,空值不能分配给基元类型,这就是我特意把其中一个num_age置为空的原因,所以我们以后为了防止报错,写实体类的属性要用包装类对象,而不用基本类型
修改后的StudentVo的代码
package com.lingaolu;
/**
* @author 林高禄
* @create 2020-06-28-10:54
*/
public class StudentVo {
private Integer id;
private String name;
private Integer ageNum;
private String classname;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAgeNum() {
return ageNum;
}
public void setAgeNum(Integer ageNum) {
this.ageNum = ageNum;
}
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
}
@Override
public String toString() {
return "StudentVo{" +
"id=" + id +
", name='" + name + '\'' +
", ageNum=" + ageNum +
", classname='" + classname + '\'' +
'}';
}
}
再次运行输出:
StudentVo{id=1, name='林帅', ageNum=23, classname='null'}
StudentVo{id=2, name='徐帅', ageNum=null, classname='null'}
StudentVo{id=3, name='吴帅', ageNum=27, classname='null'}
发现没有,我们的classname全是空的,奇怪,数据库里的age_num能赋值到Student属性里的ageNum,为何sql查出来的class_name不能赋值到Student属性里的classname呢,因为表里属性下划线查出来后能转为驼峰命名,但是classname并不是驼峰命名,className才是驼峰命名,所以这里我们要改一下,第一种改法是把StudentVo类里的classname改为className,第二种改法是sql语句取别名和StudentVo类的对应,这里我们采用第一种,规范一下命名,建议sql的别名最好也要规范一下和属性一致,看着舒服,当然不改也行。
package com.lingaolu;
/**
* @author 林高禄
* @create 2020-06-28-10:54
*/
public class StudentVo {
private Integer id;
private String name;
private Integer ageNum;
private String className;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAgeNum() {
return ageNum;
}
public void setAgeNum(Integer ageNum) {
this.ageNum = ageNum;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
@Override
public String toString() {
return "StudentVo{" +
"id=" + id +
", name='" + name + '\'' +
", ageNum=" + ageNum +
", className='" + className + '\'' +
'}';
}
}
测试例子还是原来的代码
@Test
public void query() {
String sql = "select t.*,c.name class_name from student t left join class c on t.class_id = c.id";
List<StudentVo> query = template.query(sql, new BeanPropertyRowMapper<StudentVo>(StudentVo.class));
query.forEach(System.out::println);
}
运行输出:
StudentVo{id=1, name='林帅', ageNum=23, className='优秀班'}
StudentVo{id=2, name='徐帅', ageNum=null, className='优秀班'}
StudentVo{id=3, name='吴帅', ageNum=27, className='尖子班'}
queryForObject:查询结果,将结果集封装为对象
@Test
public void queryForObject() {
String sql = "select count(*) from student";
Map map = template.queryForObject(sql, Map.class);
System.out.println(map);
}
运行输出:
org.springframework.dao.TypeMismatchDataAccessException: Type mismatch affecting row number 0 and column type 'BIGINT': Value [3] is of type [java.lang.Long] and cannot be converted to required type [java.util.Map]
Long不能转为Map,queryForObject方法一般是适用于聚合函数,返回的是Long值,所以我们要把测试代码修改下
@Test
public void queryForObject() {
String sql = "select count(*) from student";
Long aLong = template.queryForObject(sql, Long.class);
System.out.println(aLong);
}