Mybatis动态SQL的示例

简介: 本文介绍了Mybatis动态SQL的常用标签,包括if、choose、when、otherwise、trim、where、set和foreach标签,并提供了示例代码以展示如何使用它们来动态构建SQL
动态SQL作用:根据不同条件拼接 SQL 语句。

IF 标签

IF 语句用来判断某条件是否符合。若条件符合则拼接该 SQL,例如下面这个 SQL中的<if test="name != null">的意思就是判断传入参数user这个对象中是否包含了name,如果包含name就会通过 if 判断,拼接SQL,否则,将不会拼接AND name like #{name}

<select id="findByCondition" parameterType="user" resultType="user">
  SELECT * FROM User tbl_user id = #{id}
  <if test="name != null">
    AND name like #{name}
  </if>
</select>

WHERE 标签

上述的SQL中:WHERE id = #{id},表示该id这个参数是必须要传入的,如果我们要将该条件也用 IF 包起来的话:

<select id="findByCondition" parameterType="user" resultType="user">
  SELECT * FROM tbl_user WHERE
  <if test="id != null">
      id = #{id}
  </if>
  <if test="name != null">
    AND name like #{name}
  </if>
</select>

如果两个条件都不满足了,就会变成这样的 SQL,SELECT * FROM User WHERE,导致 SQL 报错。

为解决问题,我们需要用到<WHERE>标签,
<WHERE> 元素只会在子元素返回任何内容的情况下才插入 WHERE 。这样就避免了两个条件都不满足的情况。

<select id="findByConditions" parameterType="user" resultType="user">
    SELECT * FROM tbl_user
    <where>
        <if test="id != null">
            id = #{id}
        </if>

        <if test="name != null">
            AND name like #{name}
        </if>
    </where>
</select>

这里可能出现一个疑问:若第一个条件不满足,第二个条件满足呢?SQL 语句会变成了:SELECT * FROM User WHERE AND name like #{name},这又出现了问题,我们尝试一下:

...DEBUG er.UserMapper.findByConditions  - ==>  Preparing: SELECT * FROM tbl_user WHERE name like ? 

看官网的介绍:<WHERE>  元素只会在子元素返回任何内容的情况下才插入 WHERE 。(这个我们已经知道到了) 若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。 所以,放心的使用<where>标签吧。

TRIM 标签

该标签会提供一些属性,让你去自定义一些前缀,或者屏蔽掉某些内容。
  1. prefix :在整个标签【前面】附加指定内容。
  2. suffix :在整个标签【最后】追加指定内容。
  3. prefixOverrides :去掉【标签体内第一个指定】的关键字。
  4. suffixOverrides :去掉标【签体内最后一个指定】的关键字。

我们将上面的代码重新用<trim>标签组织一下:

<where>
    <if test="id != null">
        id = #{id}
    </if>

    <if test="name != null">
        AND name like #{name}
    </if>
</where>

组织结果如下:

<trim prefix="where" prefixOverrides="AND">
    <if test="id != null">
        id = #{id}
    </if>

    <if test="name != null">
        AND name like #{name}
    </if>
</trim>

所以该标签很强大,不光可以实现<where>同样的效果,<set>也是如此。

CHOSE

条件中我只取一个,如果传过来的都不满足,那我设置一个保底。
<select id="findAdmin" parameterType="user" resultMap="user">
    select * from tbl_user
    <choose>
        <when test="id != null and id != '">
            where id = #{id};
        </when>
        <when test="name != null and name != ''">
            where name = #{name};
        </when>
        <otherwise>
          where name = '老程'
        </otherwise>
    </choose>
</select>

该SQL中只会取一个where条件,如果前面的idname都缺省了,那么就会默认查询name为'老程'的管理员。

FOREACH

如果我的参数是一个列表,就像SQL语句的 IN操作,这就需要 FOREACH标签。

举个IN的例子:

首先我们定义一个接口,设定一个方法:findAllUseForeach,它的参数是传入一个数组,名字我限定使用@Param修饰,该参数在XML文件中的别名叫ids

  • Mapper接口:
List<User> findAllUseForeach(@Param("ids") List<String> ids);

在XML文件中,用parameterType标明参数是列表类型;使用<fireach>标签遍历整个数组参数,这里我们介绍一下属性的作用:

  1. collection:放传入参数(集合/数组)的名称。
  2. item:遍历(集合/数组)中每个元素,我们取个名字,例如这里,我们叫做:id
  3. open:表示要用什么符号作为foreach标签的前缀。
  4. close:表示用什么符号作为foreach标签的后缀。
  5. separator:表示中间的#{id}是使用什么分隔符隔开。
  • XML文件:
