mybatis核心用法

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不可同时使用,二者互斥,分别适配自定义映射、自动映射场景。

四、总结

  1. 参数传递:单参数直接取值、多参数优先 @Param 注解、集合参数用foreach、混合参数用Map封装,适配全业务场景;

  2. 动态SQL:if 适配多可选条件、choose 适配互斥条件,灵活拼接动态SQL,简化多条件查询开发;

  3. 配置避坑:通过别名扫描、XML路径配置、Mapper接口扫描,彻底解决ResultMap映射、文件加载、接口注入等常见报错,适配MyBatis原生与MyBatis-Plus框架。

posted @ 2026-07-07 08:51  lakewatcher  阅读(0)  评论(0)    收藏  举报