MyBatis resultType 与 resultMap多表查询(association,collection)动态SQL的使用(iftrimwheresetforeach)

Posted Perceus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis resultType 与 resultMap多表查询(association,collection)动态SQL的使用(iftrimwheresetforeach)相关的知识,希望对你有一定的参考价值。

@TOC


1. resultType VS resultMap

这样我们是查不到 对应的值的,这时候我们就可以使用 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>


2. 多表查询

2.1 一对一查询 association

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


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. 单元测试代码:


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. 单元测试代码:


3. 动态 SQL

3.1 if 标签

简单语法:


举例:添加用户

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 的测试代码:


3.2 trim 标签

主要语法:


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. 单元测试代码:


3.3 where 标签

主要作用就是:

举例:根据 id 查找用户

1. mapper层:

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

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

2. XML层:

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

3. 单元测试代码:

4. 加上 and:


3.4 set 标签

主要作用就是:

举例,修改数据:

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. 测试代码:


3.5 foreach 标签

作用主要就是:

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


举例:根据多个用户 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>

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

3. 单元测试代码:


以上是关于MyBatis resultType 与 resultMap多表查询(association,collection)动态SQL的使用(iftrimwheresetforeach)的主要内容,如果未能解决你的问题,请参考以下文章

mybatis学习四 mybatis的三种查询方式

[转]MyBatis中resultType与resultMap区别

在mybatis中resultMap与resultType的区别

Mybatis中输出映射resultType与resultMap的区别

ibatis/mybatis属性三:resultMap和resultClass/resultType

mybatis中resultMap和resultType区别,三分钟读懂