MyBatis 基本使用
1. 基础 CRUD 场景(注解方式)
适用于简单的 SQL 逻辑,无需创建冗长的 XML 文件,代码直接写在 Mapper 接口上
@Mapper
public interface UserMapper {
@Select("SELECT * FROM users WHERE id = #{id}")
User findById(@Param("id") Long id);
@Insert("INSERT INTO users(name, email) VALUES(#{name}, #{email})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(User user);
@Update("UPDATE users SET name=#{name} WHERE id=#{id}")
int update(User user);
@Delete("DELETE FROM users WHERE id = #{id}")
int delete(Long id);
}
2. 复杂 SQL 场景(XML 映射方式)
这是 MyBatis 的主流用法。适用于长 SQL、多表联查或需要维护 SQL 格式的场景,实现代码与 SQL 的解耦。
Mapper 接口:
@Mapper
public interface UserMapper {
UserDetailDto getUserDetail(Long id);
}
XML 映射文件 (UserMapper.xml):
<select id="getUserDetail" resultMap="UserDetailMap">
SELECT u.*, o.order_no, p.profile_path
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
LEFT JOIN profiles p ON u.id = p.user_id
WHERE u.id = #{id}
</select>
3. 动态 SQL 场景(核心优势)
利用 MyBatis 的标签(<if>, <where>, <set>, <foreach>)根据入参动态拼接 SQL。这是处理“多条件搜索”最优雅的方案。
<select id="searchUsers" resultType="User">
SELECT * FROM users
<where>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="status != null">
AND status = #{status}
</if>
<if test="ids != null and ids.size > 0">
AND id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</if>
</where>
</select>
4. 关联查询场景(ResultMap)
处理对象间的层级关系,如“一对一” (association) 和 “一对多” (collection)。
<resultMap id="UserOrderMap" type="User">
<id property="id" column="user_id"/>
<result property="userName" column="username"/>
<collection property="orders" ofType="Order">
<id property="id" column="order_id"/>
<result property="orderNo" column="order_no"/>
</collection>
</resultMap>
5. 批量操作场景 (Batch Operations)
在处理大量数据导入时,使用 foreach 拼接批量插入语句,性能远高于单条循环插入。
<insert id="batchInsertUsers">
INSERT INTO users (name, email)
VALUES
<foreach collection="list" item="user" separator=",">
(#{user.name}, #{user.email})
</foreach>
</insert>
6. 分页查询场景
在 Spring Boot 中,最典型的方法是集成 PageHelper 插件。
Service 层用法:
public PageInfo<User> getUsers(int pageNum, int pageSize) {
// 开启分页,紧跟其后的第一个 select 语句会被分页
PageHelper.startPage(pageNum, pageSize);
List<User> list = userMapper.selectAll();
return new PageInfo<>(list);
}
7. 事务管理场景
MyBatis 完美集成 Spring 的声明式事务。只需在 Service 方法上添加 @Transactional。
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Transactional(rollbackFor = Exception.class)
public void registerUser(User user) {
userMapper.insert(user);
// 如果这里抛出异常,上面的 insert 会自动回滚
if(error) throw new RuntimeException();
}
}