Springboot整合Elasticsearch的初级基本操作
项目地址:https://gitee.com/libeimaningg/beizhilib
一、环境准备
1、添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>3.4.0</version>
</dependency>
注意与springboot版本一致,我的是3.4.3版本,jdk使用的是17版本。
2、Elasticsearch 配置
spring:
elasticsearch:
uris: http://localhost:9200
username: elastic
password: 123456
Elasticsearch的安装与启动参考文章:https://www.cnblogs.com/lbming/articles/18812746
二、使用ElasticsearchRepository进行操作支持
1、ElasticsearchRepository简介
- Spring Data 对 Elasticsearch 提供了 Repository 支持,其基本原理是根据方法名称自动构建查询,提供了更简便的数据搜索和分析功能。
- ElasticsearchRepository 是 Spring Data Elasticsearch 提供的一个接口,用于简化与 Elasticsearch 交互的操作。它继承自 CrudRepository 和 PagingAndSortingRepository,扩展了基本的 CRUD(创建、读取、更新、删除)功能,支持分页和排序,还提供了对 Elasticsearch 特有的操作支持。使用 ElasticsearchRepository,开发者可以快速构建功能全面的数据访问层,而无需编写复杂的 Elasticsearch 客户端代码。
2、作用和优点
- 简化数据操作:提供了基础的 CRUD 方法,如 save()、findById()、findAll() 和 deleteById() 等,方便开发者直接使用。
- 自定义查询:通过定义接口中的方法(如 findByName(String name)),可以自动生成符合方法命名规范的查询。
- 分页与排序:内置了分页和排序支持,方法如 findAll(Pageable pageable) 可以直接返回分页数据。
- 与 Spring 无缝集成:使用 Spring 的依赖注入和配置机制,无需手动创建或管理客户端连接。
- 减少代码复杂度:自动实现常用的数据库操作,减少重复代码,提高开发效率。
适用于开发中涉及到简单或中等复杂度的查询,使用方法命名约定生成查询即可满足需求的场景。
3、具体使用
(1)创建实体类
- @Document:作用在类上,标记实体类为文档对象。 indexName(索引名称,相当于数据库的表名称)
- @Id:作用在成员变量上,标记一个字段作为id主键。 在Elasticsearch中,文档ID是唯一的,用于标识文档。
- @Field:定义Java对象属性与Elasticsearch文档字段之间的映射关系。
@Document(indexName = "user_info")
@TableName(value = "sys_user")
@Data
public class SysUser implements Serializable {
/**
* 用户ID
*/
@Id
@TableId(type = IdType.AUTO)
private Long userId;
/**
* 部门ID
*/
@Field(name = "dept_id")
private Long deptId;
/**
* 用户账号
*/
@Field(name = "user_name")
private String userName;
/**
* 用户昵称
*/
@Field(name = "nick_name")
private String nickName;
}
(2)创建 Repository 接口
继承 ElasticsearchRepository,第一个参数为实体类,第二个参数为标记了@Id注解的数据类型
package org.beizhilib.biz.service.repository;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.beizhilib.common.core.domain.entity.SysUser;
/**
* TODO 类作用描述
*
* @author Bryson
* @date 2025/4/9
*/
public interface SysUserRepository extends ElasticsearchRepository<SysUser, Long> {
/**
* 方法命名规则查询,方法名必须遵守SpringData的规范
*/
List<SysUser> findByDeptId(Long deptId);
// 使用@Query注解自定义查询,字段名注意与@Field注解的一致
//Elasticsearch 查询时 term、match、match_phrase、match_phrase_prefix 的区别:https://cloud.tencent.com/developer/article/2472767
@Query("{\"match\": {\"dept_id\": {\"query\": \"?0\"}}}")
Page<SysUser> searchByDeptId(Long deptId, Pageable pageable);
// 分页查询
//注意导入正确的包:import org.springframework.data.domain.
Page<SysUser> findByDeptId(Long deptId, Pageable pageable);
}
(3)具体实现
① 插入一条数据
Controller层:
/**
* 插入一条数据
*
* @param user
* @return
*/
@PostMapping("/save")
public RestResult save(@RequestBody UserDto user) {
sysUserESService.saveRepository(user);
return new RestResult<>(RestResult.SUCCESS_CODE, "新增成功");
}
实现层:
@Override
public void saveRepository(UserDto user) {
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(user, sysUser);
sysUserRepository.save(sysUser);
}
测试结果


