Spring boot Springboot:使用实体的多个特征搜索实体列表的最佳方法是什么

Spring boot Springboot:使用实体的多个特征搜索实体列表的最佳方法是什么,spring-boot,search,spring-data-jpa,Spring Boot,Search,Spring Data Jpa,我正在SpringBoot中开发一个web应用程序,用户可以使用搜索字段搜索用户。根据输入字段中键入的值搜索的用户将根据其用户名、名字和姓氏进行查询。这是我的用户模型: @Component @Entity @Table(name = "Users") public class User extends DefaultEntity { @Column(name = "FirstName") @NotNull(message = "Enter a FirstName")

我正在SpringBoot中开发一个web应用程序,用户可以使用搜索字段搜索用户。根据输入字段中键入的值搜索的用户将根据其用户名、名字和姓氏进行查询。这是我的用户模型:

    @Component
@Entity
@Table(name = "Users")
public class User extends DefaultEntity {


    @Column(name = "FirstName")
    @NotNull(message = "Enter a FirstName")
    private String firstName;


    @Column(name = "LastName")
    @NotBlank(message = "Enter a LastName")
    private String lastName;


    @Column(unique = true,name = "UserName")
    @NotBlank(message = "Enter a UserName")
    private String userName;


    @Column(unique = true, name = "Email")
    @NotBlank(message = "Please enter an Email address")
    @Email(message = "Enter a valid Email")
    private String email;


    @Column(name = "Password")
    @NotBlank(message = "Enter a Password")
    private String password;


    @Enumerated(EnumType.STRING)
    @Column(name = "Gender")
    private Gender gender;


    @Column(name = "Address")
    @NotBlank(message = "Please enter your Home Address")
    private String address;


    @Column(name = "Country")
    @NotBlank(message = "Please enter your Country")
    private String country;


    @Column(name = "Picture")
    private String picture;


    @Column(unique = true, name = "PhoneNumber") //make this accept only numbers
    private String phoneNumber;


    @Column(name = "Bio")
    private String bio;


    @Enumerated(EnumType.STRING)
    @Column(name = "OnlineStatus")
    private OnlineStatus onlineStatus;

    @Enumerated(EnumType.STRING)
    @Column(name = "UserType")
    private UserType userType;


    @Column(name = "Money")
    private double money;


    //@MapsId()
    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name = "playerstats")
    private PlayerStats playerStats;

    //columnDefinition = "tinyint default false"
    @Column(name = "locked",columnDefinition = "BOOL default false")
    private Boolean locked;



    @Transient
    private MultipartFile file;


    public String getFirstName() {
        return firstName;
    }

    public User setFirstName(String firstName) {
        this.firstName = firstName;
        return this;
    }

    public String getLastName() {
        return lastName;
    }

    public User setLastName(String lastName) {
        this.lastName = lastName;
        return this;
    }

    public String getUserName() {
        return userName;
    }

    public User setUserName(String userName) {
        this.userName = userName;
        return this;
    }

    public String getEmail() {
        return email;
    }

    public User setEmail(String email) {
        this.email = email;
        return this;
    }

    public String getPassword() {
        return password;
    }

    public User setPassword(String password) {
        this.password = password;
        return this;
    }

    public Enum.Gender getGender() {
        return gender;
    }

    public User setGender(Enum.Gender gender) {
        this.gender = gender;
        return this;
    }

    public String getAddress() {
       return address;
    }

    public User setAddress(String address) {
       this.address = address;
       return this;
    }

    public String getCountry() {
        return country;
    }

    public User setCountry(String country) {
        this.country = country;
        return this;
    }

    public String getPicture() {
        return picture;
    }

    public User setPicture(String picture) {
        this.picture = picture;
        return this;
    }

    public String getBio() {
        return bio;
    }

    public User setBio(String bio) {
        this.bio = bio;
        return this;
    }

    public Enum.OnlineStatus getOnlineStatus() {
        return onlineStatus;
    }

    public User setOnlineStatus(Enum.OnlineStatus onlineStatus) {
        this.onlineStatus = onlineStatus;
        return this;
    }

    public Enum.UserType getUserType() {
        return userType;
    }

    public User setUserType(Enum.UserType userType) {
        this.userType = userType;
        return this;
    }

    public double getMoney() {
        return money;
    }

    public User setMoney(double money) {
        this.money = money;
        return this;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public User setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
        return this;
    }

    public MultipartFile getFile() {
        return file;
    }

    public User setFile(MultipartFile file) {
        this.file = file;
        return this;
    }

    public PlayerStats getPlayerStats() {
        return playerStats;
    }

    public User setPlayerStats(PlayerStats playerStats) {
        this.playerStats = playerStats;
        return this;
    }

    public Boolean getLocked() {
        return locked;
    }

    public void setLocked(Boolean locked) {
        this.locked = locked;
    }

}
这是我在UserRepository中查询usermodel的方法:

    @Repository
