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 …...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...

USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...

佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...