<select id="findAllUseForeach" parameterType="list" resultType="user">
    select * from tbl_user
    where id in
    <foreach collection="ids" item="id" open="(" close=")" separator=",">
        #{id}
    </foreach>
</select>
  • 测试
@Test
public void findAllUseForeach() {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<String> list = new ArrayList<>();
    list.add("09ec5fcea620c168936deee53a9cdcfb");
    list.add("09ec5fcea620c168936deee53a9cdcff");
    List<User> allUseForeach = mapper.findAllUseForeach(list);
    for (User useForeach : allUseForeach) {
        System.out.println(useForeach);
    }
}

这里再给出一个,单条的批量修改的SQL(传入的参数是一个:类转的Map),请自行学习其中的奥秘,关键信息已用注解标注

<!--键值对的 key 是 index ,value 是 item-->
<!--${key} 是引用属性,不能用#{},不然会以?占位,这里我们需要的是name = ?-->
<update id="updateUserByMap" parameterType="map">
    update tbl_user
    <foreach collection="beanMap" index="key" item="value" open="set " separator=",">
        <if test="value != null">
            ${key} = #{value}
        </if>
    </foreach>
    where id = #{id}
</update>

它的测试语句如下:

@Test
public void updateUserByMap() {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    User user = new User();
    user.setName("老四");
    BeanMap beanMap = BeanMap.create(user);
    System.out.println(beanMap);
    // {birthday=null, name=老四, id=null, department=null, version=null, age=null}

    Map<String, Object> departmentMap = new HashMap<>(2);
    departmentMap.put("id", "09ec5fcea620c168936deee53a9cdcff");
    departmentMap.put("beanMap", beanMap);
    mapper.updateUserByMap(departmentMap);
    sqlSession.commit();
}

BIND

bind 元素允许你在 SQL 表达式以外创建一个变量,并将其绑定到当前的上下文。比如:

<!--bind类似声明一个变量-->
<select id="findAllUserUseBind" parameterType="user" resultType="user">
    <bind name="namelike" value="'%' + _parameter.getName() + '%'"/>
    select * from tbl_user
    where name like #{namelike}
</select>

通常用来简化处理模糊查询的%拼接工作。

SET

SET标签非常简单,就是<set><if>的拼接,也可以用<trim>替换相同的功能,就不展开介绍了,尝试一下是否掌握了吧~

目录
相关文章
|
5月前
|
SQL Java 测试技术
3、Mybatis-Plus 自定义sql语句
这篇文章介绍了如何在Mybatis-Plus框架中使用自定义SQL语句进行数据库操作。内容包括文档结构、编写mapper文件、mapper.xml文件的解释说明、在mapper接口中定义方法、在mapper.xml文件中实现接口方法的SQL语句,以及如何在单元测试中测试自定义的SQL语句,并展示了测试结果。
3、Mybatis-Plus 自定义sql语句
|
16天前
|
SQL XML Java
mybatis实现动态sql
MyBatis的动态SQL功能为开发人员提供了强大的工具来应对复杂的查询需求。通过使用 `<if>`、`<choose>`、`<foreach>`等标签,可以根据不同的条件动态生成SQL语句,从而提高代码的灵活性和可维护性。本文详细介绍了动态SQL的基本用法和实际应用示例,希望对您在实际项目中使用MyBatis有所帮助。
46 11
|
2月前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
2月前
|
SQL Java 数据库连接
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
|
3月前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
61 10
|
4月前
|
SQL XML Java
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
文章介绍了MyBatis中动态SQL的用法,包括if、choose、where、set和trim标签,以及foreach标签的详细使用。通过实际代码示例,展示了如何根据条件动态构建查询、更新和批量插入操作的SQL语句。
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
|
3月前
|
存储 SQL 数据库
SQL Server 临时存储过程及示例
SQL Server 临时存储过程及示例
63 3
|
5月前
|
SQL Java 数据库连接
Mybatis系列之 Error parsing SQL Mapper Configuration. Could not find resource com/zyz/mybatis/mapper/
文章讲述了在使用Mybatis时遇到的资源文件找不到的问题,并提供了通过修改Maven配置来解决资源文件编译到target目录下的方法。
Mybatis系列之 Error parsing SQL Mapper Configuration. Could not find resource com/zyz/mybatis/mapper/
|
4月前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
75 1
|
5月前
|
SQL Java 数据库连接
Mybatis系列之 动态SQL
文章详细介绍了Mybatis中的动态SQL用法,包括`<if>`、`<choose>`、`<when>`、`<otherwise>`、`<trim>`和`<foreach>`等元素的应用,并通过实际代码示例展示了如何根据不同条件动态生成SQL语句。