最全面的Mybatis教程,从“开局”到“通关”(二)(中)

简介: 最全面的Mybatis教程,从“开局”到“通关”(二)(中)

十、Mybatis关联映射


以多个学生对应一个老师为例,存在:


  • 学生关联老师,多对一关系
  • 老师管理集合,一对多关系


1️⃣sql建表


  create table `teacher`(
  `id` int not null,
  `name` varchar(30) default null,
  primary key(`id`)
  ) engine=InnoDB default charset=utf8;
  insert into teacher values (1,'王老师');
  create table `student`(
  `id` int not null,
  `name` varchar(30) default null,
  `tid` int not null,
  primary key(`id`),
  key `FK_tid` (`tid`),
  constraint `FK_tid` foreign key(`tid`) references `teacher`(`id`)
  ) engine=InnoDB default charset=utf8;


2️⃣测试环境搭建


🍀(1)导入Lombok


🍀(2)新建Teacher,Student实体类


🍀(3)新建Mapper接口


🍀(4)在resources新建com->xxx->dao文件夹


🍀(5)新建xxxMapper.xml文件


🍀(6)在mybatis-config.xml中注册绑定xxxMapper.xml


🍀(7)在TeacherMapper接口中创建selectAll()方法


🍀(8)在TeacherMapper.xml中写对应的查询


🍀(9)新建测试类,在测试类中测试使用


3️⃣按照查询嵌套处理多对一


🍀实体类


Student.java:

  @Data
  @AllArgsConstructor
  @NoArgsConstructor
  public class Student {
      private int id;
      private String name;
      private Teacher teacher;
  }

Teacher.java:

 @Data
  @AllArgsConstructor
  @NoArgsConstructor
  public class Teacher {
      private int id;
      private String name;
  }

🍀Mapper接口


List<Student> selectAll();


🍀xxxMapper.xml

  <!-- 
      查询思路:
      1.查询所有学生
      2.根据查询出的学生的tid查询老师,子查询
   -->
  <resultMap id="student_teacher" type="Student">
  <!-- property是实体类的属性 column是数据库的字段 -->
      <result property="id" column="id"/>
      <result property="name" column="name"/>
      <!--
          复杂的属性,需要单独处理,对象:association 集合collection
       -->
      <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
  </resultMap>
  <select id="selectAll" resultMap="student_teacher">
      select * from mybatis.student
  </select>
  <select id="getTeacher" resultType="Teacher">
      select * from mybatis.teacher where id=#{tid}
  </select>


🍀测试

  @Test
  public void selectAll(){
      SqlSession sqlSession = MybatisUtils.getSqlSession();
      StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
      List<Student> studentList = mapper.selectAll();
      for (Student s:
           studentList) {
          System.out.println(s);
      }
      sqlSession.close();
  }

4️⃣按照结果嵌套处理多对一


🍀Mapper接口


List<Student> selectAll2();


🍀xxxMapper.xml

<select id="selectAll2" resultMap="S_T">
      select s.id sid,s.name sname,t.name tname
      from mybatis.student s,mybatis.teacher t
      where s.tid=t.id
</select>
<resultMap id="S_T" type="Student">
      <result property="id" column="sid"/>
      <result property="name" column="sname"/>
      <association property="teacher" javaType="Teacher">
          <result property="name" column="tname"/>
      </association>
</resultMap>

🍀测试

 @Test
  public void selectAll(){
      SqlSession sqlSession = MybatisUtils.getSqlSession();
      StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
      List<Student> studentList = mapper.selectAll();
      for (Student s:
           studentList) {
          System.out.println(s);
      }
      sqlSession.close();
  }

5️⃣一对多关系的处理


🍀实体类

Student.java:

  @Data
  @AllArgsConstructor
  @NoArgsConstructor
  public class Student {
      private int id;
      private String name;
      private int tid;
  }

Teacher.java:

  @Data
  @AllArgsConstructor
  @NoArgsConstructor
  public class Teacher {
      private int id;
      private String name;
      //老师拥有多个学生
      private List<Student> students;
  }

🍀Mapper接口

public interface TeacherMapper {
      List<Teacher> selectAll();
      //获取指定老师下的所有学生
      Teacher getTeacher(@Param("tid")int id);
      Teacher getTeacher2(@Param("tid")int id);
      List<Student> getStudents(@Param("tid")int id);
  }


