0
点赞
收藏
分享

微信扫一扫

【MyBatis】 resultType 与 resultMap、多表查询(association,collection)、动态SQL的使用(if、trim、where、set、foreach)

@TOC

1. resultType VS resultMap

在 resultType中,如果我们在实体类中的字段和mysql中的字段不匹配

image-20220814164805365

这样我们是查不到 对应的值的,这时候我们就可以使用 resultMap手动进行映射的处理

 <resultMap id="BaseMap" type="com.example.demo.model.UserInfo">
        <!-- 主键映射 -->
        <id column="id" property="id"></id>
        <!-- 普通属性映射 -->
        <result column="username" property="name"></result>
    </resultMap>

    <!-- 根据用户 id 查询用户 -->
    <select id="getUserById" resultMap="BaseMap">
        select * from userinfo where id=#{id}
    </select>

image-20220814164832560

2. 多表查询

2.1 一对一查询 association

⼀对⼀映射要使⽤ &lt;association&gt; 标签,具体实现如下(⼀篇⽂章只对应⼀个作者):

我们在建一个文章实体类:

image-20220814164856695

1. model层:

import lombok.Data;

@Data
public class ArticleInfo {
    private int id;
    private String title;
    private String content;
    private String createtime;
    private String updatetime;
    private int uid;
    private int rcount;
    private int state;
    private UserInfo userInfo;
}

多加了一个 UserInfo 类

2. mapper层:

import com.example.demo.model.ArticleInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

@Mapper
public interface ArticleMapper {
    //根据文章 id 获取文章
    public ArticleInfo getArticleById(@Param("id") Integer id);
}

3. XML层:

<?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">
<!-- namespace 要设置是实现接口的具体包名加类名 -->
<mapper namespace="com.example.demo.mapper.ArticleMapper">

    <resultMap id="BaseMap" type="com.example.demo.model.ArticleInfo">
        <id column="id" property="id"></id>
        <result column="title" property="title"></result>
        <result column="content" property="content"></result>
        <result column="createtime" property="createtime"></result>
        <result column="updatetime" property="updatetime"></result>
        <result column="uid" property="uid"></result>
        <result column="rcount" property="rcount"></result>
        <result column="state" property="state"></result>
        <association property="userInfo"
                     resultMap="com.example.demo.mapper.UserMapper.BaseMap"
                     columnPrefix="u_"></association>
    </resultMap>
    <select id="getArticleById" resultMap="BaseMap">
        select a.*,u.id u_id,u.username u_username,u.password u_password 
        from articleinfo a 
        left join userinfo u on a.uid=u.id 
        where a.id=#{id}
    </select>
</mapper>

4. 单元测试代码:

image-20220814164938360

image-20220814164948775

以上使⽤&lt;association&gt;标签,表示⼀对⼀的结果映射:

  • property 属性:指定 Article 中对应的属性,即⽤户。

  • resultMap 属性:指定关联的结果集映射,将基于该映射配置来组织⽤户数据。

  • columnPrefix 属性:绑定⼀对⼀对象时,是通过columnPrefix+association.resultMap.column 来映射结果集字段。

association.resultMap.column是指 标签中 resultMap属性,对应的结果集映射中,column字段。

注意事项:column不能省略

2.2 一对多查询 collection

跟一对一差不多,⼀对多需要使⽤&lt;collection&gt; 标签,⽤法和 &lt;association&gt;相同,

1. model层:

import lombok.Data;

import java.util.List;

/**
 * 用户实体类
 */
@Data
public class UserInfo {
    private Integer id;
    private String name;
    private String password;
    private String photo;
    private String createtime;
    private String updatetime;
    private int state;
    private List<ArticleInfo> artlist;
}

2. mapper层:

 // 查询用户及用户发表的所有文章,根据用户id
    public UserInfo getUserAndArticleByUid(@Param("uid") Integer uid);

3. XML层:

<mapper namespace="com.example.demo.mapper.UserMapper">
    <resultMap id="BaseMap" type="com.example.demo.model.UserInfo">
        <!-- 主键映射 -->
        <id column="id" property="id"></id>
        <!-- 普通属性映射 -->
        <result column="username" property="name"></result>
        <result column="password" property="password"></result>
        <result column="photo" property="photo"></result>
        <result column="createtime" property="createtime"></result>
        <result column="updatetime" property="updatetime"></result>
        <result column="state" property="state"></result>
        <collection property="artlist"
                    resultMap="com.example.demo.mapper.ArticleMapper.BaseMap"
                    columnPrefix="a_">
        </collection>
    </resultMap>

    <select id="getUserAndArticleByUid" resultMap="BaseMap">
        select u.*,a.id a_id,a.title a_title,a.content a_content,
               a.createtime a_createtime,
               a.updatetime a_updatetime from userinfo u left join articleinfo a
                                                                   on u.id=a.uid where u.id=#{uid}
    </select>

