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> {@Overridepublic 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