SpringBoot整合Mybatis
现在大多数开发工作,就是用SpringBoot集成Mybatis来完成数据交互的。
一、使用Mybatis完成基本CRUD
1、项目架构
2、配置数据源
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/demo?serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
3、创建与数据库表对应的实体类
import java.sql.Date;
import java.util.Objects;
public class Emp {
private Integer empno;
private String ename;
private String job;
private Integer mgr;
private Date hiredate;
private Double sal;
private Double comm;
private Integer deptno;
public Emp() {
}
public Emp(Integer empno, String ename) {
this.empno = empno;
this.ename = ename;
}
public Emp(Integer empno, String ename, String job, Integer mgr, Date hiredate, Double sal, Double comm, Integer deptno) {
this.empno = empno;
this.ename = ename;
this.job = job;
this.mgr = mgr;
this.hiredate = hiredate;
this.sal = sal;
this.comm = comm;
this.deptno = deptno;
}
public Integer getEmpno() {
return empno;
}
public void setEmpno(Integer empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public Integer getMgr() {
return mgr;
}
public void setMgr(Integer mgr) {
this.mgr = mgr;
}
public Date getHiredate() {
return hiredate;
}
public void setHiredate(Date hiredate) {
this.hiredate = hiredate;
}
public Double getSal() {
return sal;
}
public void setSal(Double sal) {
this.sal = sal;
}
public Double getComm() {
return comm;
}
public void setComm(Double comm) {
this.comm = comm;
}
public Integer getDeptno() {
return deptno;
}
public void setDeptno(Integer deptno) {
this.deptno = deptno;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Emp)) return false;
Emp emp = (Emp) o;
return Objects.equals(empno, emp.empno) &&
Objects.equals(ename, emp.ename) &&
Objects.equals(job, emp.job) &&
Objects.equals(mgr, emp.mgr) &&
Objects.equals(hiredate, emp.hiredate) &&
Objects.equals(sal, emp.sal) &&
Objects.equals(comm, emp.comm) &&
Objects.equals(deptno, emp.deptno);
}
@Override
public int hashCode() {
return Objects.hash(empno, ename, job, mgr, hiredate, sal, comm, deptno);
}
@Override
public String toString() {
return "Emp{" +
"empno=" + empno +
", ename='" + ename + '\'' +
", job='" + job + '\'' +
", mgr=" + mgr +
", hiredate=" + hiredate +
", sal=" + sal +
", comm=" + comm +
", deptno=" + deptno +
'}';
}
}
4、配置Mapper接口类
增删改查方法的声明
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface EmpMapper {
List<Emp> selectEmp();
Emp selectEmpById(Integer empno);
Integer addEmp(Emp emp);
Integer updateEmp(Emp emp);
Integer deleteEmp(Integer empno);
}
5、在resources下创建Emp.xml文件
增删改查方法的sql语句实现
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mashibing.mapper.EmpMapper">
<select id="selectEmp" resultType="Emp">
select * from emp
</select>
<select id="selectEmpById" resultType="Emp">
select * from emp where empno = #{empno}
</select>
<insert id="addEmp" parameterType="Emp">
insert into emp (empno,ename) values (#{empno},#{ename})
</insert>
<update id="updateEmp" parameterType="Emp">
update emp set ename=#{ename} where empno = #{empno}
</update>
<delete id="deleteEmp" parameterType="int">
delete from emp where empno = #{empno}
</delete>
</mapper>
6、编写yaml配置文件
修改yaml配置文件,添加Mybatis的相关配置,使支持Mybatis
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/demo?serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:mybatis/mapper/*.xml
type-aliases-package: com.mjt.entity
注意编写标签的时候的细节:
yaml使用基本原则:
- 大小写敏感
- 使用缩进表示层级关系
mybatis是通过缩进来表示层级关系的,所以上面这个yaml配置文件是有问题的,你能发现问题在哪吗?
7、编写Controller,处理请求
我们这里只是模拟增删改查的实现,所有处理都在Controller层完成了,实际上我们开发中应该分层进行处理:
- 接收请求应该在Service层
- 将service层的请求并向后转发,将数据库返回的信息向前转发应该在Controller层
- 与数据库交互应该在Dao层
这里没有详细细分。
import com.mjt.entity.Emp;
import com.mjt.mapper.EmpMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class EmpController {
@Autowired
private EmpMapper empMapper;
//选择全部用户
@GetMapping("/selectEmp")
public String selectEmp(){
List<Emp> emps = empMapper.selectEmp();
for (Emp Emp : emps) {
System.out.println(Emp);
}
return "ok";
}
//根据id选择用户
@GetMapping("/selectEmpById")
public String selectEmpById(){
Emp emp = empMapper.selectEmpById(1234);
System.out.println(emp);
return "ok";
}
//添加一个用户
@GetMapping("/addEmp")
public String addEmp(){
empMapper.addEmp(new Emp(1234,"heheda"));
return "ok";
}
//修改一个用户
@GetMapping("/updateEmp")
public String updateEmp(){
empMapper.updateEmp(new Emp(1234,"heihei"));
return "ok";
}
//根据id删除用户
@GetMapping("/deleteEmp")
public String deleteEmp(){
empMapper.deleteEmp(1234);
return "ok";
}
}
8、运行测试
我们在浏览器发送请求之后,发现并不能正常进行mapper方法的调用,报错信息:Invalid bound statement (not found)
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.mjt.mapper.EmpMapper.selectEmp
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)问题,即在mybatis中dao接口与mapper配置文件在做映射绑定的时候出现问题,简单说,就是接口与xml要么是找不到,要么是找到了却匹配不到
此问题检索到解决方法,如下:
解决org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)问题解决org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
但是以上的解决方案并没有解决我的问题,经过了半个小时的排查,我发现问题还是出现在application.yaml配置文件上,我们先来回顾一下yaml配置文件的细节:
yaml使用基本原则:
- 大小写敏感
- 使用缩进表示层级关系
- 禁止使用tab缩进,只能使用空格键
- 缩进长度没有限制,只要元素对齐就表示这些元素属于一个层级。
- 使用#表示注释
- 字符串可以不用引号标注
我们要特别注意一点:yaml是通过使用缩进表示层级关系 ,而我们上面的yaml配置文件是把mybatis放置在spring的下一层,意味着mybatis应该在Spring的下面找,这是不对的。
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/demo?serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:mybatis/mapper/*.xml
type-aliases-package: com.mjt.entity
应该配置成下面这种层级关系:
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/demo?serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
#注意:mybatis同样是一级目录,要顶格
mybatis:
#配置mapper.xml文件所在的路径
mapper-locations: classpath:mapper/*.xml
#配置实体类bean所在的包名
type-aliases-package: com.mjt.entity
这时再运行项目,浏览器发送请求之后,能够执行SQL语句:
二、总结
我们在上面简单的演示了SpringBoot如何集成Mybatis,可以发现相较于使用SSM时Mybatis的复杂配置,SpringBoot内置的组件能够大大的减少我们的配置。
我们这里只是简单的演示了基本的增删改查功能,其他稍微复杂的功能如事务的控制等、我们不在这里演示。
基本的开发功能和模块、方法、SQL语句的编写同Mybatis没有任何变化。大胆的拥抱SpringBoot吧,让我们不再烦心于复杂的配置,只需要关注业务逻辑的实现即可。