🍀xxxMapper.xml

   <select id="selectAll" resultType="Teacher">
      select * from mybatis.teacher
  </select>
  <select id="getTeacher" resultMap="S_T">
      select t.id tid, t.name tname,s.name sname
      from mybatis.teacher t,mybatis.student s
      where s.tid=tid and tid=#{tid}
  </select>
  <resultMap id="S_T" type="Teacher">
      <result property="id" column="tid"/>
      <result property="name" column="tname"/>
      <!-- 集合中的泛型信息,我们使用ofType -->
      <collection property="students" ofType="Student">
          <result property="name" column="sname"/>
          <result property="tid" column="tid"/>
      </collection>
  </resultMap>
  <select id="getTeacher2" resultMap="student_teacher">
      select * from mybatis.teacher where id=#{tid}
  </select>
  <resultMap id="student_teacher" type="Teacher">
      <result property="id" column="id"/>
      <result property="name" column="name"/>
      <collection property="students" column="id" ofType="Student" select="getStudents"/>
  </resultMap>
  <select id="getStudents" resultType="Student">
      select * from mybatis.student where tid=#{tid}
  </select>

🍀测试

 @Test
  public void selectAll(){
      SqlSession sqlSession = MybatisUtils.getSqlSession();
      StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
      List<Student> studentList = mapper.selectAll();
      for (Student s:
           studentList) {
          System.out.println(s);
      }
      sqlSession.close();
  }

十一、Mybatis动态SQL


1️⃣动态SQL概述


MyBatis提供了对SQL语句动态的组装能力,大量的判断都可以在 MyBatis的映射XML文件里面配置,以达到许多我们需要大量代码才能实现的功能,大大减少了我们编写代码的工作量。


动态SQL的元素:


元素 作用 备注
if 判断语句 单条件分支判断
choose、when、otherwise 相当于Java中的 case when语句 多条件分支判断
trim、where、set 辅助元素 用于处理一些SQL拼装问题
foreach 循环语句 在in语句等列举条件常用


2️⃣if元素


if元素相当于Java中的if语句,它常常与test属性联合使用。现在我们要根据name去查找学生,但是name是可选的,如下所示:

<select id="findUserById" resultType="com.wang.entity.User">
    select id,username,password from user
    where 1 =1
    <if test="id != null">
        AND id = #{id}
    </if>
    <if test="username != null and username != ''">
        AND username = #{username}
    </if>
    <if test="password != null and password != ''">
        AND password = #{password}
    </if>
</select>

3️⃣where元素


上面的select语句我们加了一个1=1的绝对true的语句,目的是为了防止语句错误,变成SELECT * FROM student WHERE这样where后没有内容的错误语句。这样会有点奇怪,此时可以使用 < where> 元素。

<select id="findUserById" resultType="com.wang.entity.User">
    select id,username,password from user
    <where>
        <if test="id != null">
            AND id = #{id}
        </if>
        <if test="username != null and username != ''">
            AND username = #{username}
        </if>
        <if test="password != null and password != ''">
            AND password = #{password}
        </if>
    </where>
</select>

4️⃣trim元素


有时候我们要去掉一些特殊的SQL语法,比如常见的and、or,此时可以使用trim元素。trim元素意味着我们需要去掉一些特殊的字符串,prefix代表的是语句的前缀,而prefixOverrides代表的是你需要去掉的那种字符串,suffix表示语句的后缀,suffixOverrides代表去掉的后缀字符串。


