MyBatis高级应用实例
以下是MyBatis高级应用实例,涵盖复杂查询、动态SQL、插件开发、缓存优化等场景,帮助深入掌握MyBatis核心技术。
动态SQL构建
Example 1: 多条件动态查询
使用<if>
和<where>
标签实现条件组合:
<select id="findUsers" resultType="User">
SELECT * FROM user
<where>
<if test="name != null">AND name = #{name}</if>
<if test="age != null">AND age = #{age}</if>
</where>
</select>
Example 2: 动态更新字段
<set>
标签避免全字段更新:
<update id="updateUser">
UPDATE user
<set>
<if test="name != null">name = #{name},</if>
<if test="email != null">email = #{email}</if>
</set>
WHERE id = #{id}
</update>
Example 3: 批量插入
<foreach>
处理集合数据:
<insert id="batchInsert">
INSERT INTO user (name, age) VALUES
<foreach item="item" collection="list" separator=",">
(#{item.name}, #{item.age})
</foreach>
</insert>
高级结果映射
Example 4: 一对一关联
嵌套结果映射:
<resultMap id="orderWithUser" 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>
Example 5: 一对多嵌套查询
分步加载关联数据:
<resultMap id="blogWithPosts" type="Blog">
<collection
property="posts"
column="id"
select="selectPostsForBlog"/>
</resultMap>
Example 6: 鉴别器映射
根据条件返回不同对象:
<discriminator javaType="int" column="type">
<case value="1" resultType="AdminUser"/>
<case value="2" resultType="NormalUser"/>
</discriminator>
缓存优化
Example 7: 二级缓存配置
在mapper.xml中启用缓存:
<cache eviction="LRU" flushInterval="60000" size="512"/>
Example 8: 自定义缓存实现
集成Redis缓存:
public class RedisCache implements Cache {
// 实现Cache接口方法
}
Example 9: 局部缓存禁用
特定语句跳过缓存:
<select id="getRealTimeData" useCache="false">
SELECT * FROM stock_data
</select>
插件开发
Example 10: SQL执行时间统计
拦截Executor
组件:
@Intercepts(@Signature(
type= Executor.class,
method="query",
args={MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}))
public class SqlTimerPlugin implements Interceptor {
// 实现拦截逻辑
}
Example 11: 分页插件
自动改写SQL语句:
StatementHandler handler = (StatementHandler) invocation.getTarget();
BoundSql boundSql = handler.getBoundSql();
String sql = boundSql.getSql() + " LIMIT ?,?";
Example 12: 敏感数据加密
拦截参数处理:
ParameterHandler ph = (ParameterHandler) invocation.getTarget();
if (ph.getParameterObject() instanceof User) {
User user = (User) ph.getParameterObject();
user.setPassword(encrypt(user.getPassword()));
}
复杂类型处理
Example 13: JSON字段映射
自定义TypeHandler:
public class JsonTypeHandler extends BaseTypeHandler<Map> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i,
Map parameter, JdbcType jdbcType) {
ps.setString(i, JSON.toJSONString(parameter));
}
}
Example 14: 枚举类型转换
实现EnumOrdinalTypeHandler:
<typeHandler
handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"
javaType="com.example.UserStatus"/>
Example 15: 存储过程调用
使用<select>
标签调用:
<select id="callProcedure" statementType="CALLABLE">
{call calculate_bonus(#{empId,jdbcType=INTEGER,mode=IN})}
</select>
批量操作优化
Example 16: 批量更新
ExecutorType.BATCH模式:
SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
try {
UserMapper mapper = session.getMapper(UserMapper.class);
for (User user : users) {
mapper.updateUser(user);
}
session.commit();
} finally {
session.close();
}
Example 17: 游标查询
处理大数据集:
try (Cursor<User> cursor = mapper.scanUsers()) {
cursor.forEach(user -> process(user));
}
Example 18: 多结果集处理
存储过程返回多个结果:
<select id="getMultiResults" resultSets="users,departments"
r