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>

结果

相关推荐
xfhuangfu8 小时前
Oracle中建立到CDB和PDB的连接
数据库·oracle·rpc
小小龙学IT9 小时前
DuckDB 深度实战:用 C++ 在进程内跑一个「分析型数据库」
数据库·c++
NineData9 小时前
DTCC 2026 预告|NineData CEO& 创始人叶正盛:面向 AI Agent 的数据库 DevOps 与数据复制实践
数据库·人工智能·数据库开发·devops·ninedata·数据库技术·dtcc
J_bean9 小时前
MySQL 事务是否必须手动开启?
数据库·mysql·数据库事务·自动提交·手动提交
J_bean10 小时前
MySQL InnoDB 如何检测死锁、判定死锁、处理死锁
数据库·mysql·死锁·死锁检测·处理死锁·死锁判定
数智化管理手记10 小时前
海量数据如何沉淀有效数据资产?数据标准化治理方案如何搭建?
java·大数据·人工智能
浪子明X10 小时前
从 MongoDB 文档到关系模型:构建可重跑、可对账的数据迁移流水线
数据库·mongodb·oracle
杜子不疼.10 小时前
国产数据库撑起固井软件自主化:金仓 × 中海油服「海恒 Cemsol」落地解析
数据库
隔窗听雨眠10 小时前
GBase 8s并发控制深度解析:封锁机制、隔离级别与死锁处理全攻略
服务器·数据库·oracle
cfm_291410 小时前
SpringAI + Ollama 本地大模型
java·开发语言·人工智能·语言模型