MyBatis XML映射文件中,<select>、<insert>、<update>、<delete>是四大核心SQL标签;<select>需指定resultType或resultMap,其余三者用id和parameterType即可,参数统一用#{ }预编译防注入,id必须与接口方法名一致。

MyBatis 的 XML 映射文件中,<select>、<insert>、<update> 和 <delete> 是最核心的 SQL 操作标签,每个标签都需配合 id(对应接口方法名)、parameterType(可选,推荐用泛型避免)和 resultType 或 resultMap(仅 <select> 需要)来使用。
基础 <select> 标签写法
用于查询单条或列表数据。必须指定 resultType(简单类型或 POJO 类名)或 resultMap(复杂映射)。
- 查单个用户(按 id):
<select id="selectById" resultType="com.example.User">
SELECT * FROM user WHERE id = #{id}
</select> - 查所有用户并映射到 List<User>:
<select id="selectAll" resultType="com.example.User">
SELECT id, username, email FROM user
</select> - 参数是对象时,用
#{username}引用属性;是 Map 时用#{keyName};多个参数建议封装成对象或用@Param注解。
基础 <insert> 标签写法
用于插入记录,支持主键自动生成(如 MySQL 的 useGeneratedKeys)或序列(如 Oracle)。
- 普通插入(不返回主键):
<insert id="insertUser">
INSERT INTO user (username, email) VALUES (#{username}, #{email})
</insert> - MySQL 自增主键回填:
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user (username, email) VALUES (#{username}, #{email})
</insert>
执行后,传入的 User 对象的id属性会被自动赋值。 - Oracle 序列示例:
<insert id="insertUser" keyProperty="id">
INSERT INTO user (id, username, email) VALUES (USER_SEQ.NEXTVAL, #{username}, #{email})
</insert>
基础 <update> 标签写法
用于更新记录,通常带 WHERE 条件防止全表更新。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
立即学习“Java免费学习笔记(深入)”;
- 根据 id 更新用户名和邮箱:
<update id="updateUser">
UPDATE user SET username = #{username}, email = #{email} WHERE id = #{id}
</update> - 只更新非空字段可用
<set>+<if>动态拼接(但基础场景不强制)。 - 返回值是影响行数(int),不是对象,无需
resultType。
基础 <delete> 标签写法
用于删除记录,务必加 WHERE 条件,否则可能误删全表。
- 按 id 删除:
<delete id="deleteById">
DELETE FROM user WHERE id = #{id}
</delete> - 按条件批量删除(例如软删除):
<delete id="deleteByStatus">
UPDATE user SET status = 0 WHERE status = #{status}
</delete>
注意:这里用了 UPDATE 实现逻辑删除,实际 DELETE 语句同理。 - 无返回结果,只返回影响行数。
不复杂但容易忽略:SQL 中的参数一律用 #{}(预编译防注入),不用 ${}(除非动态表名/列名且已严格校验);每个标签的 id 必须与 Mapper 接口方法名一致;namespace 要指向对应 Mapper 接口全限定名。

















