mybatis----动态Sql

1.if标签

通过if标签构建动态条件,通过其test属性的true或false来判断该添加语句是否执行。

mapper接口

public interface AccountMapper {
    List<Account> selectAllByCondition(Account account);
}

映射文件

<select id="selectAllByCondition" resultMap="AccountMap">
    select *
    from account
    where 1=1
    <if test="id!=null and id!=''">
        and id=#{id}
    </if>
    <if test="accountType!=null and accountType!=''">
        and account_type=#{accountType}
    </if>
</select>

这里test中的属性名与Account类中的属性名一致。例如:上述文件的第一个if标签中的id严格与Account中属性名id一致。

测试

@Test
public void sqlTest(){
    AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class);
    Account account=new Account();
    account.setId(1);
    account.setAccountType("Checking");
    List<Account> accounts = accountMapper.selectAllByCondition(account);
    System.out.println(accounts);
}

结果:

执行效果等同于select * from account where 1=1 and id=1 and account_type="Checking"

现在修改查询的id属性值,将其赋值为空,在测试类中注释掉account.setId方法

test属性是boolean类型,通过表达式判断true,false,决定此条件是否会被执行

注意其中的1=1,这样就可以解决if标签可能会带来的sql语法错误例如:

select * from account where and id=1;

当Mapper接口传递的是@Param参数指定的形参时,if标签中的test属性名应与Param参数指定的值一致

例如接口参数修改为如下形式:

public interface AccountMapper {
    List<Account> selectAllByCondition(@Param("AccountId") int id,@Param("accountType") String accountType);
}

映射文件应修改如下(注意AccountId的修改):

<select id="selectAllByCondition" resultMap="AccountMap">
    select *
    from account
    where 1=1
    <if test="AccountId!=null and AccountId!=''">
        and id=#{AccountId}
    </if>
    <if test="accountType!=null and accountType!=''">
        and account_type=#{accountType}
    </if>
</select>

这中映射规则与#{}值的映射类似

2.where标签

where标签是对if标签的升级版,这里用where标签替代where语句,而且它还能消除条件语句中可能出现的多余sql字段,例如and,or。

映射文件修改如下:

<select id="selectAllByCondition" resultMap="AccountMap">
    select *
    from account
    <where>
    <if test="id!=null and id!=''">
        and id=#{id}
    </if>
    <if test="accountType!=null and accountType!=''">
        and account_type=#{accountType}
    </if>
    </where>
</select>

这里测试时id为null,此时where语句会自动去除if标签中属性值多余的and或者or,如果and或or在属性值后面则不会生效。

3.trim标签

使用trim标签可以添加在指定sql语句前添加删除字段

映射文件修改

<select id="selectAllByCondition" resultMap="AccountMap">
    select *
    from account
    <trim prefix="where" prefixOverrides="and">
        <if test="id!=null and id!=''">
            and id=#{id}
        </if>
        <if test="accountType!=null and accountType!=''">
            and account_type=#{accountType}
        </if>
    </trim>
</select>

测试结果

当测试id值为null时,prefixOverrides属性值的设定取出了多余的and,prefix值的设定在trim标签前添加了where。如下,trim标签还用suffix,suffixOverrides属性,与前两个属性相对,分别是在trim标签中语句后添加值,在if标签中对and或or相对属性值后的动态处理,防止sql语句出错。

4.choose标签

如下choose标签中的when,otherwise类似与if else,它只会执行其中的一个

<select id="selectAllByCondition" resultMap="AccountMap">
    select *
    from account
    where
    <choose>
        <when test="id!=null and id!=''">
            id=#{id}
        </when>
        <otherwise>
            account_type=#{accountType}
        </otherwise>
    </choose>
</select>

测试方法中只设置id属性

@Test
    public void sqlTest(){
        AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class);
        Account account=new Account();
        account.setId(2);
//        account.setAccountType("Checking");
        List<Account> accounts = accountMapper.selectAllByCondition(account);
        System.out.println(accounts);
    }

结果:

再将id属性设置注释掉,测试

它只会执行其中一个条件,而且一定会执行其中一个。

5.foreach标签

foreach标签是针对于集合,列表的类似与for循环

范围查询:

接口方法:

List<Account> selectByIds(@Param("ids") int [] s);

映射文件

<select id="selectByIds" resultMap="AccountMap">
    select * from account where id in(1,2);
</select>

测试

@Test
public void sqlTest2(){
    AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class);
    int [] ids={1,2};
    List<Account> accounts = accountMapper.selectByIds(ids);
    System.out.println(accounts);
}

修改xml,使用foreach标签

<select id="selectByIds" resultMap="AccountMap">
    select * from account where id in(
    <foreach collection="ids" item="id" separator=",">
        id
    </foreach><!--遍历ids数组,将生成的id以,隔开--> 
    );
</select>

结果

相关推荐
PGCCC18 分钟前
【PGCCC】postgresql 缓存池并发设计
数据库·缓存·postgresql
哎呦没20 分钟前
SpringBoot框架下的资产管理自动化
java·spring boot·后端
小爬虫程序猿25 分钟前
如何利用Python解析API返回的数据结构?
数据结构·数据库·python
wowocpp1 小时前
查看 磁盘文件系统格式 linux ubuntu blkid ext4
linux·数据库·ubuntu
m0_571957582 小时前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
魔道不误砍柴功4 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2344 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨4 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
测开小菜鸟6 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
Ai 编码助手7 小时前
MySQL中distinct与group by之间的性能进行比较
数据库·mysql