每一年都奔走在自己热爱里 没有人是一座孤岛,总有谁爱着你

岁
万
月
12

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);
    }

测试结果
image

image


② 批量插入数据

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);
    }

测试结果
image

image


③ 删除一条数据

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());
    }

测试结果
image

image


④ 删除多条数据

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();

    }

测试结果
image

image


⑤ 更新数据

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);
    }

测试结果
image

image


⑦ 使用自带方法查询数据

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());
    }

测试结果
image

image

image


⑧ 带查询条件分页查询数据

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;
    }

测试结果
image

image

image


⑨ 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;
    }

测试结果
image

image

image


posted @ 2025-04-14 09:05  果咩那塞  阅读(7)  评论(0)    收藏  举报