mybatis动态sql

动态SQL所需标签:

动态 SQL 是 MyBatis 的强大特性之一,解决根据不同条件拼接 SQL 语句的不便。
可以借助功能强大的基于 OGNL 的表达式

If(常常用于字符串的非空判断)

实例代码如下:(仅供参考)

// 使用动态sql 标签  if(mapper接口方法)
List<User> queryUsersByGender(@Param("gender") String gender,@Param("username") String username);
    
<!--List<User> queryUsersBySex(String sex);-->
    <select id="queryUsersByGender" resultType="user">
        <!--select * from user where gender = #{gender} -->
        select * from user where 1 = 1
        <if test=" gender != '' and gender != null">
           and gender = #{gender}
        </if>

        <if test=" username != '' and username != null">
            and username like '%' #{username} '%'
        </if>
  </select>
/**
 * 测试动态sql 标签  if
 */
@Test
public void testQueryUsersBySex(){
    List<User> users = userDao.queryUsersByGender("男","大叔");
    for (User user : users) {
        System.out.println(user);
    }
}
choose (when, otherwise)

有时候,我们不想使用所有的条件,而只是从这些条件之中选择一个使用,Mybatis提供了choose标签

// 使用动态sql 标签 choose(mapper接口方法)
 List<User> queryUserByCondition(@Param("username") String username, @Param("address") String address,@Param("age") int age);
<!--User queryUserByCondition(String username,String address,int age);-->
    <!--使用choose标签-->
    <select id="queryUserByCondition" resultType="user">
        <!--select * from user where username like '%'#{username} '%' and address = #{address} and age &lt; #{age};-->
        select * from user where 1=1
        <choose>
            <when test="username != null and username != ''">
                and username like '%' #{username} '%'
            </when>
            <when test="address != null and address != ''">
                and address = #{address}
            </when>
            <otherwise>
                age &lt; #{age}
            </otherwise>
        </choose>
    </select>
/**
 * 测试动态sql 标签 choose  when情形是互斥的
 */
@Test
public void testQueryUserByCondition(){
    List<User> user = userDao.queryUserByCondition("花", "河南信阳", 20);
    System.out.println(user);
}
trim(where set)

where 可以去掉第一个and
set 用于动态更新语句。set标签可以用于动态包含需要更新的字段,忽略其他不更新的字段。

where

where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除

// 使用动态sql 标签 where(mapper接口方法)
List<User> queryUserByAgeAndDid(@Param("age") int age,@Param("u_did") int u_did);
<!--List<User> queryUserByAgeAndDid(@Param("age") int age,@Param("u_did") int u_did);-->
<!--测试动态sql where标签-->
<select id="queryUserByAgeAndDid" resultType="user">
<!-- select * from user where age &lt; #{age} and u_did &lt; #{u_did} -->
select * from user
<where>
   <if test="age != '' and age != null">
       age &lt; #{age}
   </if>
   <if test="u_did &lt;= 2">
      and age &lt; #{age}
   </if>
</where>
</select>
/**
* 测试动态sql 标签 where
*/
@Test
public void testQueryUserByAgeAndDid() {
// 年龄 < 20 部门id值 > 2
List<User> users = userDao.queryUserByAgeAndDid(20, 2);
for (User user : users) {
   System.out.println(user);
}
}

set

set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。

// 使用动态sql标签 set(mapper接口方法)
void updateUserByNecessary(User user);
<!--void updateUserByNecessary(User user);-->
<!--测试动态标签 set -->
<update id="updateUserByNecessary" parameterType="user">
  <!--update user set username = #{username},age = #{age},address = #{address},gender = #{gender} where id = #{id}-->
    update user
    <set>
        <if test="username != '' and username != null">username = #{username},</if>
        <if test="age &gt; 0"> age = #{age},</if>
        <if test="address != '' and address != null">address = #{address},</if>
        <if test="gender != '' and gender != null">gender = #{gender}</if>
    </set>
    <where>
        <if test="id &gt; 0">
            id = #{id}
        </if>
    </where>
</update>
/**
 * 测试动态sql标签 set
 */
@Test
public void testUpdateUserByNecessary() {
    User user = new User("马大神2",0,"","");
    user.setId(4);
    userDao.updateUserByNecessary(user);
}

sql片段

可以把多次出现的sql封装为一个片段,在使用的时候,进行引用。
sql中将重复的sql提取出来,使用时使用标签include标签引用即可,最终达到sql重用的目的。

示例如下:

select * from user
<!--把select * from user提取到sql片段中-->
<sql id = "selectUser">
    select * from user
</sql>
<!--根据性别和姓名查询用户信息-->
<select id = "findUserByGenderAndUsername" parameterType = "user" resultType = "user">
	<!--select * from user where gender = #{gender} and username like '%' #{username} '%'-->
    <include refid = "selectUser"/>  <!--相当于 select * from user -->
    <where>
        <if test = "gender != '' and gender != null">
          gender = #{gender}
        </if>
        <if test = "username != '' and username != null">
          username = #{username}
        </if>
    </where>
</select>
foreach

foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符

你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach

尤其是在构建 IN 条件语句的时候使用的,select * from user where id in(1,3,5,7);

示例如下:

<!--
使用动态标签 foreach
List<User> queryUserByIds(List<Integer> ids);
-->
<sql id="selectUser">
select * from user
</sql>
<!--list集合-->
<select id="queryUserByIds" parameterType="list" resultType="user">
<include refid="selectUser"/>
<where>
   <!-- id in(1,3,5,7,9) -->
   <foreach collection="list" item="id" open="id  in (" close=" )" separator=",">
       #{id}
   </foreach>
</where>
</select>
<!--数组-->
<select id="queryUserByIds" parameterType="java.util.Arrays" resultType="user">
<include refid="selectUser"/>
<where>
   <!-- id in(1,3,5,7,9) -->
   <foreach collection="array" item="id" open="id  in (" close=" )" separator=",">
       #{id}
   </foreach>
</where>
</select>
// 使用动态标签 foreach
List<User> queryUserByIds(List<Integer> ids);
List<User> queryUserByIds(Integer[] ids);
/**
 * 测试动态sql标签  foreach
 *
 */
@Test
public void testQueryUserByIds() {
    ArrayList<Integer> list = new ArrayList<>();
    // (1,3,11,19)
    list.add(1);
    list.add(3);
    list.add(11);
    list.add(19);
    Integer[] ids = {1, 3, 11, 19};
    //List<User> users = userDao.queryUserByIds(list);
    List<User> users = userDao.queryUserByIds(ids);
    for (User user : users) {
        System.out.println(user);
    }
}

注意事项 :

  • 如果传入的是数组 collection需要使用arrays
  • 如果传入的是list集合,collection需要使用list
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值