MyBatis 防坑全家桶
MyBatis 是一个优秀的持久层框架,但不注意细节很容易踩坑。
我把开发中最常见的 15 个坑和对应的最佳实践总结成了这份防坑全家桶,照着用,持久层更稳、更安全、更高效。
坑点对照表
|
坑点编号 |
常见坑做法 |
正确用法 |
|
1 |
直接拼接 SQL 字符串防不住注入 |
用 #{} 占位符 |
|
2 |
数据库字段与 Java 属性不一致,映射失败 |
用 resultMap 明确映射 |
|
3 |
条件查询写成一堆 if-else |
用 <where> + <if> |
|
4 |
内存分页 |
PageHelper / 数据库分页 |
|
5 |
忘记加事务注解 |
@Transactional |
|
6 |
N+1 查询 |
延迟加载 + 合理关联映射 |
|
7 |
枚举等特殊类型处理混乱 |
自定义 TypeHandler |
|
8 |
缓存导致数据不一致 |
选择性启用缓存 |
|
9 |
多表关联映射混乱 |
用 association / collection |
|
10 |
批量操作多次执行单条 SQL |
用 <foreach> 一次批量 |
|
11 |
多个条件互斥还用多个 <if> |
用 <choose> |
|
12 |
手动处理 SQL 前后 AND/OR |
用 <trim> |
|
13 |
每次都写字段映射 |
开启 mapUnderscoreToCamelCase |
|
14 |
SQL 重复写 |
<sql> 片段复用 |
|
15 |
SQL 出错不好查 |
开启 MyBatis 日志输出 |
详细用法示例
1. SQL 注入防护
<select id="getUser" resultType="User">
SELECT * FROM users WHERE id = #{id}
</select>
2. 字段与属性映射
<resultMap id="userResultMap" type="User">
<id property="userId" column="user_id"/>
<result property="userName" column="user_name"/>
</resultMap>
3. 动态 SQL 条件查询
<select id="findUsers" resultType="User">
SELECT * FROM users
<where>
<if test="name != null">AND name = #{name}</if>
<if test="age != null">AND age = #{age}</if>
</where>
</select>
4. 分页处理(数据库级)
PageHelper.startPage(1, 10);
List<User> users = userMapper.selectAll();
PageInfo<User> pageInfo = new PageInfo<>(users);
5. 事务管理
@Transactional
public void updateUser(User user) {
userMapper.update(user);
logMapper.insertLog(user.getId(), "update");
}
6. 避免 N+1 查询
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
7. 自定义类型处理器
public class MyEnumTypeHandler implements TypeHandler<MyEnum> {
// 实现方法
}
8. 缓存合理使用
<select id="getConfig" resultType="Config" useCache="true">
SELECT * FROM config WHERE id = #{id}
</select>
9. 多表关联映射
<resultMap id="orderResultMap" type="Order">
<id property="id" column="order_id"/>
<association property="user" javaType="User">
<id property="id" column="user_id"/>
<result property="name" column="user_name"/>
</association>
</resultMap>
10. 批量操作
<insert id="insertUsers">
INSERT INTO users (name, age)
VALUES
<foreach collection="list" item="user" separator=",">
(#{user.name}, #{user.age})
</foreach>
</insert>
11. 条件分支
<choose>
<when test="id != null">id = #{id}</when>
<when test="name != null">name = #{name}</when>
<otherwise>age > 18</otherwise>
</choose>
12. SQL 拼接优化
<trim prefixOverrides="AND |OR ">
<if test="name != null">AND name = #{name}</if>
<if test="age != null">OR age = #{age}</if>
</trim>
13. 驼峰映射
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
14. SQL 片段复用
<sql id="userColumns">id, name, age, email</sql>
<select id="getUser" resultType="User">
SELECT <include refid="userColumns"/> FROM users WHERE id = #{id}
</select>
15. 日志调试
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
总结
- 避坑第一步:尽量不用 ${}
- 避坑第二步:全局设置和 SQL 片段多用
- 避坑第三步:分页、批量、缓存都要有意识地优化
掌握这些,你的 MyBatis 代码不仅更安全,还更高效、更易维护。
© 版权声明
文章版权归作者所有,未经允许请勿转载。如内容涉嫌侵权,请在本页底部进入<联系我们>进行举报投诉!
THE END















- 最新
- 最热
只看作者