当前位置:首页 > 技术 > 正文内容

MyBatis日常开发实用技巧汇总

访客 技术 2026年10月18日 1

技术栈:Spring MVC + Spring + MyBatis

开发工具:IntelliJ IDEA

数据库:MySQL

本文整理了MyBatis在实际项目开发中的常见用法,供大家参考学习。

MySQL数据库:插入数据时获取自动增长的主键值

<insert id="insertUser" useGeneratedKeys="true" keyProperty="userId" parameterType="com.example.entity.SysUser">
  insert into sys_user(username,email,status,create_date,update_date,is_deleted)
  values(#{username},#{email},#{status},#{createDate},#{updateDate},0)
</insert>

动态模糊查询与条件判断:

关键字搜索建议使用CONCAT函数拼接,避免直接使用$符号导致SQL注入风险。

MyBatis中排序字段只能使用$符号,#符号无法实现动态排序功能。

<select id="queryProductList" parameterType="java.util.Map" resultType="java.util.Map">
    select p.id,p.product_name AS productName,p.product_code,p.stock,p.price,
           c.id AS categoryId,
           c.category_name AS categoryName
    from product_info AS p
    left join product_category AS pc on p.id = pc.product_id
    left join category_info AS c on pc.category_id = c.id
    where 1=1 and p.is_deleted=0
    <if test="productName != null and productName != ''">
        and p.product_name like CONCAT('%', #{productName}, '%')
    </if>
    <if test="categoryId != null and categoryId != ''">
        and c.id = #{categoryId}
    </if>
    group by p.id
    order by p.id desc
    limit #{start}, #{pageSize}
</select>

多参数传递方式一:Map封装

XML配置:

<update id="updateUserScore" parameterType="java.util.Map">
    update user_score
    set score_value = #{score}
    where user_id = #{userId}
</update>

DAO层接口:

int updateUserScore(Map<String, Object> params);

Service层调用:

Map<String, Object> paramMap = new HashMap<>();
paramMap.put("score", 1500);
paramMap.put("userId", "U20240001");
userScoreDao.updateUserScore(paramMap);

注意:#{}中的占位符名称必须与Map的key保持一致,否则参数无法正确传递。

多参数传递方式二:@Param注解

XML配置:

<select id="getWarehouseInfo" resultMap="WarehouseResult">
    select * from warehouse_info where warehouse_id = #{warehouseId} and company_id = #{companyId}
</select>

DAO层接口:

WarehouseInfo getWarehouseInfo(@Param("companyId") int companyId, @Param("warehouseId") int warehouseId);

提示:传递多个参数时务必使用@Param注解进行命名区分,否则无法正确识别参数。

集合类型参数传递:List、Array、Map与foreach循环

foreach核心属性说明:

foreach用于在SQL语句中迭代集合元素,主要包含以下属性:item指定迭代元素的变量名,index表示迭代位置索引,collection指定要遍历的集合对象,open和close定义SQL片段的首尾符号,separator指定元素间的分隔符。其中collection属性最为关键,不同传入类型其值也不同:

  1. 单参数为List时,collection属性值为"list"
  2. 单参数为Array数组时,collection属性值为"array"
  3. 参数为Map类型时,collection属性值为Map中对应的key名称

示例演示:

  1. List类型参数传递
<select id="queryUserListByIds" resultType="User">
    select user_id, username, email, mobile
    from sys_user
    where user_id in
    <foreach collection="list" item="uid" index="idx" open="(" close=")" separator=",">
        #{uid}
    </foreach>
</select>

对应Mapper接口:

List<User> queryUserListByIds(List<String> userIdList);
  1. Array数组类型参数传递
<select id="queryRoleListByCodes" resultType="Role">
    select role_id, role_name, role_code
    from sys_role
    where role_code in
    <foreach collection="array" item="roleCode" index="i" open="(" close=")" separator=",">
        #{roleCode}
    </foreach>
</select>

对应Mapper接口:

List<Role> queryRoleListByCodes(String[] roleCodes);
  1. Map类型参数传递(Map中包含数组)
<select id="queryPermissionByMap" resultType="Permission">
    select permission_id, permission_name, permission_url
    from sys_permission
    <where>
        <if test="permissionCodes != null and permissionCodes.length > 0">
            permission_code in
            <foreach collection="permissionCodes" item="permCode" index="index" open="(" close=")" separator=",">
                #{permCode}
            </foreach>
        </if>
    </where>
</select>

对应Mapper接口:

List<Permission> queryPermissionByMap(Map<String, Object> conditions);

Map数据构建方式:

Map<String, Object> conditions = new HashMap<>();
String[] codes = new String[]{"P001", "P002", "P003", "P004"};
conditions.put("permissionCodes", codes);

关键总结:

  1. 当Map的value为数组或List时,foreach标签中的collection属性值必须与Map的key完全匹配。数组长度判断使用array.length,List大小判断使用list.size()。
  2. 对传入参数进行空值校验非常重要,可在Controller层校验,也可在XML中进行判断。对List判空示例:
<if test="goodsList != null and goodsList.size() > 0">
    <foreach collection="goodsList" item="goodsId" open="(" separator="," close=")">
        #{goodsId, jdbcType = BIGINT}
    </foreach>
</if>

对数组判空示例:

<if test="deptIds != null and deptIds.length > 0">
    <foreach collection="array" item="deptId" index="idx" open="(" close=")" separator=",">
        #{deptId}
    </foreach>
</if>

MyBatis日期Date类型格式化处理

MySQL数据库:日期格式化函数使用DATE_FORMAT

<sql id="Common_Columns">
    id, user_id, user_name, user_role,
    date_format(create_time, '%Y-%m-%d %H:%i:%s') AS createTime,
    date_format(update_time, '%Y-%m-%d %H:%i:%s') AS updateTime
</sql>

Oracle数据库:日期格式化函数使用TO_CHAR

<sql id="Common_Columns">
    ID, DEPT_ID, DEPT_NAME, MANAGER_ID,
    to_char(CREATE_DATE, 'yyyy-MM-dd HH24:mi:ss') create_date_str,
    to_char(UPDATE_DATE, 'yyyy-MM-dd HH24:mi:ss') update_date_str
</sql>

注意:若需要将日期以字符串形式返回,需在实体类中定义对应的String类型字段。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。