public interface UserRepository extends JpaRepository<User,Long> {


    Page<User> findUsersByUserNameContainingOrFirstNameContainingOrLastNameContaining(String UserName, String FirstName, String LastName, Pageable pageable);

}

我的问题是:有没有更好或更有效的方法来实现对用户实体的查询?

如评论中所述,您正在寻找的是模糊搜索。这不是在数据库中可以轻松完成的事情,但您可以使用单独的搜索引擎:

基于apachelucene的apachesolr平台 弹性搜索 Hibernate搜索Hibernate与ApacheLucene的集成 ... 当使用这种解决方案时,您还必须将实体索引到搜索引擎中。Spring数据可以帮助您做到这一点,因为它还存在

首先,您需要一个新类来表示实体在Solr中的外观。请注意,如果要使用嵌套关系,则需要展平所有对象:

@文件 公共类用户文档{ @身份证 @Indexeded 私有字符串id; @IndexedfirstName 私有字符串名; @IndexedlastName 私有字符串lastName; @IndexeduserName 私有字符串用户名; // ... } 之后,您可以编写一个存储库,就像您习惯于使用Spring数据一样:

公共接口UserDocumentRepository扩展了SolrCrudeRepository{ @QueryuserName:?0或firstName:?0或lastName:?0 列出findAllString搜索项; } 之后,您可以执行以下操作:

公共用户创建用户输入{ //在数据库中创建用户 documentRepository.savenew UserDocumentinput.getFirstName、input.getLastName、input.getUserName; } 您还可以使用存储库查询模糊搜索:

documentRepository.findAllvickz~3; 这将使用我刚刚编写的查询,并将查找包含vickz的名字、姓氏或用户名。末尾的~3表示名称可以是3个不同于我刚才使用的字符=编辑距离

但是,这将返回UserDocument Solr实体。如果要获取实体,还必须查找它们,这可以通过它们的用户名完成:

列出用户名=documentRepository .findAllvickz~3 流动 .mapUserDocument::getUserName .toList; repository.findByUsernameusernames;//在数据库中查找与这些用户名匹配的用户
嗨,你能告诉我们你为什么期待一种“更高效”的方式吗?您对实际解决方案的担忧是什么?@Vyncent我需要更高效的解决方案,因为如果我有一个用户名为vic、名为victor、名为clinton的用户。我在找vickz这个名字…它找不到victor。我想要一种算法,即使名称拼写不正确,也能找到与实际名称相近的名称。事实上,你想做一些模糊匹配吗?你要找的比普通数据库通常能提供的更多。您应该寻找类似ApacheLucene的东西,可能与Hibernate搜索或ApacheSolr结合使用。它们提供了诸如开箱即用的模糊搜索之类的功能,并允许您根据匹配的程度对用户进行排序。然而,详细解释要比在堆栈溢出上发布的内容占用更多的空间,因此我认为这个问题可能太宽泛而无法回答。@appzone_oto模糊匹配基本上就是您所解释的,您可以查找vickz,它将返回victor。