【SpringBoot】JPA接入Elasticsearch6.3.2 实战


【SpringBoot】JPA接入Elasticsearch6.3.2 实战

前言:最近在一项目中使用到了ES存储和相关操作,本来以为会和MYSQL使用引入的方式一样,但是经过实际的验证发现确实有大不一样。首先,es针对不同版本不做兼容,所以每一个客户端都需要引入自己固定的maven,否则就连接不上或者各种对应不上。

版本

SpringBoot 2.2.6.RELEASE

ES 6.3.2

JPA 操作方式

Maven核心配置

<code>
<properties>
<java.version>1.8/<java.version>
<lombok.version>1.18.10/<lombok.version>
<hutool.version>5.1.2/<hutool.version>
<elasticsearch.version>6.3.2/<elasticsearch.version>
/<properties>/<code>

Application.yml核心配置

<code>spring:
data:
elasticsearch:
\t\t\t#要和自己的ES配置的是一样
cluster-name: xxx
#TCP地址,非HttpRest地址
cluster-nodes: 192.0.0.1:11011
\t\t\t#如果ES没有权限验证可以不配置,当然即使配置了也不会有作用,这个是我自定义的,请往后看
\t\t\t#用户名

username: xxx
#密码
password: XXXXXXXXX
#头部
header: xxx/<code>

JPA开始操作

  • 新建Domain
<code>
@Data
// indexName 代表mysql的database
// type 代表mysql的table
@Document(indexName = "x-app-db", type = "x-app-table")
public class XDomain {
@Id
@Field(name = "x-id", type = FieldType.Keyword)
private String xId;
@Field(name = "x-create-time", type = FieldType.Long)
private Long xCreateTime;
\t.....
}/<code>

以上是一个简单的实体定义,@Id 使用该注解之后,请确保ES-mapping对应的是keyword类型,否则会报current[text] mreage[keyword]

  • 新建JPA Repository
<code>public interface XDomainRepository extends ElasticsearchCrudRepository<xdomain> {

/**
* 查询全部
*
* @return
*/
@Override
Iterable<xdomain> findAll();

\t .... 其它查询,请遵守jpa操作格式

}/<xdomain>/<xdomain>/<code>
  • 新建service.impl操作
<code>
@Service
public class XDomainServiceImpl {

@Autowired
private XDomainRepository xDomainRepository;

\t//查询全部,返回结果集合
public Iterable<xdomain> findAll() {
return xDomainRepository.findAll();
}

\t\t//保存及更新
\t\t//非常实用的方法
public Boolean save(XDomain xDomain) {
\t//根据XId 查询是否存在
XDomain x1 = xDomainRepository.findXDomainByXId(xDomain.getXId());
if (ObjectUtil.isEmpty(x1)) {
\t// 不存在,就是新增,可以设置一些其它初始化
} else {
// 组合旧数据 防止覆盖已经提交的数据
BeanUtil.copyProperties(xDomain, x1, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
xDomain = x1;
}
XDomain x2 = xDomainRepository.save(xDomain);
if (ObjectUtil.isEmpty(x2)) {
return false;
}
return true;
}
\t
\t\t//删除等操作就比较简单了
}/<xdomain>/<code>

请注意上面的更新操作,

非常实用,因为ES在执行更新操作的时候会把旧的给覆盖掉,为了不被覆盖就需要针对旧数据进行复制操作。

  • 温馨提示:目前版本针对查询出最后一条并未有好的方案,JPA操作的方式,还是需要通过Top或者First,取出10条,通过OrderByXXX ,在结果集上使用 .get(0) 可以达到取最后的效果

安全认证

  • es官方在6.2以后的版本都不再提供x-pack了,相信大家也都看过或者查过了,那么看到本文章之后,请点个赞,本章提供一下相关的解决方案。
  • 直接提供代码了,新建TransportClientConfig.java
<code>
/**
* Es 6.3.2 使用TransPort 安全验证
*
* @author Mr.Hao
* @date 2020-04-23
*/
@Configuration
public class TransportClientConfig {
@Value("${spring.data.elasticsearch.cluster-name}")
private String clusterName;
@Value("${spring.data.elasticsearch.cluster-nodes}")
private String esIpPorts;
@Value("${spring.data.elasticsearch.header}")
private String header;
@Value("${spring.data.elasticsearch.username}")
private String username;

@Value("${spring.data.elasticsearch.password}")
private String password;
private TransportClient client;

@Bean
public TransportClient transportClient() throws UnknownHostException {
Settings settings = Settings.builder()
//关闭自动发现集群节点
.put("client.transport.sniff", false)
//设置请求头的Basic认证的Base64码
.put(header, "Basic " + Base64.encode(username + ":" + password))
//添加节点名称
.put("cluster.name", clusterName)
.build();

client = new PreBuiltTransportClient(settings);

String[] strings = esIpPorts.split(",");
for (String val : strings) {
String[] hostPort = val.split(":");
client.addTransportAddresses(
new TransportAddress(
InetAddress.getByName(hostPort[0]),
Integer.parseInt(hostPort[1])
)
);
}
return client;
}
}/<code>

到这就已经完全完成了通过Transport-TCP方式连接和操作ES,本文章为小篇辛苦编写和总结,真实的开发经验,希望大家可以关注一下默默学习的小作者;小篇会持续的输出实战的内容。


分享到:


相關文章: