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(); 
    }
}


举报

© 著作权归作者所有


0