MyBatis日常开发实用技巧汇总
技术栈: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属性最为关键,不同传入类型其值也不同:
- 单参数为List时,collection属性值为"list"
- 单参数为Array数组时,collection属性值为"array"
- 参数为Map类型时,collection属性值为Map中对应的key名称
示例演示:
- 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);
- 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);
- 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);
关键总结:
- 当Map的value为数组或List时,foreach标签中的collection属性值必须与Map的key完全匹配。数组长度判断使用array.length,List大小判断使用list.size()。
- 对传入参数进行空值校验非常重要,可在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类型字段。