feat(core): 添加 UUID 和自定义 ID 策略支持

- 在 EsClientUtils 中增加驼峰转下划线配置的支持
- 在 BaseEsMapperImpl 中实现 id 在实体中返回
- 在 InsertTest 中添加用户创建测试用例
This commit is contained in:
阿杰 2025-09-19 14:37:37 +08:00
parent 78fe61fd1f
commit 676f200f10
8 changed files with 191 additions and 10 deletions

View File

@ -4,6 +4,7 @@ import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequestInterceptor;
@ -126,7 +127,10 @@ public class EsClientUtils {
.ifPresent(requestConfigBuilder::setConnectionRequestTimeout);
return requestConfigBuilder;
});
// 如果是驼峰转下划线, 则增加序列化器
if (easyEsConfigProperties.getGlobalConfig().getDbConfig().isMapUnderscoreToCamelCase()) {
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
}
return new ElasticsearchClient(new RestClientTransport(builder.build(),
new JacksonJsonpMapper(objectMapper)));
}

View File

@ -1398,18 +1398,33 @@ public class BaseEsMapperImpl<T> implements BaseEsMapper<T> {
private IndexRequest.Builder<T> buildIndexRequest(T entity, String routing, String parentId, String indexName) {
IndexRequest.Builder<T> indexRequest = new IndexRequest.Builder<T>()
.routing(routing)
.index(indexName)
.document(entity);
.index(indexName);
// id预处理,除下述情况,其它情况使用es默认的id
EntityInfo entityInfo = EntityInfoHelper.getEntityInfo(entityClass);
if (IdType.UUID.equals(entityInfo.getIdType())) {
indexRequest.id(UUID.randomUUID().toString());
} else if (IdType.CUSTOMIZE.equals(entityInfo.getIdType())) {
indexRequest.id(getIdValue(entity));
String uuid = UUID.randomUUID().toString();
indexRequest.id(uuid);
// 如果id需要存入_source
if (entityInfo.isId2Source()) {
try {
entityInfo.getKeyField().set(entity, uuid);
} catch (IllegalAccessException e) {
throw ExceptionUtils.eee(e);
}
}
} else if (IdType.CUSTOMIZE.equals(entityInfo.getIdType())) {
String idValue = getIdValue(entity);
indexRequest.id(idValue);
if (entityInfo.isId2Source()) {
try {
entityInfo.getKeyField().set(entity, idValue);
} catch (IllegalAccessException e) {
throw ExceptionUtils.eee(e);
}
}
}
indexRequest.document(entity);
// 针对父子类型-追加joinField信息
if (StringUtils.isNotBlank(entityInfo.getJoinAlias())) {
if (!(entity instanceof BaseJoin)) {

View File

@ -0,0 +1,57 @@
package org.dromara.easyes.test.entity;
import lombok.Data;
import org.dromara.easyes.annotation.IndexField;
import org.dromara.easyes.annotation.IndexId;
import org.dromara.easyes.annotation.rely.FieldType;
import org.dromara.easyes.annotation.rely.IdType;
/**
* @author MoJie
* @since 2025-09-19
*/
@Data
public class BaseEsEntity {
/**
* 文档ID使用UUID策略自动生成
*/
@IndexId(type = IdType.UUID)
private String id;
/**
* 创建时间
*/
@IndexField(fieldType = FieldType.KEYWORD)
private String createTime;
/**
* 创建人
*/
@IndexField(fieldType = FieldType.KEYWORD)
private String createBy;
/**
* 更新时间
*/
@IndexField(fieldType = FieldType.KEYWORD)
private String updateTime;
/**
* 更新人
*/
@IndexField(fieldType = FieldType.KEYWORD)
private String updateBy;
/**
* 是否删除逻辑删除标记
*/
@IndexField(fieldType = FieldType.BOOLEAN)
private Boolean deleted = false;
/**
* 版本号用于乐观锁
*/
@IndexField(fieldType = FieldType.LONG)
private Long version = 1L;
}

View File

@ -0,0 +1,66 @@
package org.dromara.easyes.test.entity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.easyes.annotation.IndexField;
import org.dromara.easyes.annotation.IndexName;
import org.dromara.easyes.annotation.rely.Analyzer;
import org.dromara.easyes.annotation.rely.FieldType;
/**
* @author MoJie
* @since 2025-09-19
*/
@Data
@IndexName(value = "user")
@EqualsAndHashCode(callSuper = true)
public class UserEntity extends BaseEsEntity {
/**
* 用户名精确匹配
*/
@IndexField(fieldType = FieldType.KEYWORD)
private String username;
/**
* 姓名支持分词搜索
*/
@IndexField(fieldType = FieldType.TEXT, analyzer = Analyzer.IK_SMART, searchAnalyzer = Analyzer.IK_MAX_WORD)
private String name;
/**
* 年龄
*/
@IndexField(fieldType = FieldType.INTEGER)
private Integer age;
/**
* 邮箱精确匹配
*/
@IndexField(fieldType = FieldType.KEYWORD)
private String email;
/**
* 地址支持分词搜索
*/
@IndexField(fieldType = FieldType.TEXT, analyzer = Analyzer.IK_SMART, searchAnalyzer = Analyzer.IK_MAX_WORD)
private String address;
/**
* 用户状态0-禁用1-启用
*/
@IndexField(fieldType = FieldType.INTEGER)
private Integer status = 1;
/**
* 用户标签支持多值
*/
@IndexField(fieldType = FieldType.KEYWORD)
private String[] tags;
/**
* 用户描述支持分词搜索
*/
@IndexField(fieldType = FieldType.TEXT, analyzer = Analyzer.IK_SMART, searchAnalyzer = Analyzer.IK_MAX_WORD)
private String description;
}

View File

@ -0,0 +1,11 @@
package org.dromara.easyes.test.mapper;
import org.dromara.easyes.core.kernel.BaseEsMapper;
import org.dromara.easyes.test.entity.UserEntity;
/**
* @author MoJie
* @since 2025-09-19
*/
public interface UserMapper extends BaseEsMapper<UserEntity> {
}

View File

@ -58,6 +58,7 @@ public class AllTest {
@Test
@Order(0)
public void testCreateIndex() {
documentMapper.deleteIndex();
// 0.前置操作 创建索引 需确保索引托管模式处于manual手动挡,若为自动挡则会冲突.
boolean success = documentMapper.createIndex();
Assertions.assertTrue(success);

View File

@ -1,8 +1,11 @@
package org.dromara.easyes.test.insert;
import org.dromara.easyes.common.utils.DateUtil;
import org.dromara.easyes.test.TestEasyEsApplication;
import org.dromara.easyes.test.entity.Document;
import org.dromara.easyes.test.entity.UserEntity;
import org.dromara.easyes.test.mapper.DocumentMapper;
import org.dromara.easyes.test.mapper.UserMapper;
import org.elasticsearch.geometry.Point;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
@ -25,6 +28,8 @@ import java.util.List;
public class InsertTest {
@Resource
private DocumentMapper documentMapper;
@Resource
private UserMapper userMapper;
@Test
public void testInsert() {
@ -42,7 +47,7 @@ public class InsertTest {
document.setGeoLocation(point.toString());
document.setStarNum(0);
int successCount = documentMapper.insert(document);
Assertions.assertEquals(successCount, 1);
Assertions.assertEquals(1, successCount);
}
@Test
@ -112,4 +117,26 @@ public class InsertTest {
System.out.println("更新后的数据:" + document1);
}
@Test
public void testCreateUser() {
// 创建测试用户
UserEntity user = new UserEntity();
user.setUsername("tester001");
user.setName("张三");
user.setAge(25);
user.setEmail("zhangsan@example.com");
user.setAddress("北京市朝阳区");
user.setStatus(1);
user.setTags(new String[]{"Java", "Spring", "Elasticsearch"});
user.setDescription("这是一个测试用户专门用于演示Easy-ES的功能");
user.setVersion(2L);
user.setDeleted(true);
user.setCreateBy("system");
user.setUpdateBy("system");
user.setCreateTime(DateUtil.format(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
user.setUpdateTime(DateUtil.format(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
// 创建用户
Assertions.assertEquals(1, userMapper.insert(user));
}
}

View File

@ -1,6 +1,6 @@
easy-es:
# enable: true
address: 10.18.2.45:9200
address: 192.168.0.18:9200
compatible: true
# schema: http
# username: elastic
@ -8,7 +8,7 @@ easy-es:
keep-alive-millis: 18000
global-config:
i-kun-mode: false
process-index-mode: manual
process-index-mode: smoothly
async-process-index-blocking: true
print-dsl: true
db-config: