SpringBoot轻松整合Mybatis

    技术2024-10-29  24

    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吧,让我们不再烦心于复杂的配置,只需要关注业务逻辑的实现即可。

    Processed: 0.011, SQL: 9