9.访问数据库2
数据更新
//注入JdbcTemplate
@Autowired
JdbcTemplate jdbcTemplate;
// 数据更新
@Test
void test7(){
String sql = """
update student set
name = ?
where id = ?
""";
// sql 从左 ---》 右,每一个 ? 对应的 值
jdbcTemplate.update(sql,"烟雨666", 2);
UserPO userPO = jdbcTemplate.queryForObject("select * from student where id = ?", (rs, rows) -> {
var id = rs.getInt("id");
var name = rs.getString("name");
var stuid = rs.getString("stuid");
var major = rs.getString("major");
return new UserPO(id, name, stuid, major);
}, 2);
System.out.println(userPO);
// UserPO{id=2, name='烟雨666', stuid='1002', major='软件技术'}
}
NamedParameterJdbcTemplate
NamedParameterJdbcTemplate 能够接受命名的参数,通过具名的参数提供代码的可读性,JdbcTemplate 使用 的是参数索引的方式。
在使用模板的位置注入 NamedParameterJdbcTemplate 对象,编写 SQL 语句,在 SQL 中 WHERE 部分“:命 名参数”。调用 NamedParameterJdbcTemplate
的诸如 query,queryForObject, execute,update 等时,将参数封装到 Map 中。
// 参数模板
@Autowired
NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@Test
void test8(){
// 使用模板写参数
String sql = "select * from student where id=:myid";
// 创建集合给模板赋值
HashMap<String, Object> objectObjectHashMap = new HashMap<>();
// 集合添加元素
objectObjectHashMap.put("myid",2);
// 执行 SQL 集合参数 绑定bean与 期待类型
UserPO userPO = namedParameterJdbcTemplate.queryForObject(sql, objectObjectHashMap,new BeanPropertyRowMapper<>(UserPO.class));
System.out.println(userPO);
// UserPO{id=2, name='烟雨666', stuid='1002', major='软件技术'}
}
多表查询
- 准备两个Java类,一个对应 student . java 另一个student_detail . java ,作为 student . java 的一个实例变量
出现类似的错误:基本上是,Lombok 无法生效,解决:自己去实现bean规范
package com.yanyu.jdbc1.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Objects;
/**
* @Author yanyu666_508200729@qq.com
* @Date 2025/3/30 21:10
* @description:
*/
public class StudentDetail {
// 把这个类,作为 Student 的一个实例变量
private Integer id;
private Integer studentId;
private String addr;
public StudentDetail(Integer id, Integer studentId, String addr) {
this.id = id;
this.studentId = studentId;
this.addr = addr;
}
public StudentDetail() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getStudentId() {
return studentId;
}
public void setStudentId(Integer studentId) {
this.studentId = studentId;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StudentDetail that = (StudentDetail) o;
return Objects.equals(id, that.id) && Objects.equals(studentId, that.studentId) && Objects.equals(addr, that.addr);
}
@Override
public int hashCode() {
return Objects.hash(id, studentId, addr);
}
@Override
public String toString() {
return "StudentDetail{" +
"id=" + id +
", studentId=" + studentId +
", addr='" + addr + '\'' +
'}';
}
}
package com.yanyu.jdbc1.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Objects;
/**
* @Author yanyu666_508200729@qq.com
* @Date 2025/3/30 21:10
* @description:
*/
public class Student {
private Integer id;
private String name;
private String stuid;
private String major;
// 添加 附表对应的实体 StudentDetail
private StudentDetail studentDetail;
public Student(Integer id, String name, String stuid, String major, StudentDetail studentDetail) {
this.id = id;
this.name = name;
this.stuid = stuid;
this.major = major;
this.studentDetail = studentDetail;
}
public Student() {
}
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 String getStuid() {
return stuid;
}
public void setStuid(String stuid) {
this.stuid = stuid;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
public StudentDetail getStudentDetail() {
return studentDetail;
}
public void setStudentDetail(StudentDetail studentDetail) {
this.studentDetail = studentDetail;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", stuid='" + stuid + '\'' +
", major='" + major + '\'' +
", studentDetail=" + studentDetail +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return Objects.equals(id, student.id) && Objects.equals(name, student.name) && Objects.equals(stuid, student.stuid) && Objects.equals(major, student.major) && Objects.equals(studentDetail, student.studentDetail);
}
@Override
public int hashCode() {
return Objects.hash(id, name, stuid, major, studentDetail);
}
}
// 参数模板
@Autowired
NamedParameterJdbcTemplate namedParameterJdbcTemplate;
// 多表查询
@Test
void test9(){
String sql = """
select s.id,s.name,s.stuid,s.major,sd.id as student_detail_id,sd.student_id,sd.addr
from student s join student_detail sd
on s.id = sd.student_id
where s.id =:id
""";
HashMap<String, Object> objectObjectHashMap = new HashMap<>();
objectObjectHashMap.put("id",1);
Student student = namedParameterJdbcTemplate.queryForObject(sql, objectObjectHashMap, (rs, rows) -> {
// student 信息
var id = rs.getInt("id");
var name = rs.getString("name");
var stuid = rs.getString("stuid");
var major = rs.getString("major");
// student_detail 信息
var student_detail_id = rs.getInt("student_detail_id");
var student_id = rs.getInt("student_id");
var addr = rs.getString("addr");
StudentDetail studentDetail = new StudentDetail(student_detail_id, student_id, addr);
return new Student(id, name, stuid, major, studentDetail);
});
System.out.println(student);
//Student{id=1, name='烟雨1', stuid='1001', major='计算机应用技术', studentDetail=StudentDetail{id=1, studentId=1, addr='东莞'}}
}
总结:
JdbcTemplate 的优点简单,灵活,上手快,访问多种数据库。对数据的处理控制能力比
较强,RowMapper, ResultSetExtractor 能够提供按需要灵活定制记录集与实体类的关系。
缺点:对 SQL 要求高,适合对 SQL 比较了解,自定义查询结果比较多,调优需求的。
JdbcTemplate 对象的调整参数,比较少。可设置 spring.jdbc.template.开头的配置项目,
比如设置超时为 10 秒,spring.jdbc.template.query-timeout=10。