数据回填
需要获取新增记录的默认时间、更新后的年龄或删除前的名字时,可以使用 RETURNING。写入语句直接返回这些值,不需要再执行一次 SELECT。
准备表
CREATE TABLE user_info (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR(64),
age INTEGER,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
插入后获取默认时间
Map<String, Object> saved = jdbcTemplate.queryForMap(
"""
INSERT INTO user_info (name, age)
VALUES (?, ?)
RETURNING id, create_time
""",
new Object[] { "mali", 18 });
结果包含 id 和数据库生成的 create_time。这里使用查询方法,是因为写入语句同时返回了字段。
写回实体属性
使用 Mapper 文件时,可以将返回列直接写回参数对象的 id 和 createTime 属性:
<insert id="insertUser"
useGeneratedKeys="true"
keyProperty="id,createTime"
keyColumn="id,create_time"
generatedKeySource="resultSet">
INSERT INTO user_info (name, age)
VALUES (#{name}, #{age})
RETURNING id, create_time
</insert>
对象需有 Long id、Timestamp createTime 属性及 getter/setter。keyProperty 指定接收属性,不要求这些属性都是主键。
更新后获取字段
修改指定记录并获取新的年龄。使用 queryForList,未匹配 ID 时返回空列表:
List<Map<String, Object>> changed = jdbcTemplate.queryForList(
"""
UPDATE user_info SET age = ? WHERE id = ?
RETURNING id, age
""",
new Object[] { 19, 1001L });
删除时获取字段
List<Map<String, Object>> deleted = jdbcTemplate.queryForList(
"""
DELETE FROM user_info WHERE id = ? RETURNING id, name
""",
new Object[] { 1001L });
每行结果包含被删除记录的 ID 和名字。更新和删除示例中的 1001L 应替换为实际已有的 ID。
注意
参数对象回填用于单行插入。返回多行时使用查询方法逐行读取,不要按返回顺序与输入位置配对。
自增主键的配置见主键生成。