Mapper XML 基础

Mapper XML 是 MyBatis 的核心:一个 XML 文件承载一组 SQL 语句,用 select/insert/update/delete 标签声明增删改查,还能在插入后把数据库生成的主键回填到对象里。会读会写映射文件,才算真正会用 MyBatis。

namespace 与语句定位

  • namespace 必填(官方 XML 约束),且在整个应用内唯一;最佳实践是写成 Mapper 接口的全限定名,如 com.example.mapper.UserMapper
  • 语句完整 ID = namespace.id,调用时写作 "com.example.mapper.UserMapper.selectById"
<mapper namespace="com.example.mapper.UserMapper">
    <!-- 语句 id 在同一个 namespace 内唯一 -->
    <select id="selectById" resultType="com.example.entity.User">
        SELECT id, name, age FROM user WHERE id = #{id}
    </select>
</mapper>

映射文件的顶层元素

一个 Mapper XML 内可按任意顺序出现:cache → cache-ref → resultMap → sql → insert → update → delete → select(旧版 parameterMap 已废弃,不要使用,以官方文档为准)。

select 查询标签

select 常用属性:id(唯一编号)、parameterType(入参类型,多数可省略)、resultType(结果类型)、resultMap(引用 resultMap,与 resultType 二选一)、flushCache/useCache(缓存控制)、timeout/fetchSize(超时与抓取行数)、statementType(PREPARED 默认/STATEMENT/CALLABLE)。

<!-- 返回多条时 resultType 仍写元素类型,自动包装成 List<User> -->
<select id="selectAll" resultType="com.example.entity.User">
    SELECT id, name, age FROM user
</select>

只要列名与属性名一致(或开启 mapUnderscoreToCamelCase,见第 3 章),MyBatis 自动完成映射,无需逐列声明。

insert / update / delete

增删改标签结构类似,返回值都是受影响行数(int):

<insert id="insert" parameterType="com.example.entity.User">
    INSERT INTO user(name, age) VALUES(#{name}, #{age})
</insert>
<update id="update">
    UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}
</update>
<delete id="delete">
    DELETE FROM user WHERE id = #{id}
</delete>

主键回填:useGeneratedKeys 与 selectKey

插入后经常要拿数据库生成的主键,两种方式:数据库支持自增(MySQL)→ useGeneratedKeys="true" keyProperty="id",框架执行 INSERT 后把自增值写回对象的 id 字段:

<insert id="insert" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO user(name, age) VALUES(#{name}, #{age})
</insert>
User u = new User();
u.setName("王五");
session.insert("...UserMapper.insert", u);
System.out.println(u.getId()); // 自增主键已被写回

数据库用序列/触发器取主键(如 Oracle)→ 用 selectKey 在插入前(order="BEFORE")先查主键:

<insert id="insert">
    <selectKey keyProperty="id" resultType="long" order="BEFORE">
        SELECT seq_user.NEXTVAL FROM dual
    </selectKey>
    INSERT INTO user(id, name, age) VALUES(#{id}, #{name}, #{age})
</insert>

selectKey 的 order 取值 BEFORE/AFTER 及更多用法以官方文档为准。

sql 片段与 include

公共列、公共条件可以抽成片段复用:

<sql id="userColumns">id, name, age</sql>
<select id="selectById" resultType="com.example.entity.User">
    SELECT <include refid="userColumns"/> FROM user WHERE id = #{id}
</select>
<select id="selectAll" resultType="com.example.entity.User">
    SELECT <include refid="userColumns"/> FROM user
</select>

与 Mapper 接口的关系(预告)

让接口方法签名与 XML 语句 id 一一对应,MyBatis 就能用动态代理生成接口实现,调用 userMapper.selectById(1) 即可,省去手写语句全名——第 15 章讲 Spring 集成时正式登场。

小结

Mapper XML 的要点:namespace 隔离定位、四类增删改查标签、插入时用 useGeneratedKeys/selectKey 回填主键。下一章解决最关键的问题——参数是怎么传进 SQL 的。

笔记加载中…