Spring Data是一个用于简化数据库、非关系型数据库、索引库访问,并支持云服务的开源框架。
其主要目标是使得对数据的访问变得方便快捷,并支持 map reduce 框架和云计算数据服务。
Spring Data 可以极大的简化 JPA Elasticsearch …)的写法,可以在几乎不用写实现的情况下,实现对数据的访问和操作。
除了 CRUD 外,还包括如分页、排序等一些常用的功能。
Spring Data的官网:
https://spring.io/projects/spring-data
Spring Data常用的功能模块如下:
Spring Data Elasticsearch基于 spring data API 简化 Elasticsearch 操作,将原始操作Elasticsearch 的客户端 API 进行封装 。 Spring Data 为 Elasticsearch 项目提供集成搜索引擎。
Spring Data Elasticsearch POJO 的关键功能区域为中心的模型与 Elastichsearch 交互文档和轻松地编写一个存储索引库数据访问层。
官方网站:
Spring Data Elasticsearch
目前最新springboot 对应 Elasticsearch7.6.2 Spring boot2.3.x 一般可以兼容 Elasticsearch7.x
1.4 框架集成 1.4.1 pom4.0.0org.springframework.bootspring-boot-starter-parent2.3.6.RELEASEcom.bestbest-es0.0.1-SNAPSHOTbest-esDemo project for Spring Boot8 8org.projectlomboklombok1.16.12org.springframework.bootspring-boot-starterorg.springframework.bootspring-boot-starter-data-elasticsearchorg.springframework.bootspring-boot-devtoolsruntimetrueorg.springframework.bootspring-boot-starter-testtestorg.elasticsearchelasticsearch7.8.0org.elasticsearch.clientelasticsearch-rest-high-level-client7.8.0org.apache.logging.log4jlog4j-api2.8.2org.apache.logging.log4jlog4j-core2.8.2com.fasterxml.jackson.corejackson-databind2.9.9junitjunit4.12org.springframework.bootspring-boot-testorg.springframeworkspring-testorg.springframework.bootspring-boot-maven-plugin1.4.2 yaml
# 端口号 server: port: 8080 # es服务地址与端口 elasticsearch: host: 127.0.0.1 port: 9200 # 配置日志级别,开启debug日志 logging: level: com: best: debug1.4.3 数据实体类
@Data @NoArgsConstructor @AllArgsConstructor @ToString @Document(indexName = "shopping", shards = 3, replicas = 1) public class Product { // 商品唯一标识, 必须有id, 这里的id 是全局唯一的标识,等同于es中的"_id" @Id private Long id; /** * type: 字段数据类型 * analyzer: 分词器类型 * index: 是否索引(默认:true) * Keyword: 短语, 不进行分词 */ // 商品名称 @Field(type = FieldType.Text, analyzer = "ik_max_word") private String title; // 分类名称 @Field(type = FieldType.Keyword) private String category; // 商品价格 @Field(type = FieldType.Double) private Double price; // 图片地址 @Field(type = FieldType.Keyword, index = false) private String images; }1.4.4 配置类
ElasticsearchRestTemplate是spring-data-elasticsearch项目中的一个类,和其他spring项目中的 template类似。
在新版的spring-data-elasticsearch 中,ElasticsearchRestTemplate 代替了原来的ElasticsearchTemplate。
原因是ElasticsearchTemplate基于TransportClient,TransportClient即将在8.x 以后的版本中移除。所以,我们推荐使用ElasticsearchRestTemplate。
ElasticsearchRestTemplate基于RestHighLevelClient客户端的。需要自定义配置类,继承AbstractElasticsearchConfiguration,
并实现elasticsearchClient()抽象方法,创建RestHighLevelClient对象。
AbstractElasticsearchConfiguration源码:
public abstract class AbstractElasticsearchConfiguration extends ElasticsearchConfigurationSupport { //需重写本方法 public abstract RestHighLevelClient elasticsearchClient(); @Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" }) public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter elasticsearchConverter) { return new ElasticsearchRestTemplate(elasticsearchClient(), elasticsearchConverter); } }
需要自定义配置类,继承AbstractElasticsearchConfiguration,并实现elasticsearchClient()抽象方法,创建RestHighLevelClient对象。
@Data @Configuration @ConfigurationProperties(prefix = "elasticsearch") public class ElasticsearchConfig extends AbstractElasticsearchConfiguration { private String host; private Integer port; @Override public RestHighLevelClient elasticsearchClient() { RestClientBuilder builder = RestClient.builder(new HttpHost(host, port)); return new RestHighLevelClient(builder); } }1.4.5 Dao数据访问对象
@Repository public interface ProductDao extends ElasticsearchRepository { }1.4.6 索引操作
@SpringBootTest class BestEsApplicationTests { @Autowired private ElasticsearchRestTemplate elasticsearchRestTemplate; @Test public void creatIndex() { // 创建索引并增加映射配置 // 创建索引,系统初始化会自动创建索引 System.out.println("创建索引"); } @Test public void deleteIndex() { boolean flag = elasticsearchRestTemplate.deleteIndex(Product.class); System.out.println("删除索引: " + flag); } }
@SpringBootTest public class SpringDataEsProductDaoTest { @Autowired private ProductDao productDao; /** * 新增 */ @Test public void save(){ Product product = new Product(); product.setId(2L); product.setTitle("华为手机"); product.setCategory("手机"); product.setPrice(2999.0); product.setImages("http://www.test/hw.jpg"); productDao.save(product); } //POSTMAN, GET http://localhost:9200/shopping/_doc/2 //修改 @Test public void update(){ Product product = new Product(); product.setId(2L); product.setTitle("小米 2 手机"); product.setCategory("手机"); product.setPrice(9999.0); product.setImages("http://www.test/xm.jpg"); productDao.save(product); } //POSTMAN, GET http://localhost:9200/shopping/_doc/2 //根据 id 查询 @Test public void findById(){ Product product = productDao.findById(2L).get(); System.out.println(product); } @Test public void findAll(){ Iterableproducts = productDao.findAll(); for (Product product : products) { System.out.println(product); } } //删除 @Test public void delete(){ Product product = new Product(); product.setId(2L); productDao.delete(product); } //POSTMAN, GET http://localhost:9200/shopping/_doc/2 //批量新增 @Test public void saveAll(){ ListproductList = new ArrayList<>(); for (int i = 0; i < 10; i++) { Product product = new Product(); product.setId(Long.valueOf(i)); product.setTitle("["+i+"]小米手机"); product.setCategory("手机"); product.setPrice(1999.0 + i); product.setImages("http://www.test/xm.jpg"); productList.add(product); } productDao.saveAll(productList); } //分页查询 @Test public void findByPageable(){ //设置排序(排序方式,正序还是倒序,排序的 id) Sort sort = Sort.by(Sort.Direction.DESC,"id"); int currentPage=0;//当前页,第一页从 0 开始, 1 表示第二页 int pageSize = 5;//每页显示多少条 //设置查询分页 PageRequest pageRequest = PageRequest.of(currentPage, pageSize,sort); //分页查询 PageproductPage = productDao.findAll(pageRequest); for (Product Product : productPage.getContent()) { System.out.println(Product); } } }
@SpringBootTest public class SpringDataEsSearchTest { @Autowired private ProductDao productDao; /** * term 查询 * search(termQueryBuilder) 调用搜索方法,参数查询构建器对象 */ @Test public void termQuery(){ TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "小米"); Iterableproducts = productDao.search(termQueryBuilder); for (Product product : products) { System.out.println(product); } } /** * term 查询加分页 */ @Test public void termQueryByPage(){ int currentPage= 0 ; int pageSize = 5; //设置查询分页 PageRequest pageRequest = PageRequest.of(currentPage, pageSize); TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("category", "手机"); Iterableproducts = productDao.search(termQueryBuilder,pageRequest); for (Product product : products) { System.out.println(product); } } }
视频教程、参考博客