<select id="select" resultType="com.wang.entity.User">
    SELECT * FROM user
    <trim prefix="WHERE" prefixOverrides="AND">
        <if test="username != null and username != ''">
            AND username LIKE concat('%', #{username}, '%')
        </if>
        <if test="id != null">
            AND id = #{id}
        </if>
    </trim>
</select>

5️⃣choose、when、otherwise元素


有些时候我们还需要多种条件的选择,在Java中我们可以使用switch、case、default语句,而在映射器的动态语句中可以使用choose、when、otherwise元素。

<!-- 有name的时候使用name搜索,没有的时候使用id搜索 -->
<select id="select" resultType="com.wang.entity.User">
    SELECT * FROM user
    WHERE 1=1
    <choose>
        <when test="name != null and name != ''">
            AND username LIKE concat('%', #{username}, '%')
        </when>
        <when test="id != null">
            AND id = #{id}
        </when>
    </choose>
</select>

6️⃣set元素


在update语句中,如果我们只想更新某几个字段的值,这个时候可以使用set元素配合if元素来完成。注意: set元素遇到,会自动把,去掉。


<update id="update">
    UPDATE user
    <set>
        <if test="username != null and username != ''">
            username = #{username},
        </if>
        <if test="password != null and password != ''">
            password = #{password}
        </if>
    </set>
    WHERE id = #{id}
</update>

7️⃣foreach元素


foreach元素是一个循环语句,它的作用是遍历集合,可以支持数组、List、Set接口。

<select id="select" resultType="com.wang.entity.User">
    SELECT * FROM user
    WHERE id IN
    <foreach collection="ids" open="(" close=")" separator="," item="id">
        #{id}
    </foreach>
</select>

collection配置的是传递进来的参数名称。

item配置的是循环中当前的元素。

index配置的是当前元素在集合的位置下标。

open和 close配置的是以什么符号将这些集合元素包装起来。

separator是各个元素的间隔符。


8️⃣foreach批量插入

<insert id="batchInsert" parameterType="list">
    insert into `user`( user_name, pass)
    values
    <foreach collection="users" item="user" separator=",">
        (#{user.username}, #{user.password})
    </foreach>
</insert>


9️⃣SQL片段


有时候可能某个 sql 语句我们用的特别多,为了增加代码的重用性,简化代码,我们需要将这些代码抽取出来,然后使用时直接调用。


提取SQL片段:

<sql id="if-title-author">
   <if test="title != null">
      title = #{title}
   </if>
   <if test="author != null">
      and author = #{author}
   </if>
</sql>


引用SQL片段:

<select id="queryBlogIf" parameterType="map" resultType="blog">
  select * from blog
   <where>
       <!-- 引用 sql 片段,如果refid 指定的不在本文件中,那么需要在前面加上 namespace -->
       <include refid="if-title-author"></include>
       <!-- 在这里还可以引用其他的 sql 片段 -->
   </where>
</select>


相关文章
|
24天前
|
SQL Java 数据库连接
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
MyBatis-Plus是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。本文讲解了最新版MP的使用教程,包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段等核心功能。
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
|
1月前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
1月前
|
SQL 存储 数据库
深入理解@TableField注解的使用-MybatisPlus教程
`@TableField`注解在MyBatis-Plus中是一个非常灵活和强大的工具,能够帮助开发者精细控制实体类与数据库表字段之间的映射关系。通过合理使用 `@TableField`注解,可以实现字段名称映射、自动填充、条件查询以及自定义类型处理等高级功能。这些功能在实际开发中,可以显著提高代码的可读性和维护性。如果需要进一步优化和管理你的MyBatis-Plus应用程
151 3
|
2月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
446 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
|
4月前
|
XML 缓存 Java
一文讲明Mybatis 的使用 超详细 【爆肝两万字教程】
文章提供了一份详尽的Mybatis使用教程,涵盖了Mybatis的简介、环境搭建、基本操作、配置解析、日志使用、分页、注解开发、多对一和一对多关系处理、动态SQL以及缓存机制等方面的内容,并提供了相应的代码示例和测试用例。
一文讲明Mybatis 的使用 超详细 【爆肝两万字教程】
|
4月前
|
SQL Java 数据库连接
Spring Boot联手MyBatis,打造开发利器:从入门到精通,实战教程带你飞越编程高峰!
【8月更文挑战第29天】Spring Boot与MyBatis分别是Java快速开发和持久层框架的优秀代表。本文通过整合Spring Boot与MyBatis,展示了如何在项目中添加相关依赖、配置数据源及MyBatis,并通过实战示例介绍了实体类、Mapper接口及Controller的创建过程。通过本文,你将学会如何利用这两款工具提高开发效率,实现数据的增删查改等复杂操作,为实际项目开发提供有力支持。
240 0
|
4月前
|
Java 关系型数据库 MySQL
MyBatisPlus如何根据id批量查询?Required request parameter ‘id‘ for method 解决方法是看青戈大佬MybatisPlus的教程
MyBatisPlus如何根据id批量查询?Required request parameter ‘id‘ for method 解决方法是看青戈大佬MybatisPlus的教程
|
7月前
|
XML Java 数据库连接
Mybatis-Plus学习小项目及详细教程
Mybatis-Plus学习小项目及详细教程
|
7月前
|
XML 监控 druid
【Java专题_02】springboot+mybatis+pagehelper分页插件+druid数据源详细教程
【Java专题_02】springboot+mybatis+pagehelper分页插件+druid数据源详细教程
109 0