数据访问(三):MyBatis

starter 与版本注意

MyBatis 由第三方社区维护,与 Spring Boot 的集成 starter 为 mybatis-spring-boot-starter(组 ID org.mybatis.spring.boot)。引入时务必选择与所用 Boot 主线兼容的版本:Boot 3.x 对应 3.x 版本线,Boot 4.x 需用更新的主版本,具体以 MyBatis 官方发布说明为准:

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>(与 Boot 主线匹配的版本)</version>
</dependency>

还需要数据库驱动(同 14 章)。启动类加 @MapperScan("com.example.demo.mapper"),或在每个 Mapper 接口上加 @Mapper(二选一),MyBatis 会自动创建 SqlSessionFactory 并扫描 Mapper。

注解方式

适合简单 SQL:

@Mapper
public interface UserMapper {

    @Select("select * from t_user where id = #{id}")
    User findById(Long id);

    @Insert("insert into t_user(name, age) values (#{name}, #{age})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(User user);

    @Update("update t_user set age = #{age} where id = #{id}")
    int updateAge(@Param("id") Long id, @Param("age") int age);

    @Delete("delete from t_user where id = #{id}")
    int deleteById(Long id);
}

要点:#{...} 是预编译占位符(防 SQL 注入);多个参数必须用 @Param 命名,或用对象传参;@Options(useGeneratedKeys = true) 可取回自增主键并回填到对象。

XML 方式

复杂 SQL 推荐 XML。Mapper 接口只写方法签名:

public interface UserMapper {
    List<User> search(@Param("name") String name, @Param("minAge") Integer minAge);
}

XML 放 src/main/resources/mapper/UserMapper.xmlnamespace 等于接口全限定名、id 等于方法名:

<mapper namespace="com.example.demo.mapper.UserMapper">
    <select id="search" resultType="com.example.demo.entity.User">
        select * from t_user
        <where>
            <if test="name != null and name != ''">
                and name like concat('%', #{name}, '%')
            </if>
            <if test="minAge != null">
                and age &gt;= #{minAge}
            </if>
        </where>
    </select>
</mapper>

配置 XML 位置与驼峰映射:

mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.configuration.map-underscore-to-camel-case=true

map-underscore-to-camel-case 开启后,t_user 表的 user_name 列可自动映射到 userName 字段。动态 SQL 的 <where>/<if>/<foreach> 是 MyBatis 处理多变查询条件的主要手段。同一方法不能同时用注解和 XML 定义,否则启动报错。

与 Spring Data JPA 的选择

维度Spring Data JPAMyBatis
编程模型实体驱动,接口即实现SQL 驱动,SQL 完全在手
简单 CRUD零代码每个方法都要写
复杂查询/报表 SQL需 JPQL/原生 SQL 打磨直接写原生 SQL + 动态 SQL

没有绝对优劣:追求开发效率与对象化建模选 JPA,追求 SQL 可控、团队普遍熟悉 SQL 时选 MyBatis。

小结

MyBatis 的集成三步:引入匹配版本的 starter → 扫描 Mapper 接口 → 用注解或 XML 写 SQL。注解适合小 SQL,XML + 动态 SQL 是复杂查询的主力,配合 map-underscore-to-camel-case 可省去大量手工映射。

笔记加载中…