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

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

🍎一.MyBatis多表查询


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


<作者表 userinfo>:

2cd0e74e88ad4b7f949119faa7bf948d.png

<文章表 articleinfo>:


19efa76218e04d9390394556e66b8f87.png

在项目中创建的对象:

17b0a8e289ec4e3f9cfbed16909e3893.png


f2a4be14eca643daa99e21c85b40f567.png


在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接口方法:

image.png


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

ArticleMapper.xml 配置信息:


47ee459bdd5b450ba35cf5d717c2f165.png


UserMapper.xml 配置信息:

image.png


配置文件多表查询语句


这是我们在MySQL进行多表一对一查询执行语句

我们发现这两个表都有一个相同的id名称属性,这会使在查询时前面id的值会将后面id的值进行覆盖,

所有我们需要将对被联合查询表进行重命名


f4f2b995b5614d5990e6e5f986853d11.png

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


在进行单元测试代码:


e180723c303c4b15a1dbf7d57d193a54.png

测试结果:

0fbfc6133cdb4d0d8b25922a4310dc53.png

c2930c1db16348f7a533c4667cdd61df.png


🍒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);
    }

单元测试结果:


abb01459c5c243118f2e13b6534f9b37.png

🍎二.动态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>

b9791e75da174b45843e8d000e633f8f.png

我们在单元测试中假设我们没有填写photo属性信息:


ef2cc148155f4207a2dc8b7dbd05be00.png

结果:


我们看到并没有实现photo属性信息填写,解决了非必要填写信息的选择语句繁琐的难题

d92524d973ed437a8530869fe736c53b.png


当我们填写photo信息时:

8945bd37510b410499800d0cc74c2386.png


868a05a60b1743c39d6d420e6fc1ff0d.png


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

测试单元代码:

1568ae406eb645a9873e7180b850e6f7.png

测试单元结果:

6e26e51281f7466c936762a0f56ed425.png

相关文章
|
SQL Java 数据库连接
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
|
SQL Java 数据库连接
MyBatis动态SQL字符串空值判断,这个细节99%的程序员都踩过坑!
本文深入探讨了MyBatis动态SQL中字符串参数判空的常见问题。通过具体案例分析,对比了`name != null and name != &#39;&#39;`与`name != null and name != &#39; &#39;`两种写法的差异,指出后者可能引发逻辑混乱。为避免此类问题,建议在后端对参数进行预处理(如trim去空格),简化MyBatis判断逻辑,提升代码健壮性与可维护性。细节决定成败,严谨处理参数判空是写出高质量代码的关键。
2027 0
|
SQL XML Java
通过MyBatis的XML配置实现灵活的动态SQL查询
总结而言,通过MyBatis的XML配置实现灵活的动态SQL查询,可以让开发者以声明式的方式构建SQL语句,既保证了SQL操作的灵活性,又简化了代码的复杂度。这种方式可以显著提高数据库操作的效率和代码的可维护性。
664 18
|
12月前
|
SQL 数据库
SQL 学习笔记 - 多表关系与多表查询
数据库多表关系包括一对多、多对多和一对一,常用外键关联。多表查询方式有隐式/显式内连接、外连接、子查询等,支持别名和条件筛选。子查询分为标量、列、行、表子查询,常用于复杂查询场景。
|
SQL Java 数据库连接
SSM相关问题-1--#{}和${}有什么区别吗?--Mybatis都有哪些动态sql?能简述一下动 态sql的执行原理吗?--Spring支持的几种bean的作用域 Scope
在MyBatis中,`#{}`是预处理占位符,可防止SQL注入,适用于大多数参数传递场景;而`${}`是直接字符串替换,不安全,仅用于动态表名、列名等特殊场景。二者在安全性、性能及使用场景上有显著区别。
552 0
|
SQL XML Java
菜鸟之路Day35一一Mybatis之XML映射与动态SQL
本文介绍了MyBatis框架中XML映射与动态SQL的使用方法,作者通过实例详细解析了XML映射文件的配置规范,包括namespace、id和resultType的设置。文章还对比了注解与XML映射的优缺点,强调复杂SQL更适合XML方式。在动态SQL部分,重点讲解了`&lt;if&gt;`、`&lt;where&gt;`、`&lt;set&gt;`、`&lt;foreach&gt;`等标签的应用场景,如条件查询、动态更新和批量删除,并通过代码示例展示了其灵活性与实用性。最后,通过`&lt;sql&gt;`和`&lt;include&gt;`实现代码复用,优化维护效率。
1412 5
|
SQL Java 数据库连接
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
|
SQL 缓存 Java
框架源码私享笔记(02)Mybatis核心框架原理 | 一条SQL透析核心组件功能特性
本文详细解构了MyBatis的工作机制,包括解析配置、创建连接、执行SQL、结果封装和关闭连接等步骤。文章还介绍了MyBatis的五大核心功能特性:支持动态SQL、缓存机制(一级和二级缓存)、插件扩展、延迟加载和SQL注解,帮助读者深入了解其高效灵活的设计理念。
|
SQL XML Java
六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性
六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性
562 0