MyBatis的if标签的基本使用
在MyBatis框架中,if标签用于在构建SQL语句时,根据参数条件判断的结果,动态地选择加入或不加where条件中。
一 常见使用
在使用MyBatis处理查询逻辑的时候,常用的是判断一些参数是否为空,列举常用的几种情况展示
1.1 数据准备
1.1.1 创建表模型
CREATE TABLE `approval_info` (`id` BIGINT NOT NULL AUTO_INCREMENT,`info_name` VARCHAR(128) DEFAULT NULL,`info_type` VARCHAR(32) DEFAULT NULL,`info_size` VARCHAR(32) DEFAULT NULL,`approval_time` DATETIME DEFAULT NULL,`create_time` DATETIME DEFAULT NULL,PRIMARY KEY (`id`)
)
1.1.2 创建实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ApprovalInfo {private Long id;private String infoName;private String infoType;private String infoSize;private Date approvalTime;private Date createTime;
}
1.1.3 创建mapper层
public interface ApprovalInfoMapper {}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mango.mapper.ApprovalInfoMapper"></mapper>
1.1.4 插入测试数据
@Test
public void insertBatchObject() {List<ApprovalInfo> approvalInfoList = new ArrayList<>();// 使用工具类往集合中添加数据Collections.addAll(approvalInfoList, new ApprovalInfo(null, "cultureProjectOne", "culture", "A", assembleDate("2023-12-05 10:10:10"), assembleDate("2023-11-15 08:08:10")),new ApprovalInfo(null, "tourismProjectOne", "tourism", "A", assembleDate("2023-12-06 09:10:11"), assembleDate("2023-11-19 15:13:11")),new ApprovalInfo(null, "gameProjectOne", "game", "A", assembleDate("2023-12-08 17:10:13"), assembleDate("2023-11-21 01:03:16")),new ApprovalInfo(null, "cultureProjectTwo", "culture", "B", assembleDate("2023-12-11 01:07:15"), assembleDate("2023-11-25 20:23:40")),new ApprovalInfo(null, "cultureProjectThree", "culture", "B", assembleDate("2023-12-17 07:12:07"), assembleDate("2023-12-29 13:41:11")),new ApprovalInfo(null, "tourismProjectTwo", "tourism", "C", assembleDate("2023-12-21 13:01:19"), assembleDate("2023-12-01 11:31:19")),new ApprovalInfo(null, "gameProjectTwo", "game", "C", assembleDate("2023-12-25 19:13:10"), assembleDate("2023-12-03 17:51:15")),new ApprovalInfo(null, "gameProjectThree", "game", "B", assembleDate("2023-12-27 02:11:10"), assembleDate("2023-12-04 12:10:21")),new ApprovalInfo(null, "tourismProjectThree", "tourism", "B", assembleDate("2023-12-29 06:19:10"), assembleDate("2023-12-05 15:43:21")),new ApprovalInfo(null, "cultureProjectFour", "culture", "C", assembleDate("2023-12-31 01:09:10"), assembleDate("2023-12-08 20:21:37")));int effectLineNumber = approvalInfoMapper.saveBatchApprovalInfo(approvalInfoList);System.out.println("effectLineNumber is: " + effectLineNumber);
}private Date assembleDate(String strDate) {try {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");return simpleDateFormat.parse(strDate);} catch (ParseException e) {e.printStackTrace();throw new RuntimeException(e.getMessage());}
}
public interface ApprovalInfoMapper {int saveBatchApprovalInfo(@Param("approvalInfoList") List<ApprovalInfo> approvalInfoList);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mango.mapper.ApprovalInfoMapper"><insert id="saveBatchApprovalInfo">insert into approval_info(info_name, info_type, info_size, approval_time, create_time)values<foreach collection="approvalInfoList" item="approvalInfo" separator=",">(#{approvalInfo.infoName}, #{approvalInfo.infoType}, #{approvalInfo.infoSize},#{approvalInfo.approvalTime}, #{approvalInfo.createTime})</foreach></insert>
</mapper>
表中数据如下:
1.2 mapper方法参数是String类型
mapper方法参数是String类型,如果在查询条件中infoType的值不为空,那么就加上infoType的判断条件:
@Test
public void testQueryApprovalInfosByType() {//==> Preparing: select id, info_name, info_type, info_size, approval_time, create_time from approval_info//==> Parameters://<== Total: 10// String infoType = null;// String infoType = "";//==> Preparing: select id, info_name, info_type, info_size, approval_time, create_time from approval_info WHERE info_type = ?//==> Parameters: (String)//<== Total: 0// String infoType = " ";//==> Preparing: select id, info_name, info_type, info_size, approval_time, create_time from approval_info WHERE info_type = ?//==> Parameters: culture(String)//<== Columns: id, info_name, info_type, info_size, approval_time, create_time//<== Row: 1, cultureProjectOne, culture, A, 2023-12-05 10:10:10, 2023-11-15 08:08:10//<== Row: 4, cultureProjectTwo, culture, B, 2023-12-11 01:07:15, 2023-11-25 20:23:40//<== Row: 5, cultureProjectThree, culture, B, 2023-12-17 07:12:07, 2023-12-29 13:41:11//<== Row: 10, cultureProjectFour, culture, C, 2023-12-31 01:09:10, 2023-12-08 20:21:37//<== Total: 4//[// ApprovalInfo(id=1, infoName=cultureProjectOne, infoType=culture, infoSize=A, approvalTime=Tue Dec 05 10:10:10 CST 2023, createTime=Wed Nov 15 08:08:10 CST 2023),// ApprovalInfo(id=4, infoName=cultureProjectTwo, infoType=culture, infoSize=B, approvalTime=Mon Dec 11 01:07:15 CST 2023, createTime=Sat Nov 25 20:23:40 CST 2023),// ApprovalInfo(id=5, infoName=cultureProjectThree, infoType=culture, infoSize=B, approvalTime=Sun Dec 17 07:12:07 CST 2023, createTime=Fri Dec 29 13:41:11 CST 2023),// ApprovalInfo(id=10, infoName=cultureProjectFour, infoType=culture, infoSize=C, approvalTime=Sun Dec 31 01:09:10 CST 2023, createTime=Fri Dec 08 20:21:37 CST 2023)// ]String infoType = "culture";List<ApprovalInfo> approvalInfoList = approvalInfoMapper.queryApprovalInfosByType(infoType);System.out.println(approvalInfoList);
}
如果infoType的值为null,那么info_type = #{infoType}就不会加入到where条件中,查询出全部的数据;
如果infoType的值为"",那么info_type = #{infoType}就不会加入到where条件中,查询出全部的数据;
如果infoType的值为" ",那么info_type = #{infoType}就会加入到where条件中,且查询出来的结果当然是空的,MyBatis不会去除空格再进行计算;
如果infoType的值为culture,那么info_type = #{infoType}就会加入到where条件中,且只查询符合条件的结果,且从数据库中查出来的顺序就是往List有序集合中依次添加的顺序;
public interface ApprovalInfoMapper {List<ApprovalInfo> queryApprovalInfosByType(@Param("infoType") String infoType);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mango.mapper.ApprovalInfoMapper"><resultMap id="approvalInfoMap" type="com.mango.domain.ApprovalInfo"><id property="id" column="id"/><result property="infoName" column="info_name"/><result property="infoType" column="info_type"/><result property="infoSize" column="info_size"/><result property="approvalTime" column="approval_time"/><result property="createTime" column="create_time"/></resultMap><select id="queryApprovalInfosByType" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="infoType != null and infoType != ''">info_type = #{infoType}</if></where></select>
</mapper>
在mapper映射文件中,要写resultMap标签用于在查询语句中,将表中的字段映射到Java对象的属性中;
在mapper映射文件中,where条件后面只有一个if标签,那么要写成<where>标签嵌套<if>标签;
mapper方法参数是String类型,那么在mapper映射文件中,就需要判断参数是否等于null,和是否等于空字符串;
1.3 mapper方法参数是Long类型
mapper方法参数是包装类Long类型或是long类型的区别;
如果在查询条件中(Long类型)id的值不为空,那么就加上id的判断条件;
@Test
public void testSelectApprovalInfoByBaseId() {// Long targetId = 5L;// long targetId = 5L;Long targetId = null;List<ApprovalInfo> approvalInfoList1 = approvalInfoMapper.queryApprovalInfoListByBaseId(targetId);List<ApprovalInfo> approvalInfoList2 = approvalInfoMapper.queryApprovalInfoListByWrapperId(targetId);System.out.println(approvalInfoList1);System.out.println(approvalInfoList2);System.out.println("集合中第一条数据: " + approvalInfoList1.get(0));System.out.println("集合中最后一条数据: " + approvalInfoList1.get(approvalInfoList1.size() - 1));
}
在服务层调用mapper层的queryApprovalInfoListByBaseId(@Param("id") long id)方法,对方法参数传值描述如下:
如果对mapper层的方法参数id传基本数据类型,可以正常使用;
如果对mapper层的方法参数id传包装类型,那么会先进行拆箱(由Long-->long),传null值会抛异常;
在服务层调用mapper层queryApprovalInfoListByWrapperId(@Param("id") Long id)方法,对方法参数传值描述如下:
如果对mapper层的方法参数id传基本数据类型,可以正常使用;
如果对mapper层的方法参数id传包装类型,可以正常使用;
小结:mapper层接口参数有动态sql条件时,最好使用包装类型,而不是基本数据类型;
public interface ApprovalInfoMapper {/*** mapper层方法参数有参与到动态sql条件, 最好使用包装类型, 而不是基本数据类型*/List<ApprovalInfo> queryApprovalInfoListByBaseId(@Param("id") long id);List<ApprovalInfo> queryApprovalInfoListByWrapperId(@Param("id") Long id);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mango.mapper.ApprovalInfoMapper"><resultMap id="approvalInfoMap" type="com.mango.domain.ApprovalInfo"><id property="id" column="id"/><result property="infoName" column="info_name"/><result property="infoType" column="info_type"/><result property="infoSize" column="info_size"/><result property="approvalTime" column="approval_time"/><result property="createTime" column="create_time"/></resultMap><select id="queryApprovalInfoListByBaseId" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="id != null">id >= #{id}</if></where></select><select id="queryApprovalInfoListByWrapperId" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="id != null">id >= #{id}</if></where></select>
</mapper>
mapper方法参数是Long类型,那么在mapper映射文件中,就只需要判断参数是否等于null;
番外篇
篇一:关于表中记录为空时,查询结果是null,譬如查询表中的最值,在mapper层的方法返回值中使用基本数据类型还是包装类型
@Test
public void testMaxIndex() {Long maxIndexWrapperType = approvalInfoMapper.getMaxIndexWrapperType();System.out.println("maxIndexWrapperType is: " + maxIndexWrapperType);long maxIndexBaseType = approvalInfoMapper.getMaxIndexBaseType();System.out.println("maxIndexBaseType is: " + maxIndexBaseType);
}
如果表中有数据,那么方法返回值使用long类型或是Long类型都可以;
如果表中没有数据,那么方法返回值使用long类型接收null值会报错,Long类型可以接收null值;
小结:如果表中记录为空,且查询结果为null,譬如mapper层获取表中字段最值时,方法返回值类型使用包装类型;
public interface ApprovalInfoMapper {/*** 获取表中字段的最值使用包装类型, long类型不能接收null值*/long getMaxIndexBaseType();Long getMaxIndexWrapperType();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mango.mapper.ApprovalInfoMapper"><select id="getMaxIndexBaseType" resultType="long">select MAX(id) from approval_info</select><select id="getMaxIndexWrapperType" resultType="java.lang.Long">select MAX(id) from approval_info</select>
</mapper>
篇二:关于表中记录为空时,查询结果是0,譬如统计表中记录的数量,在mapper层的方法返回值中使用基本数据类型还是包装类型
@Test
public void testCount() {long baseCount = approvalInfoMapper.queryCountBaseType();System.out.println("基本数据类型接收的值: " + baseCount);Long wrapperCount = approvalInfoMapper.queryCountWrapperType();System.out.println("包装数据类型接收的值: " + wrapperCount);
}
如果表中没有数据,那么方法返回值0,使用long类型或是Long类型都可以接收;
如果表中有数据,那么方法返回值10,使用long类型或是Long类型都可以接收;
小结:如果表中记录为空,且查询结果为0,譬如mapper层统计表中记录的数量,方法返回值类型使用基本数据类型和包装类型都可以;
public interface ApprovalInfoMapper {/*** 获取表中记录的数量*/long queryCountBaseType();Long queryCountWrapperType();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mango.mapper.ApprovalInfoMapper"><select id="queryCountBaseType" resultType="long">select count(*) from approval_info</select><select id="queryCountWrapperType" resultType="java.lang.Long">select count(*) from approval_info</select>
</mapper>
1.4 mapper方法参数是Date类型
mapper方法参数是包装类Date类型,如果在查询条件中date的值不为空,那么就加上date的判断条件:
@Test
public void testSelectApprovalInfoByDate() {// Date date = null;Date date = assembleDate("2023-12-03 17:51:15");List<ApprovalInfo> approvalInfoList = approvalInfoMapper.queryApprovalInfoListByDate(date);System.out.println(approvalInfoList);System.out.println("====");System.out.println(approvalInfoList.get(0));System.out.println(approvalInfoList.get(approvalInfoList.size() - 1));
}
private Date assembleDate(String strDate) {try {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");return simpleDateFormat.parse(strDate);} catch (ParseException e) {e.printStackTrace();throw new RuntimeException(e.getMessage());}
}
public interface ApprovalInfoMapper {/*** 使用date类型筛选数据*/List<ApprovalInfo> queryApprovalInfoListByDate(@Param("date") Date date);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mango.mapper.ApprovalInfoMapper"><resultMap id="approvalInfoMap" type="com.mango.domain.ApprovalInfo"><id property="id" column="id"/><result property="infoName" column="info_name"/><result property="infoType" column="info_type"/><result property="infoSize" column="info_size"/><result property="approvalTime" column="approval_time"/><result property="createTime" column="create_time"/></resultMap><!-- 方式一 --><select id="queryApprovalInfoListByDate" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="date != null">create_time >= #{date}</if></where></select><!-- 方式二 --><select id="queryApprovalInfoListByDate" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="date != null">create_time >= #{date}</if></where></select><!-- 方式三 --><select id="queryApprovalInfoListByDate" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="date != null">create_time <![CDATA[>=]]> #{date}</if></where></select>
</mapper>
mapper方法参数是Date类型,那么在mapper映射文件中,就只需要判断参数是否等于null;
1.5 小结
如果MyBatis的mapper层方法参数是String类型,那么在mapper映射文件需要判断参数不等于null,和不等于空字符串;
如果MyBatis的mapper层方法参数是Long类型等基本数据类型对应的包装类型,那么在mapper映射文件只需要判断参数不等于null;
如果MyBatis的mapper层方法参数是Date类型,那么在mapper映射文件只需要判断参数不等于null;
在MyBatis表示关系运算符的方式有如下三种:
方式一,可以使用>关系运算符和>=关系运算符,不可以使用<关系运算符或<=关系运算符;
方式二,可以将关系运算符进行转义,使用&开头,和使用;结尾的方式
< | < |
<= | <= |
> | > |
>= | >= |
& | & |
' | ' |
" | " |
方式三,可以使用<![CDATA[ ]]>嵌套关系运算符,<![CDATA[>]]>,<![CDATA[>=]]>,<![CDATA[<]]>,和<![CDATA[<=]]>
二 其他使用
2.1 if标签指定的单个字符
如果infoSize的值是指定字符A,那就查询指定字符A的ApprovalInfo集合,如果不是那就查询全部的ApprovalInfo集合:
@Test
public void testSelectApprovalInfoBySize() {String size = "A";List<ApprovalInfo> approvalInfoList = approvalInfoMapper.queryApprovalInfoListBySize(size);System.out.println(approvalInfoList);
}
public interface ApprovalInfoMapper {/*** 当参数值是单字符时, 对应着的动态sql标签的判断条件如何处理*/List<ApprovalInfo> queryApprovalInfoListBySize(@Param("size") String size);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mango.mapper.ApprovalInfoMapper"><resultMap id="approvalInfoMap" type="com.mango.domain.ApprovalInfo"><id property="id" column="id"/><result property="infoName" column="info_name"/><result property="infoType" column="info_type"/><result property="infoSize" column="info_size"/><result property="approvalTime" column="approval_time"/><result property="createTime" column="create_time"/></resultMap><select id="queryApprovalInfoListBySize" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="size = 'A'">info_size = #{size}</if></where></select>
</mapper>
2.2 if标签指定的多个字符
如果infoType的值是指定的字符串culture,那就查询指定的字符串culture的ApprovalInfo集合,如果不是那就查询全部的ApprovalInfo集合:
@Test
public void testSelectApprovalInfoByType() {//==> Preparing: select id, info_name, info_type, info_size, approval_time, create_time from approval_info//==> Parameters://<== Total: 10// String type = null;// String type = "culture12306";//==> Preparing: select id, info_name, info_type, info_size, approval_time, create_time from approval_info WHERE info_type = ?//==> Parameters: culture(String)//<== Total: 4String type = "culture";List<ApprovalInfo> approvalInfoList = approvalInfoMapper.queryApprovalInfoListByType(type);System.out.println(approvalInfoList);System.out.println("====");System.out.println(approvalInfoList.get(0));System.out.println(approvalInfoList.get(approvalInfoList.size() - 1));
}
public interface ApprovalInfoMapper {/*** 当参数值是多字符时, 对应着的动态sql标签的判断条件如何处理* mapper接口中的方法参数, 只是用于mapper映射文件中的条件判断和组装sql字段值, 不一定要和表中字段名保持一致*/List<ApprovalInfo> queryApprovalInfoListByType(@Param("infoType") String infoType);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mango.mapper.ApprovalInfoMapper"><resultMap id="approvalInfoMap" type="com.mango.domain.ApprovalInfo"><id property="id" column="id"/><result property="infoName" column="info_name"/><result property="infoType" column="info_type"/><result property="infoSize" column="info_size"/><result property="approvalTime" column="approval_time"/><result property="createTime" column="create_time"/></resultMap><!-- 方式一 --><select id="queryApprovalInfoListByType" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="infoType == 'culture'">info_type = #{infoType}</if></where></select><!-- 方式二 --><select id="queryApprovalInfoListByType" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test='infoType == "culture"'>info_type = #{infoType}</if></where></select>
</mapper>
在mapper映射文件中,判断方法参数是否等于指定的值,使用<if>标签的test属性值可以写如下两种书写的格式:
<if test=" infoType == 'culture' ">,双引号和单引号配合着使用;
<if test=' infoType == "culture" '>,单引号和双引号配合着使用;
2.3 if标签指定的数字
如果id的值是指定长整型5,那就查询infoType是culture的ApprovalInfo集合;
如果id的值是指定长整型7,那就查询infoType是tourism的ApprovalInfo集合;
@Test
public void testQueryApprovalInfoListById() {// Long id = 5L;// Long id = 6L;Long id = 7L;String type = assembleMapData().get(id);List<ApprovalInfo> approvalInfoList = approvalInfoMapper.queryApprovalInfoListById(id, type);System.out.println(approvalInfoList);
}
private Map<Long, String> assembleMapData() {Map<Long, String> map = new HashMap<>();map.put(5L, "culture");map.put(7L, "tourism");return map;
}
public interface ApprovalInfoMapper {/*** 当参数值是数字时, 对应着的动态sql标签的判断条件如何处理*/List<ApprovalInfo> queryApprovalInfoListById(@Param("id") Long id, @Param("infoType") String infoType);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mango.mapper.ApprovalInfoMapper"><resultMap id="approvalInfoMap" type="com.mango.domain.ApprovalInfo"><id property="id" column="id"/><result property="infoName" column="info_name"/><result property="infoType" column="info_type"/><result property="infoSize" column="info_size"/><result property="approvalTime" column="approval_time"/><result property="createTime" column="create_time"/></resultMap><!-- 方式一 --><select id="queryApprovalInfoListById" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="id == 5">and info_type = #{infoType}</if><if test="id == 7">and info_type = #{infoType}</if></where></select><!-- 方式二 --><select id="queryApprovalInfoListById" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test='id == 5'>and info_type = #{infoType}</if><if test='id == 7'>and info_type = #{infoType}</if></where></select>
</mapper>
2.4 if标签的test属性介绍
在MyBatis中,<if>标签的test属性值用于设置条件判断:
如果test属性值为true,那么if标签的条件会加到where中,
如果test属性值为false,那么if标签的条件不会加到where中,
<if>标签的test属性值的条件判断的内容可以写基本数据类型,字符串常量,关系表达式和引用类型对象;
@Test
public void testSelectApprovalInfoByType() {String type = "culture";List<ApprovalInfo> approvalInfoList = approvalInfoMapper.queryApprovalInfoListByType(type);System.out.println(approvalInfoList);
}
public interface ApprovalInfoMapper {List<ApprovalInfo> queryApprovalInfoListByType(@Param("infoType") String infoType);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mango.mapper.ApprovalInfoMapper"><resultMap id="approvalInfoMap" type="com.mango.domain.ApprovalInfo"><id property="id" column="id"/><result property="infoName" column="info_name"/><result property="infoType" column="info_type"/><result property="infoSize" column="info_size"/><result property="approvalTime" column="approval_time"/><result property="createTime" column="create_time"/></resultMap><!-- 方式一: boolean类型 --><select id="queryApprovalInfoListByType" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="true">info_type = #{infoType}</if></where></select><!-- 方式二: 数字(byte short int long float double)类型, 0为false, 非0(哪怕是0.0)为true --><select id="queryApprovalInfoListByType" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="1">info_type = #{infoType}</if></where></select><!-- 方式三: char类型, 任意char类型都表示为true --><select id="queryApprovalInfoListByType" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="'a'">info_type = #{infoType}</if></where></select><!--单引号+单字符会解析成char类型;双引号+单字符会解析成String类型;单引号+多字符会解析成String类型;多引号+多字符会解析成String类型;--><!-- 方式四: String类型, String类型都表示为true --><select id="queryApprovalInfoListByType" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="'abc'">info_type = #{infoType}</if></where></select><select id="queryApprovalInfoListByType" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test='"abc"'>info_type = #{infoType}</if></where></select><!-- 方式五: 关系表达式, 相等表达式 --><select id="queryApprovalInfoListByType" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="'abc'=='abc'">info_type = #{infoType}</if></where></select><!-- 方式六: 关系表达式, 不相等表达式 --><select id="queryApprovalInfoListByType" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="'abc' != 'cba'">info_type = #{infoType}</if></where></select><!-- 方式七: 引用类型对象, infoType是String类型 --><select id="queryApprovalInfoListByType" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="infoType">info_type = #{infoType}</if></where></select><!-- 方式八: 引用类型对象, infoType用在关系表达式中 --><select id="queryApprovalInfoListByType" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="infoType == 'culture'">info_type = #{infoType}</if></where></select>
</mapper>
小结:在if标签的test属性值表达式中,引用类型对象不加引号(双引号或单引号),字符和字符串类型需要加引号(双引号或单引号);
在mapper映射文件中,if标签的标签体是表字段、运算符和值表达式,其中值表达式和if标签的test属性值表达式的内容是一致的,只不过在使用引用类型时需要使用#{}或${}给包括起来;
在mapper接口的方法中,方法参数可以自定义需要的参数,不一定非得和表中字段一样或是匹配,只要能表述清楚就可以了;
@Test
public void testSelectApprovalInfoByCustomize() {String type = "culture";String code = "en";List<ApprovalInfo> approvalInfoList = approvalInfoMapper.queryApprovalInfoListByCustomize(type, code);System.out.println(approvalInfoList);
}
public interface ApprovalInfoMapper {List<ApprovalInfo> queryApprovalInfoListByCustomize(@Param("customizeType") String customizeType, @Param("customizeCode") String customizeCode);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mango.mapper.ApprovalInfoMapper"><resultMap id="approvalInfoMap" type="com.mango.domain.ApprovalInfo"><id property="id" column="id"/><result property="infoName" column="info_name"/><result property="infoType" column="info_type"/><result property="infoSize" column="info_size"/><result property="approvalTime" column="approval_time"/><result property="createTime" column="create_time"/></resultMap><select id="queryApprovalInfoListByCustomize" resultMap="approvalInfoMap">select id, info_name, info_type, info_size, approval_time, create_timefrom approval_info<where><if test="customizeCode == 'en'">and info_type = #{customizeType}</if></where></select>
</mapper>
2.5 MyBatis中#{}常用属性
MyBatis中#{}占位符的常用属性,javaType、jdbcType、mode、numericScale、resultMap、typeHandler、jdbcTypeName、expression。
javaType属性:指定参数的Java类型;
jdbcType属性:指定参数的JDBC类型;
typeHandler属性:指定自定义的类型处理器,用于处理特定类型的参数或结果;
MyBatis在预编译(parsing)阶段会读取SQL中的字段类型,以确保预编译SQL的字段类型正确;
MyBatis在预编译(parsing)阶段由SqlSourceBuilder解析#{}参数,将#{}替换为?号(占位),并将#{}中的内容解析为ParameterMapping的封装,ParameterMapping包含了参数的各个属性,解析是除了typeHandler和javaType外其它属性都直接从配置中获取到然后设定,若未指定则为null,ParameterMapping中的typeHandler和javaType是必须要的,因为在后面通过setter方法设置参数值时,从#{}中javaType属性指定的类型信息来选择对应的setter方法进行参数设定,最后执行sql;
在执行sql时,但是有时候在执行的时会报ClassCastException,譬如表中字段是单字符就会报String cannot be cast to Integer的错误,需要手动设置参数的Java类型为:info_size = #{size, javaType=String};
相关文章:

MyBatis的if标签的基本使用
在MyBatis框架中,if标签用于在构建SQL语句时,根据参数条件判断的结果,动态地选择加入或不加where条件中。 一 常见使用 在使用MyBatis处理查询逻辑的时候,常用的是判断一些参数是否为空,列举常用的几种情况展示 1.1…...

【Azure Cache for Redis】Redis的导出页面无法配置Storage SAS时通过az cli来完成
问题描述 在Azure Redis的导出页面,突然不能配置Storage Account的SAS作为授权方式。 image.png 那么是否可以通过AZ CLI或者是Powershell来实现SAS的配置呢? 问题解答 可以的。使用 az redis export 可以实现 az redis export --container --prefix[--a…...

【微服务】Nacos
一、安装 1、官网地址:https://nacos.io/download/nacos-server/ 2、启动:找到bin目录下的startup.cmd双击启动,或者打开一个命令窗口输入: startup.cmd -m standalone双击启动后如下:可以访问控制台地址 访问后的…...
5、定义与调用函数
大家好,欢迎来到Python函数入门课程! 在编程中,函数就像一个可以重复使用的代码块,它接受输入(参数),执行特定的任务,并可能返回一个结果。想象一下,函数就像一个厨房里的搅拌机,你放入水果(参数),按下按钮(调用函数),它就会帮你制作出美味的果汁(返回值)。…...

Linux 网络编程之TCP套接字
前言 上一期我们对UDP套接字进行了介绍并实现了简单的UDP网络程序,本期我们来介绍TCP套接字,以及实现简单的TCP网络程序! 🎉目录 前言 1、TCP 套接字API详解 1.1 socket 1.2 bind 1.3 listen 1.4 accept 1.5 connect 2、…...

前海湾地铁的腾通数码大厦背后的临时免费停车点探寻
临时免费停车点:前海湾地铁的腾通数码大厦背后的桂湾大街,目前看不仅整条桂湾大街停了车,而且还有工地餐点。可能是这个区域还是半工地状态,故暂时还不会有罚单的情况出现。 中建三局腾讯数码大厦项目部A栋 广东省深圳市南山…...
OpenCV相机标定与3D重建(7)鱼眼镜头立体校正的函数stereoRectify()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::fisheye::stereoRectify 是 OpenCV 中用于鱼眼镜头立体校正的函数。该函数计算两个相机之间的校正变换,使得从两个相机拍摄的图像…...
前端如何获取unpkg的资源链接
在现代前端开发中,快速获取和使用npm包是一个常见需求。unpkg是一个全球性的CDN服务,它为npm上的每个包提供了快速访问。通过unpkg,你可以轻松地通过URL获取任何npm包的文件。本文将介绍如何获取unpkg的资源链接。 unpkg简介 unpkg是一个快…...
Flink 离线计算
文章目录 一、样例一:读 csv 文件生成 csv 文件二、样例二:读 starrocks 写 starrocks三、样例三:DataSet、Table Sql 处理后写入 StarRocks四、遇到的坑 <dependency><groupId>org.apache.flink</groupId><artifactId&…...

Git | 理解团队合作中Git分支的合并操作
合并操作 团队合作中Git分支的合并操作分支合并过程1.创建feature/A分支的过程2. 创建分支feature/A-COPY3.合并分支查看代码是否改变 团队合作中Git分支的合并操作 需求 假设团队项目中的主分支是main,团队成员A基于主分支main创建了feature/A,而我又在团队成员A创…...
C++多态的实现原理
【欢迎关注编码小哥,学习更多实用的编程方法和技巧】 1、类的继承 子类对象在创建时会首先调用父类的构造函数 父类构造函数执行结束后,执行子类的构造函数 当父类的构造函数有参数时,需要在子类的初始化列表中显式调用 Child(int i) : …...

[极客大挑战 2019]PHP--详细解析
信息搜集 想查看页面源代码,但是右键没有这个选项。 我们可以ctrlu或者在url前面加view-source:查看: 没什么有用信息。根据页面的hint,我们考虑扫一下目录看看能不能扫出一些文件. 扫到了备份文件www.zip,解压一下查看网站源代码…...

map用于leetcode
//第一种map方法 function groupAnagrams(strs) {let map new Map()for (let str of strs) {let key str ? : str.split().sort().join()if (!map.has(key)) {map.set(key, [])}map.get(key).push(str)} //此时map为Map(3) {aet > [ eat, tea, ate ],ant > [ tan,…...
CommonJS 和 ES Modules 的 区别
CommonJS 和 ES Modules 的 区别 1. CommonJS 和 ES Modules 区别?1.1 语法差异CommonJS:ES Modules: 1.2. 加载机制CommonJS:ES Modules: 1.3. 运行时行为CommonJS:ES Modules: 1.4. 兼容性和使用场景Com…...

科技为翼 助残向新 高德地图无障碍导航规划突破1.5亿次
今年12月03日是第33个国际残疾人日。在当下科技发展日新月异的时代,如何让残障人士共享科技红利、平等地参与社会生活,成为当前社会关注的热点。 中国有超过8500万残障人士,其中超过2400万为肢残人群,视力障碍残疾人数超过1700万…...

Flink四大基石之Time (时间语义) 的使用详解
目录 一、引言 二、Time 的分类及 EventTime 的重要性 Time 分类详述 EventTime 重要性凸显 三、Watermark 机制详解 核心原理 Watermark能解决什么问题,如何解决的? Watermark图解原理 举例 总结 多并行度的水印触发 Watermark代码演示 需求 代码演示ÿ…...
Spring WebFlux与Spring MVC
Spring WebFlux 是对 Spring Boot 项目中传统 Spring MVC 部分的一种替代选择,主要是为了解决现代 Web 应用在高并发和低延迟场景下的性能瓶颈。 1.WebFlux 是对 Spring MVC 的替代 架构替代: Spring MVC 使用的是基于 Servlet 规范的阻塞式模型…...

【深度学习基础】一篇入门模型评估指标(分类篇)
🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀深度学习_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2. 模…...
D80【 python 接口自动化学习】- python基础之HTTP
day80 requests请求加入headers 学习日期:20241126 学习目标:http定义及实战 -- requests请求加入headers 学习笔记: requests请求加入headers import requestsurlhttps://movie.douban.com/j/search_subjects params{"type":…...

⽂件操作详解
⽬录 一 文件操作的引入 1 为什么使⽤⽂件? 2 什么是⽂件? 3 文件分类(1 从⽂件功能的⻆度来分类:程序⽂件/数据⽂件 2根据数据的组织形式:为⽂本⽂件/⼆进制⽂件) 二 ⽂件的打开和关闭 1 …...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...

逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...

sshd代码修改banner
sshd服务连接之后会收到字符串: SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢? 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头,…...

Matlab实现任意伪彩色图像可视化显示
Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中,如何展示好看的实验结果图像非常重要!!! 1、灰度原始图像 灰度图像每个像素点只有一个数值,代表该点的亮度(或…...