整合Springboot-Mybatis和resultMap映射

1、整合Mybatis并执行一个SQL

1、创建项目时引入mybatis启动器和jdbc启动器。

  1. mybatis-spring-boot-starter
  2. spring-boot-starter-jdbc

2、在yaml配置文件中配置mysql参数

#配置mybatis
spring:
  datasource:
    username: root 
    password: root
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT
    driver-class-name: com.mysql.jdbc.Driver

3、写mapper接口

@Mapper
@Repository
public interface StudentMapper {
     

}

@Mapper注解:
在springboot中,由于添加了mybatis的starter,此时mybatis的自动配置会生效,mybatis的自动配置里会扫描springboot的有效包路径下的带有@Mapper注解的接口,然后根据里面的mybatis注解生成mapper代理类。代替了老式的xml映射。

@Repository注解就不多了吧: @Repository、@Service、@Controller
@Component 将类标识为Bean。

4、 写mapper.xml


DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qzh.mapper.StudentMapper">
		这里写SQL
mapper>

mapper namespace标签中和咱们刚刚写好的mapper接口映射上,才可以关联上mapper接口和mapper.xml。

4、 在yaml做mybatis的相关配置

#mybatis的相关配置
mybatis:
  #mapper配置文件
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.qzh.pojo
  #开启驼峰命名
  configuration:
    map-underscore-to-camel-case: true

mybatis.mapper-locations是让springboot自动加载mapper目录下的所有xml文件。
mybatis.type-aliases-package是给pojo起别名,这样我们在xml中编写SQL返回pojo时,就可不写全名。
mybatis.configuration.map-underscore-to-camel-case = true是开启驼峰命名,比如student中有一个属性是deptId,可以自动匹配mysql中的dept_id列。

5、 编写一个查询sql

studentMapper.xml


DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qzh.mapper.StudentMapper">
    <select id="getStudentById" resultType="Student">
        select * from student where id = #{id}
    select>
mapper>

StudentMapper.java

@Mapper
@Repository
public interface StudentMapper {
     
    Student getStudentById(Integer id);
}

Test

@SpringBootTest
class MybatisApplicationTests {
     

    @Autowired
    StudentMapper studentMapper;
    @Test
    void contextLoads() throws SQLException {
     
        System.out.println(studentMapper.getStudentById(3));
    }
}

结果:Student(id=3, name=赵四, deptId=2)

**补充:**在这例子中我们用#{ }的形式对sql进行了条件拼接,但我们还知道有一种${ }的形式,二者有什么区别呢?

#{ }和${ }的的区别:

  1. #{ }预编译处理,对数据加一对儿双引号,在代替PreparedStatement中的“?”。
  2. ${ }是字符串替换,直接换掉了占位符,是不安全的,会引发SQL注入。

这样我们的springboot整合mybatis编写的第一个查询SQL就执行成功啦!

这里理应编写一套增删查改的demo,但是过于基础,我这里就不做重复了,下面我们学习一下mybatis的进阶。

2、Mybatis的映射

使用背景:

一般地,我们在数据库中查询出来的结果,通过设置resultType属性,mybatis可以帮助我们封装成我们想要的实体(前提是这个pojo中有对应数据项)。但若是pojo中的数据名和mysql中的列名不匹配怎么办呢?
所以mybatis中最牛逼的功能resultMap登场了!

resultMap ----- 自定义映射。

情况一:pojo数据名和数据库列名不对应。

Student.java

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
     

    private Integer id;
    private String name;
    private Integer XXXX;//这里我们强行把这个成员名改成XXXX
}

这里我们强行把这个成员名改成“XXXX”,但是在mysql中是dept_id,所以即便是开启驼峰命名,也是映射不上的!


DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qzh.mapper.StudentMapper">
    <resultMap id="StudentResultMap" type="Student">
        <result column="dept_id" property="XXXX"/>
    resultMap>
    <select id="getStudentById" resultMap="StudentResultMap">
        select * from student where id = #{id}
    select>
mapper>

可以看到,使用标签自定义了映射关系,将mysql中的dept_id列映射到Student类中的XXXX属性。而其他正常们可以被映射的数据,则不需要在中重申。
传入id参数为3,通过执行SQL,结果:Student(id=3, name=赵四, XXXX=2)
大吉大利,映射成功了!
值得注意的是:resultMap 和resultType在SQL标签中只能存在一个!

情况二:给pojo中的对象成员映射(一对一)

如果我们要查找全部学生所在学院的名称name,显然学生表和学院表通过学生id关联,但学院name并不是student实体的属性,所以要把学院对象作为学生的属性。

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
     

    private Integer id;
    private String name;
    private Integer deptId;
    private Dept dept; //学院信息
}

下面演示怎么给Student.Dept 映射:


DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qzh.mapper.StudentMapper">

    <resultMap id="StudentresultMap" type="Student">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <association property="dept" javaType="Dept">
            <id column="deptId" property="id"/>
            <result column="deptName" property="name"/>
            <result column="des" property="des"/>
        association>
    resultMap>

    <select id="getStudentsDeptInfo" resultMap="StudentresultMap">
        SELECT
            l.id,
            l.NAME,
            r.id  deptId,
            r.NAME deptName,
			r.des
        FROM
            student AS l
            LEFT JOIN dept AS r ON l.dept_id = r.id
    select>
mapper>

这里我们使用标签嵌套在中,对列名和pojo数据名以一对应,但是由于select了两种不同id(student.id和dept.id),所以要注意在SQL中起别名,不然mybatis不知道该注入哪个id。

执行SQL,结果:[Student(id=1, name=李刚, deptId=null, dept=Dept(id=1, name=计算机, des=牛比)), Student(id=2, name=二子, deptId=null, dept=Dept(id=1, name=计算机, des=牛比)), Student(id=3, name=赵四, deptId=null, dept=Dept(id=2, name=会计, des=真不戳)), Student(id=4, name=李三, deptId=null, dept=Dept(id=2, name=会计, des=真不戳)), Student(id=5, name=五哥, deptId=null, dept=Dept(id=2, name=会计, des=真不戳))]

由此可见,Student.Dept对象成员通过映射成功!
补充一种简便写法:
使用外部定义的形式,在标签引用外部定义的。可以简化代码,避免太长看不懂。


<resultMap id="DeptResult" type="Dept">
    <id column="deptId" property="id"/>
    <result column="deptName" property="name"/>
    <result column="des" property="des"/>
resultMap>

<resultMap id="StudentresultMap" type="Student">
    <id column="id" property="id"/>
    <result column="name" property="name"/>
    
    <association property="dept" resultMap="DeptResult"/>
resultMap>

情况三:给pojo中的集合映射(一对多)

什么是一对多?
假设有两张表:
班级表属性:id,name…
学生表属性:id , name , classId…
我们现在查询一个班级的id和name,还有此班的全部学生信息。
一个班级对应多个学生,这就是一对多。
很明显,在clazz.java中一定会有一个泛型是Student的List,如何给这个List泛型呢?

使用标签:

与上面学习的标签的用法一样,自定义一个外部的,然后再标签中引用外部的即可!

例子我就不举了,看到这里你一定明白,
其实就是一个,区别是可以定义不同的映射关系。

继续更新ING。。。

你可能感兴趣的:(javaweb,java,spring,boot,restful)