数据写入
通过 dbVisitor 执行 Elasticsearch REST 命令完成新增、修改和删除。查询方 法及实体映射见查询操作。
执行写入命令
JdbcTemplate jdbc = new JdbcTemplate(dataSource);
jdbc.executeUpdate(
"POST /user_info/_doc\\?refresh=wait_for {\"uid\": ?, \"name\": ?}",
new Object[] { "1001", "mali" });
jdbc.executeUpdate(
"POST /user_info/_update_by_query\\?refresh=true {\"query\":{\"term\":{\"uid\": ?}},\"script\":{\"source\":\"ctx._source.name = params.name\",\"params\":{\"name\": ?}}}",
new Object[] { "1001", "new name" });
jdbc.executeUpdate(
"POST /user_info/_delete_by_query\\?refresh=true {\"query\":{\"term\":{\"uid\": ?}}}",
new Object[] { "1001" });
备注
URL 中的 ? 不是绑定参数,需要转义:Java 字符串写 \\?,Mapper 文件写 \?。详见参数标记转义。
文档 ID 与更新条件
使用构造器 API 或 BaseMapper 插入时,已赋值的单个映射主键同时作为文档 _id。直接执行 REST 命令时,文档 ID 由请求路径决定。见主键生成。
多个属性标记为 primary=true 时,BaseMapper 使用全部主键字段定位记录,但不会将它们合成为 _id 或创建复合唯一约束。业务需保证这些字段的组合唯一,否则修改、删除可能影响多条文档。
通过不同 API 修改数据
以下示例复用查询操作中的实体映射,将指定记录的名称改为 new name。
- 构造器 API
- 方法注解
- Mapper 文件
LambdaTemplate lambda = new LambdaTemplate(dataSource);
int changed = lambda.update(UserInfo.class)
.eq(UserInfo::getUid, "1001")
.updateTo(UserInfo::getName, "new name")
.doUpdate();
@SimpleMapper
public interface UserInfoWriteMapper {
@Update("POST /user_info/_update_by_query\\?refresh=true {\"query\":{\"term\":{\"uid\": #{uid}}},\"script\":{\"source\":\"ctx._source.name = params.name\",\"params\":{\"name\": #{name}}}}")
int rename(@Param("uid") String uid, @Param("name") String name);
}
<mapper namespace="com.example.UserInfoWriteMapper">
<update id="rename">
POST /user_info/_update_by_query\?refresh=true {"query":{"term":{"uid": #{uid}}},"script":{"source":"ctx._source.name = params.name","params":{"name": #{name}}}}
</update>
</mapper>
@RefMapper("/mapper/elastic-write.xml")
public interface UserInfoWriteMapper {
int rename(@Param("uid") String uid, @Param("name") String name);
}
XML 保存到 /mapper/elastic-write.xml,接口位于 com.example 包。
Session session = new Configuration().newSession(dataSource);
UserInfoWriteMapper mapper = session.createMapper(UserInfoWriteMapper.class);
int changed = mapper.rename("1001", "new name");
实际写入动作
| 操作 | 数据库动作 |
|---|---|
| 修改指定属性 | _update_by_query |
| 删除匹配记录 | _delete_by_query |
BaseMapper 的修改和删除复用相同操作。
写入后立即查询
写入后立即搜索时,单文档请求使用 refresh=wait_for。构造器连续写后查询可在连接中配置 indexRefresh=true,代价是更频繁地刷新索引。
条件与结果读取见查询操作。
多条写入与事务
多条命令不会自动构成事务,失败前成功的写入不保证回滚。事务调用方式、传播及隔离级别见事务支持。