MyBatis 写法
MyBatis 高效使用技巧
常见 MyBatis 使用技巧,这些技巧有助于简化数据库操作,提高开发效率,并增强系统的性能。
1. 动态 SQL
动态 SQL 让开发者能够依据参数灵活地构建 SQL 语句,避免了手动拼接字符串带来的复杂性和错误风险。
<select id="selectUsersByCondition" parameterType="map" resultType="User">
SELECT * FROM users WHERE 1=1
<if test="username != null">AND username = #{username}</if>
<if test="age != null">AND age = #{age}</if>
<if test="status != null">AND status = #{status}</if>
</select>
2. 批量操作
通过 <foreach>
标签可以轻松实现批量插入或更新,减少多次调用造成的性能损失。
<insert id="batchInsert" parameterType="list">
INSERT INTO users (username, age)
VALUES
<foreach collection="list" item="user" separator=",">
(#{user.username}, #{user.age})
</foreach>
</insert>
3. 结果集映射 (resultMap
)
当查询结果与实体类字段不匹配时,resultMap
可以帮助进行精确映射,适用于复杂的关联关系。
<resultMap id="userResultMap" type="User">
<id property="id" column="user_id"/>
<result property="username" column="user_name"/>
<result property="age" column="user_age"/>
</resultMap>
4. 分页查询
利用分页插件(如 MyBatis-Plus 或 PageHelper)简化分页逻辑,无需手动处理 LIMIT
和 OFFSET
。
Page<User> page = new Page<>(1, 10); // 第一页,每页10条记录
List<User> users = userMapper.selectPage(page, new QueryWrapper<>());
5. 一对多关系映射
collection
标签用于处理一对多的关系,自动将子表数据封装到父对象中。
<resultMap id="userWithOrders" type="User">
<!-- 省略主表映射 -->
<collection property="orders" ofType="Order">
<id property="id" column="order_id"/>
<result property="amount" column="order_amount"/>
</collection>
</resultMap>
6. 注解与 XML 配合使用
结合 @Mapper
注解和 XML 映射文件,既保持了接口配置的简洁性,又实现了 SQL 的外部化管理。
@Mapper
public interface UserMapper {
List<User> selectUsersByCondition(Map<String, Object> params);
}
7. 批量更新
同样可以通过 <foreach>
实现批量更新,减少数据库交互次数。
<update id="batchUpdateUsers" parameterType="list">
<foreach collection="list" item="user" separator=";">
UPDATE users SET username = #{user.username}, age = #{user.age} WHERE id = #{user.id}
</foreach>
</update>
8. 复杂表达式处理
bind
标签允许在 SQL 中直接处理复杂的表达式,使代码更整洁。
<bind name="pattern" value="'%' + keyword + '%'"/>
<select id="selectUsersByKeyword" resultType="User">
SELECT * FROM users WHERE username LIKE #{pattern}
</select>
9. 自定义类型处理器
为了解决 Java 类型与数据库类型的不一致问题,可以创建自定义类型处理器。
@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(CustomType.class)
public class CustomTypeHandler extends BaseTypeHandler<CustomType> { /* ... */ }
10. 逻辑删除
逻辑删除是一种保留历史数据的删除方式,它只是标记记录为已删除状态。
<update id="deleteUser" parameterType="int">
UPDATE users SET deleted = 1 WHERE id = #{id}
</update>
11. 分表策略
对于海量数据场景,分表策略能显著提升查询性能。注意防范 SQL 注入风险。
<select id="selectFromTable" resultType="User">
SELECT * FROM ${tableName} WHERE id = #{id}
</select>
12. SQL 片段复用
使用 <sql>
标签定义可复用的 SQL 片段,减少重复代码。
<sql id="baseUserColumns">
id, username, age, email
</sql>
13. 枚举类型映射
枚举类型处理器简化了枚举值与数据库字段间的映射,增强了代码的可读性。
@EnumTypeHandler(EnumTypeHandler.class)
public enum UserStatus {
ACTIVE, INACTIVE;
}
14. 多数据源配置
多数据源配置有助于分离不同类型的数据,满足微服务架构下的需求。
@Configuration
public class MyBatisConfig {
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
return factoryBean.getObject();
}
}
15. 延迟加载
延迟加载特性可以在需要时才加载关联数据,从而优化性能。
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
</settings>