4. 单元测试代码:

image-20220814165225608

image-20220814165247237

3. 动态 SQL

3.1 if 标签

判断一个参数是否有值的,如果没值,那么就会隐藏 if 中 的 SQL
就像我们在填写一些注册信息的时候,有些项可以填也可以不填,有些就是必须要填.

简单语法:

image-20220814165401208

举例:添加用户

1. mapper层:

// 添加用户,添加用户时 photo是非必传参数
    public int add2(UserInfo userInfo);

2. XML:

 <!-- 添加用户,添加用户时 photo是非必传参数 -->
    <insert id="add2">
        insert into userinfo(username,password
        <if test="photo!=null">
            ,photo
        </if>
        ) values(#{name},#{password}
        <if test="photo!=null">
            ,#{photo}
        </if>
        )
    </insert>

3. 不加 photo 的测试代码:

image-20220814165452850

3.2 trim 标签

最主要的作用就是:

去除 SQL 语句前后多余的某个字符,向我们经常会在最后添加的值多加一个逗号啥的

主要语法:

image-20220814165605798

image-20220814165656931

1. mapper层:

// 添加用户,其中 username、password、photo 都是非必传参数,
    // 但至少会传递一个参数
    public int add3(UserInfo userInfo);

2. XML层:

<insert id="add3">
        insert into userinfo
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="name!=null">
                username,
            </if>
            <if test="password!=null">
                password,
            </if>
            <if test="photo!=null">
                photo
            </if>
        </trim>
        values
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="name!=null">
                #{name},
            </if>
            <if test="password!=null">
                #{password},
            </if>
            <if test="photo!=null">
                #{photo}
            </if>
        </trim>
    </insert>

3. 单元测试代码:

image-20220814165751509

3.3 where 标签

主要作用就是:

实现查询中的 where sql 替换的,他可以实现如果没有任何的查询条件,那么他可以因此查询中的 where sql,但是如果存在查询条件,那么会生成 where 的 sql 查询,并且使用 where 标签可以自动的去除最前面一个 and 字符

举例:根据 id 查找用户

1. mapper层:

// 根据用户 id 查询用户
    public UserInfo getUserById(@Param("id") Integer id);
12

注意:这里只返回一个,我就把数据库保留了一份

image-20220814165854820

2. XML层:

<!-- 根据 id 查询用户 -->
    <select id="getUserById" resultMap="BaseMap">
        select * from userinfo
        <where>
            <if test="id!=null">
                id=#{id}
            </if>
        </where>
    </select>

3. 单元测试代码:

image-20220814170002907

4. 加上 and:

image-20220814170038709

image-20220814170048943

image-20220814170054740

注意: and 在前面不能在后面

image-20220814170117091

image-20220814170125825

3.4 set 标签

主要作用就是:

进行修改操作时, 配合 if 来处理非必传输的,它的特点就是会自动去除最后一个英文逗号

举例,修改数据:

1. mapper层:

int update2(UserInfo userInfo);

2. XML层:

<update id="update2">
        update userinfo
        <set>
            <if test="name!=null">
                username=#{name},
            </if>
            <if test="password!=null">
                password=#{password},
            </if>
            <if test="photo!=null">
                photo=#{photo}
            </if>
        </set>
        where id=#{id}
    </update>

3. 测试代码:

image-20220814170320303

image-20220814170337109

image-20220814170346618

image-20220814170356993

3.5 foreach 标签

作用主要就是:

对集合进行循环遍历

&lt;foreach&gt;标签有如下属性:

  • collection:绑定⽅法参数中的集合,如 List,Set,Map或数组对象
  • item:遍历时的每⼀个对象
  • open:语句块开头的字符串
  • close:语句块结束的字符串
  • separator:每次遍历之间间隔的字符串

举例:根据多个用户 id 删除用户:

1. mapper层:

int delIds(List<Integer> ids);

2. XML层:

 <delete id="delIds">
        delete from userinfo where id in
        <foreach collection="ids" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </delete>

方便观察,我们可以加几条数据:

image-20220814170515513

3. 单元测试代码:

image-20220814170528631

image-20220814170541825

image-20220814170554059

举报

相关推荐

0 条评论