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 的。