② 批量插入数据
Controller层:
/**
* 插入多条数据
*
* @param users
* @return
*/
@PostMapping("/saveAll")
public RestResult saveAll(@RequestBody List<UserDto> users) {
sysUserESService.saveAllRepository(users);
return new RestResult<>(RestResult.SUCCESS_CODE, "新增成功");
}
实现层:
@Override
public void saveAllRepository(List<UserDto> users) {
List<SysUser> sysUsers = new ArrayList<>();
for (UserDto user : users) {
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(user, sysUser);
sysUsers.add(sysUser);
}
sysUserRepository.saveAll(sysUsers);
}
测试结果


③ 删除一条数据
Controller层:
/**
* 删除一条数据
*
* @param user
* @return
*/
@PostMapping("/delete")
public RestResult delete(@RequestBody UserDto user) {
sysUserESService.deleteRepository(user);
return new RestResult<>(RestResult.SUCCESS_CODE, "删除成功");
}
实现层:
@Override
public void deleteRepository(UserDto user) {
//一次删除一个
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(user, sysUser);
//效果跟deleteById一样,都要传id
// sysUserRepository.delete(sysUser);
//一次删除一个,根据Id删除
//todo:id判空
sysUserRepository.deleteById(user.getUserId());
}
测试结果


④ 删除多条数据
Controller层:
/**
* 删除多条数据
*
* @param users
* @return
*/
@PostMapping("/deleteAll")
public RestResult deleteAll(@RequestBody List<UserDto> users) {
sysUserESService.deleteAll(users);
return new RestResult<>(RestResult.SUCCESS_CODE, "删除成功");
}
实现层:
@Override
public void deleteAll(List<UserDto> users) {
//一次删除多个
List<SysUser> sysUsers = new ArrayList<>();
for (UserDto userDto : users) {
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(userDto, sysUser);
sysUsers.add(sysUser);
}
//还是需要id
sysUserRepository.deleteAll(sysUsers);
//清空整个文档的数据并删除这个文档
// sysUserRepository.deleteAll();
}
测试结果


⑤ 更新数据
Controller层:
/**
* 更新数据
*
* @param user
* @return
*/
@PostMapping("/update")
public RestResult update(@RequestBody UserDto user) {
sysUserESService.updateRepository(user);
return new RestResult<>(RestResult.SUCCESS_CODE, "更新成功");
}
实现层:
@Override
public void updateRepository(UserDto user) {
//修改es中存在的数据 使用的仍然是save方法,当id一样时,会覆盖原来的数据,因此可用于修改数据。
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(user, sysUser);
sysUserRepository.save(sysUser);
}
测试结果


⑦ 使用自带方法查询数据
Controller层:
/**
* 使用自带方法查询数据
*
* @return
*/
@PostMapping("/findAll")
public RestResult<List<SysUser>> findAll() {
return new RestResult<>(RestResult.SUCCESS_CODE, "查询成功", sysUserESService.findAll());
}
实现层:
@Override
public List<SysUser> findAll() {
//todo:findAll的三种用法
//添加排序规则
Iterable<SysUser> all1 = sysUserRepository.findAll(Sort.by("userId").descending());
//添加分页规则
Page<SysUser> all2 = sysUserRepository.findAll(PageRequest.of(0, 3));
//添加排序规则和分页规则
Page<SysUser> all3 = sysUserRepository.findAll(PageRequest.of(0, 2, Sort.by("userId").descending()));
Iterable<SysUser> all = sysUserRepository.findAll();
return IteratorUtils.toList(all.iterator());
}
测试结果



⑧ 带查询条件分页查询数据
Controller层:
/**
* 带查询条件分页查询数据
*
* @return
*/
@PostMapping("/findByPage")
public RestResult<Page<SysUser>> findByPage(@RequestBody UserDto user) {
return new RestResult<>(RestResult.SUCCESS_CODE, "查询成功", sysUserESService.findByPage(user));
}
实现层:
@Override
public Page<SysUser> findByPage(UserDto user) {
//注意导入正确的包:import org.springframework.data.domain.
//PageIndex从0开始!!
Pageable pageable = PageRequest.of(user.getPageIndex(), user.getPageSize(), Sort.by("userId").descending());
Page<SysUser> userPage = sysUserRepository.findByDeptId(user.getDeptId(), pageable);
return userPage;
}
测试结果



⑨ DSL自定义查询
Controller层:
/**
* DSL自定义查询
*
* @param user
* @return
*/
@PostMapping("/searchByDsl")
public RestResult<Page<SysUser>> searchByDsl(@RequestBody UserDto user) {
return new RestResult<>(RestResult.SUCCESS_CODE, "查询成功", sysUserESService.searchByDsl(user));
}
实现层:
@Override
public Page<SysUser> searchByDsl(UserDto user) {
Pageable pageable = PageRequest.of(user.getPageIndex(), user.getPageSize());
Page<SysUser> userPage = sysUserRepository.searchByDeptId(user.getDeptId(), pageable);
return userPage;
}
测试结果




浙公网安备 33010602011771号