MyBatis【多表查询与动态SQL使用】_多表动态sql

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

MyBatis【多表查询与动态SQL使用】

🍎一.MyBatis多表查询

我们在进行多表查询的时候,我们需要在数据库创建两个表(作者表,文章表)

<作者表 userinfo>:
在这里插入图片描述
<文章表 articleinfo>:
在这里插入图片描述
在项目中创建的对象:
在这里插入图片描述

在这里插入图片描述

在userinfo配置文件mybatis.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">
<!-- namepace 要设置是实现接口所在的具体包加类名 -->
<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="username"></result>
        <result column="username" property="username"></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 关联映射 适用于一对多 -->
        <collection
                property="artlist"
                resultMap="com.example.demo.mapper.ArticleMapper.BaseMap"
                columnPrefix="a_">
        </collection>

    </resultMap>
</mapper>

在aricleinfo配置文件mybatis.xml配置信息

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namepace 要设置是实现接口所在的具体包加类名 -->
<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 关联映射 适用于一对一 -->
        <association property="userInfo"
                     resultMap="com.example.demo.mapper.UserMapper.BaseMap"
                     columnPrefix="u_">
        </association>

    </resultMap>
</mapper>

🍒1.1 一对一查询

创建一个ArticleMapper接口方法:
在这里插入图片描述

创建一个ArticleMapper接口对应 aricleinfo 和 userinfo 在maybatis.xml配置文件

ArticleMapper.xml 配置信息:
在这里插入图片描述

UserMapper.xml 配置信息:
在这里插入图片描述
配置文件多表查询语句
这是我们在MySQL进行多表一对一查询执行语句

我们发现这两个表都有一个相同的id名称属性,这会使在查询时前面id的值会将后面id的值进行覆盖,
所有我们需要将对被联合查询表进行重命名
在这里插入图片描述


    <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>

在进行单元测试代码:
在这里插入图片描述
测试结果:
在这里插入图片描述

在这里插入图片描述

🍒1.2 一对多查询

UserMapper接口代码:

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

UserMapper.xml代码:

   <!-- 根据用户输入uid查询用户及用户发表的所有文章,根据用户uid-->
    <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>

单元测试代码:

   @Test
    void getUserAndArticleByUid() {
        UserInfo userInfo = userMapper.getUserAndArticleByUid(1);
        log.info("用户文章详细"+userInfo);
    }

单元测试结果:
在这里插入图片描述

🍎二.动态SQL使用

动态 sql 是Mybatis的强⼤特性之⼀能够完成不同条件下不同的 sql 拼接
可以参考官⽅⽂档官⽅⽂档

🍒2.1 if 标签使用

在注册⽤户的时候可能会有这样⼀个问题就是有必选和非必选是,当我们使用传统的SQL语句就会很繁琐,需要大量代码来实现,这时我们就可以使用动态SQL来进行筛选用户所填的非必选信息

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

在这里插入图片描述
我们在单元测试中假设我们没有填写photo属性信息:
在这里插入图片描述
结果:
我们看到并没有实现photo属性信息填写,解决了非必要填写信息的选择语句繁琐的难题
在这里插入图片描述

当我们填写photo信息时:
在这里插入图片描述

在这里插入图片描述

🍒2.2 trim 标签使用

<trim>标签结合<if>标签对多个字段都采取动态⽣成的⽅式
<trim>标签中有如下属性
● prefix表示整个语句块以prefix的值作为前缀

● suffix表示整个语句块以suffix的值作为后缀

● prefixOverrides表示整个语句块要去除掉的前缀

● suffixOverrides表示整个语句块要去除掉的后缀

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

🍒2.3 where 标签使用

where属性没有输入就默认时全局查找了

传⼊的⽤户对象根据属性做 where 条件查询⽤户对象中属性不为 null 的都为查询条件
如user.username 为 “a”则查询条件为 where username=“a”

  <!-- <where> 标签可以去除前面and标签 -->
    <select id="getUserById" resultMap="BaseMap">
           select * from userinfo
        <where>
            <if test="id != null">
                 and id=#{id}
            </if>
        </where>
    </select>

以上<where>标签也可以使⽤ <trim prefix="where" prefixOverrides="and"> 替换

🍒2.4 set 标签使用(增添)

根据传⼊的⽤户对象属性来更新⽤户数据可以使⽤<set>标签来指定动态内容

 <!-- <set>可以去除 后面的 ,标签 -->
    <update id="update2">
          update userinfo
        <set>
            <if test="username != null">
                username=#{username},
            </if>
            <if test="password != null">
                password=#{password},
            </if>
            <if test="photo != null">
                photo=#{photo},
            </if>
        </set>
        where id=#{id}
    </update>

以上<set>标签也可以使⽤ <trim prefix="set" suffixOverrides=","> 替换

🍒2.5 foreach 标签使用(集合进行遍历)

 // 删除方法{根据id删除这一条数据
    public int del2(@Param("ids") List<Integer> ids);
  <!-- collection 是数组对象名
         item   是 数组对象的子对象
         separator是每次遍历之间间隔的字符串-->
    <delete id="del2">
        delete from userinfo where id in
        <foreach collection="ids" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </delete>

测试单元代码:
在这里插入图片描述
测试单元结果:
在这里插入图片描述
在这里插入图片描述

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6