mybatis核心用法实例详解
作者:lakewatcher
MyBatis核心使用详解
MyBatis 是一款使用比较广泛的ORM框架,以灵活的SQL配置、轻量高效、自定义参数映射等优势流行使用。本文将系统梳理MyBatis三大核心实操知识点:多场景参数传递方式、动态SQL条件判断语法、ResultMap包路径匹配异常解决方案。
一、MyBatis多场景参数传递详解
MyBatis支持多种参数传递方式,适配单个参数、多个普通参数、集合参数、混合类型参数等不同业务场景,不同方式的语法、适用场景和注意事项各不相同,以下是最全实操整理。
1.1 单个参数传递
适用于方法仅传入一个参数的场景,可直接通过 #{参数名} 获取参数值,需指定 parameterType 声明参数类型。
Java接口方法
// 单个字符串参数查询 public List<XXBean> getXXBeanList(String xxCode);
核心注意点
- Mapper的id必须与接口方法名完全一致;
#{}中的参数名可自定义,与方法参数对应即可;- 查询字段需与实体Bean属性名匹配,名称不一致时可通过
字段 as 属性名别名适配。
1.2 多参数索引传递(基础方式)
当接口方法传入多个普通参数时,无法使用 parameterType,可通过参数索引取值,索引从0开始依次对应方法参数顺序。
Java接口方法
// 传入两个字符串参数 public List<XXXBean> getXXXBeanList(String xxId, String xxCode);
Mapper XML配置
<select id="getXXXBeanList" resultType="XXBean">
select t.* from tableName where id = #{0} and name = #{1}
</select>优缺点
优点:写法简单、无需额外封装;缺点:可读性差,参数顺序调整后需同步修改XML索引,仅适用于参数较少的简单场景。
1.3 Map封装多参数(通用方式)
适用于多参数、参数类型不固定的场景,将所有参数封装到HashMap中,通过Map的key取值,支持任意数量、任意类型参数。
Java接口方法
public List<XXXBean> getXXXBeanList(HashMap map);
Mapper XML配置
<select id="getXXXBeanList" parameterType="hashmap" resultType="XXBean">
select 字段... from XXX where id=#{xxId} and code = #{xxCode}
</select>核心注意点
- MyBatis已内置hashmap别名,可直接使用,无需自定义配置;
- XML中
#{} 内的名称必须与Map的key完全一致; - 灵活性高,适配动态多参数查询、复杂条件筛选场景。
1.4 List集合参数(IN批量查询)
专门适配数据库 in 批量查询场景,通过 <foreach> 标签遍历List集合,拼接批量查询条件。
Java接口方法
public List<XXXBean> getXXXBeanList(List<String> list);
Mapper XML配置
<select id="getXXXBeanList" resultType="XXBean">
select 字段... from XXX where id in
<foreach item="item" index="index" collection="list" open="(" separator="," close=")">
#{item}
</foreach>
</select>标签参数说明
- collection:固定填list,对应方法传入的集合参数;
- item:遍历后单个元素的变量名;
- open/close:拼接SQL的前后括号;
- separator:元素之间的分隔符(逗号);
最终拼接SQL效果:select 字段... from XXX where id in ('1','2','3','4')
1.5 @Param注解多参数(推荐方式)
日常开发最推荐的多参数传递方式,通过 @Param 注解绑定参数名,XML中直接通过自定义名称取值,可读性强、无顺序限制。
Java接口方法
import org.apache.ibatis.annotations.Param;
// 注解绑定参数名,与XML取值一一对应
public AddrInfo getAddrInfo(@Param("corpId")int corpId, @Param("addrId")int addrId);Mapper XML配置
<select id="getAddrInfo" resultMap="com.xxx.xxx.AddrInfo">
SELECT * FROM addr__info
where addr_id=#{addrId} and corp_id=#{corpId}
</select>核心优势
无需指定 parameterType,参数名称固定,不受参数顺序影响,后续新增、删除参数无需修改XML取值逻辑,维护性极高。
1.6 混合类型参数(String+List)
当查询参数同时包含普通字符串、数字、List集合等多种类型时,selectList() 仅支持单个入参,可通过Map封装所有参数实现混合传参。
Java业务代码
// 封装混合参数
List<String> idList = new ArrayList<>();
idList.add("1");
idList.add("2");
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("list", idList); // 集合参数
paramMap.put("siteTag", "0"); // 普通字符串参数
// 调用查询方法
public List<SysWeb> getSysInfo(Map<String, Object> paramMap) {
return getSqlSession().selectList("sysweb.getSysInfo", paramMap);
}Mapper XML配置
<select id="getSysInfo" parameterType="java.util.Map" resultType="SysWeb">
select t.sysSiteId, t.siteName, t1.mzNum as siteTagNum, t1.mzName as siteTag, t.url, t.iconPath
from TD_WEB_SYSSITE t
left join TD_MZ_MZDY t1 on t1.mzNum = t.siteTag and t1.mzType = 10
WHERE t.siteTag = #{siteTag }
and t.sysSiteId not in
<foreach collection="list" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</select>二、MyBatis动态SQL条件判断语法
MyBatis动态SQL可根据参数值动态拼接查询条件,避免硬编码SQL、解决空参数拼接多余and/or的问题,核心常用标签为 <if>、<choose>,适配绝大多数条件判断场景。
2.1 if单条件判断(最常用)
用于非必选条件,参数满足条件则拼接SQL片段,不满足则不拼接,支持字符串、布尔值、数值判断。
完整语法示例
<!-- 布尔值判断:isMin为true时拼接条件 -->
<if test="isMin"> and max_num = 1</if>
<!-- 显式布尔值匹配判断 -->
<if test="boolvalue==true"> and status = 1</if>
<!-- 字符串非空、非空串判断(开发必备) -->
<if test="str!=null and str!='' "> and name like concat('%',#{str},'%')</if>判断规则说明
- 布尔类型:直接写变量名即可,
test="变量名"等价于变量为true; - 字符串类型:必须同时判断
!=null和!="",避免空字符串导致查询异常; - 支持and/or、大于、小于、不等于、in、not in等复杂逻辑判断。
2.2 choose-when-otherwise多条件互斥判断
功能等价于Java的 switch-case-default,多条件互斥,只会匹配第一个满足条件的when,所有条件不满足则执行otherwise,适用于优先级筛选场景。
完整语法示例
<choose>
<!-- 优先匹配:参数不为空则按名称查询 -->
<when test="name != null and name != ''">
and name = #{name}
</when>
<!-- 次优先级:名称为空、编号不为空则按编号查询 -->
<when test="code != null and code != ''">
and code = #[code]
</when>
<!-- 所有条件不满足,执行默认条件 -->
<otherwise>
and status = 1
</otherwise>
</choose>三、ResultMap找不到对应包问题解决方案
开发中常出现 resultMap type找不到实体类、别名失效、XML映射文件加载失败 问题,核心原因是实体类包未扫描、Mapper XML路径未配置,以下是MyBatis、MyBatis-Plus通用解决方案。
3.1 实体类别名自动扫描配置
通过 typeAliasesPackage 配置实体类扫描路径,配置后XML中resultMap、resultType可直接写实体类名,无需写全类名,解决找不到type对应实体的问题。
MyBatis原生配置(application.yml/application.properties)
# 单个实体包扫描 mybatis.typeAliasesPackage=com.xxxcloud.coupon.dao.entity.* # 多包扫描(逗号分隔),支持通配符匹配多级包 mybatis.typeAliasesPackage=com.xxxcloud.**.dao.entity
MyBatis-Plus配置
mybatis-plus.typeAliasesPackage = com.xxxcloud.coupon.dao.entity.*
3.2 Mapper XML文件路径配置
配置XML映射文件扫描路径,确保项目能加载到自定义Mapper XML文件,避免映射失效、SQL找不到问题。
MyBatis原生配置
mybatis.mapper-locations=classpath*:dict/*.xml
MyBatis-Plus配置
mybatis-plus.mapperLocations = classpath*:dict/*.xml
3.3 Mapper接口扫描注解
在启动类添加 @MapperScan 注解,扫描Mapper接口包,实现接口与XML文件绑定,解决接口无法注入、映射失败问题。
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
// 扫描指定Mapper接口包,支持多包扫描
@MapperScan({"cn.xxxcloud.infra.dict"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}3.4 核心报错避坑总结
- resultMap type找不到类:优先检查
typeAliasesPackage包路径是否正确、是否包含实体类; - XML文件不生效:检查
mapper-locations路径匹配规则,确保XML文件在扫描范围内; - Mapper接口无法注入:确认
@MapperScan注解包路径覆盖所有Mapper接口; - resultMap与resultType不可同时使用,二者互斥,分别适配自定义映射、自动映射场景。
四、总结
- 参数传递:单参数直接取值、多参数优先
@Param注解、集合参数用foreach、混合参数用Map封装,适配全业务场景; - 动态SQL:
if适配多可选条件、choose适配互斥条件,灵活拼接动态SQL,简化多条件查询开发; - 配置避坑:通过别名扫描、XML路径配置、Mapper接口扫描,彻底解决ResultMap映射、文件加载、接口注入等常见报错,适配MyBatis原生与MyBatis-Plus框架。
到此这篇关于mybatis核心用法的文章就介绍到这了,更多相关mybatis核心用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
