当前位置: 首页 > 知识库问答 >
问题:

使用 JPA 提取表记录时,使用多个列作为筛选器

赏光霁
2023-03-14

我正在创建一个包含一个用户实体的Spring Boot应用程序。

我想实现一个功能,管理员可以使用不同的过滤器搜索用户,过滤器可以是用户表中的一列或多列。

下面是用户实体类:

@Getter
@Setter
@Entity
@Table(name = "users")
public class UserEntity {

    @Id
    @Column(name = "user_id", nullable = false, unique = true, length = 10)
    private String userId;

    @Column(name = "user_first_name", nullable = false, length = 20)
    private String userFirstName;

    @Column(name = "user_middle_name", length = 20)
    private String userMiddleName;

    @Column(name = "user_last_name", nullable = false, length = 20)
    private String userLastName;

    @Column(name = "user_contact", nullable = false, unique = true, length = 10)
    private Long userContact;

    @Column(name = "user_email", nullable = false, unique = true, length = 50)
    private String userEmail;

    @Column(name = "user_password", nullable = false)
    private String userPassword;

    @Column(name = "user_enabled", nullable = false)
    private Boolean userEnabled;

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "user_roles",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "role_id")
    )
    private Set<RoleEntity> userRoles;

    @OneToMany(mappedBy = "tokenUser", fetch = FetchType.LAZY)
    private Set<TokenEntity> userTokens;

    @Temporal(TemporalType.DATE)
    @Column(name = "last_updated_on", nullable = false)
    private Date lastUpdatedOn;

    @Column(name = "last_updated_by", nullable = false)
    private String lastUpdatedBy;

    @Temporal(TemporalType.DATE)
    @Column(name = "created_on", nullable = false)
    private Date createdOn;

    @Column(name = "created_by", nullable = false)
    private String createdBy;
}

搜索用户时,只有名字可以是筛选器,或者在某些时候,名字和姓氏都可以是筛选器,或者如果需要,其他一些列值(ID、电子邮件和联系人)也可以与它们一起用作筛选器。筛选器的选择将完全是管理员在运行时的选择。

有人能指导我如何使用JPA和Spring Boot实现此功能吗?

下面分别是我的控制器类、服务和存储库类。

用户控制器

@RestController
@RequestMapping("/bma/api/admin/users")
public class UserController {

    @Autowired
    private UserService userService;

    private final int DEFAULT_PAGE_NUMBER = 1;
    private final int DEFAULT_PAGE_SIZE = 5;

    @GetMapping("/all")
    public ResponseEntity<?> getAllUsers(
            @RequestParam(name = "page_number", required = false) Integer pageNumber,
            @RequestParam(name = "page_size", required = false) Integer pageSize) {
        try {
            if (pageNumber == null) pageNumber = DEFAULT_PAGE_NUMBER;
            if (pageSize == null) pageSize = DEFAULT_PAGE_SIZE;
            List<UserResponseModel> responseModels = userService.getAllUserList(pageNumber-1, pageSize);
            GetAllDataResponseMetadata metadata = new GetAllDataResponseMetadata(HttpStatus.FOUND.value(),
                    pageNumber, pageSize);
            return ResponseEntity.status(HttpStatus.FOUND).body(new SuccessResponse<>(metadata, responseModels));
        }
        catch (NoRecordAvailableException exception) {
            CommonResponseMetadataWithMessage metadata =
                    new CommonResponseMetadataWithMessage(HttpStatus.NOT_FOUND.value(), exception.getMessage());
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ErrorResponse<>(metadata));
        }
    }
}

用户服务

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    public UserResponseModel addNewUser(UserRequestModel userRequestModel) {
        if (userRepository.existsUserEntityByUserContact(userRequestModel.getUserContact())) {
            throw new InformationAlreadyExistsException("Contact Number Already Exists");
        }
        else if (userRepository.existsUserEntityByUserEmail(userRequestModel.getUserEmail())) {
            throw new InformationAlreadyExistsException("Email Already Exists");
        }
        else {
            UserDetailsValidationUtility.isEmailValid(userRequestModel.getUserEmail());
            UserDetailsValidationUtility.isContactNumberValid(userRequestModel.getUserContact());
            UserDetailsValidationUtility.isNameValid(userRequestModel.getUserFirstName(), false);
            UserDetailsValidationUtility.isNameValid(userRequestModel.getUserLastName(), false);
            UserDetailsValidationUtility.isNameValid(userRequestModel.getUserMiddleName(), true);
            UserDetailsValidationUtility.isPasswordValid(userRequestModel.getUserPassword());

            UserEntity newUserEntity = getUserEntityFromModel(userRequestModel);
            return getUserResponseModelFromEntity(userRepository.save(newUserEntity));
        }
    }

    public List<UserResponseModel> getAllUserList(int pageNumber, int PageSize) {
        Pageable pageWithSpecificNumberOfRecord = PageRequest.of(pageNumber, PageSize);
        Page<UserEntity> userEntities = userRepository.findAll(pageWithSpecificNumberOfRecord);
        if (userEntities.isEmpty()) {
            throw new NoRecordAvailableException("No User Record Available");
        }
        else {
            List<UserResponseModel> userResponseModels = new ArrayList<>();
            userEntities.forEach(userEntity ->
                    userResponseModels.add(getUserResponseModelFromEntity(userEntity)));
            return userResponseModels;
        }
    }

    private UserResponseModel getUserResponseModelFromEntity(UserEntity existingUserEntity) {
        UserResponseModel responseModel = new UserResponseModel();
        responseModel.setUserId(existingUserEntity.getUserId());
        responseModel.setUserFullName(buildFullNameOfUser(existingUserEntity));
        responseModel.setUserContact(existingUserEntity.getUserContact());
        responseModel.setUserEmail(existingUserEntity.getUserEmail());
        return responseModel;
    }

    private UserEntity getUserEntityFromModel(UserRequestModel userRequestModel) {
        Date currentDateTime = BankManagementUtility.getCurrentDateTime();
        String userId = generateUserId();

        UserEntity newUserEntity = new UserEntity();
        newUserEntity.setUserId(userId);
        newUserEntity.setUserFirstName(userRequestModel.getUserFirstName().trim());
        if (userRequestModel.getUserMiddleName() == null)
            newUserEntity.setUserMiddleName("");
        else newUserEntity.setUserMiddleName(userRequestModel.getUserMiddleName().trim());
        newUserEntity.setUserLastName(userRequestModel.getUserLastName().trim());
        newUserEntity.setUserContact(userRequestModel.getUserContact());
        newUserEntity.setUserEmail(userRequestModel.getUserEmail().trim());
        newUserEntity.setUserPassword(passwordEncoder.encode(userRequestModel.getUserPassword().trim()));
        newUserEntity.setUserEnabled(false);
        newUserEntity.setLastUpdatedOn(currentDateTime);
        newUserEntity.setLastUpdatedBy(userId);
        newUserEntity.setCreatedOn(currentDateTime);
        newUserEntity.setCreatedBy(userId);

        newUserEntity.setUserTokens(new HashSet<>());
        newUserEntity.setUserRoles(new HashSet<>());
        newUserEntity.getUserRoles().add(roleRepository.findRoleEntityByRoleName("USER"));

        return newUserEntity;
    }

    private String generateUserId() {
        StringBuilder userId = new StringBuilder("USER");
        userId.append(BankManagementUtility.generateNumberIdNumberByDigit(6));
        if (userRepository.existsUserEntityByUserId(userId.toString())) {
            return generateUserId();
        }
        else return userId.toString();
    }

    private String buildFullNameOfUser(UserEntity userEntity) {
        StringBuilder fullName = new StringBuilder(userEntity.getUserFirstName());
        if (!userEntity.getUserMiddleName().isEmpty()) {
            fullName.append(" ");
            fullName.append(userEntity.getUserMiddleName());
        }
        fullName.append(" ");
        fullName.append(userEntity.getUserLastName());
        return fullName.toString();
    }
}

用户知识库

@Repository
public interface UserRepository extends JpaRepository<UserEntity, String> {

    UserEntity findUserEntityByUserEmail(String email);
    UserEntity findUserEntityByUserId(String id);

    Boolean existsUserEntityByUserId(String id);
    Boolean existsUserEntityByUserEmail(String email);
    Boolean existsUserEntityByUserContact(Long contact);
}

如果有人想查看整个项目,这里还有GitHub存储库链接:

https://github . com/rajeshsinha 1997/centrazed _ Banking _ System _ Application

除上述查询外,如果有人对代码或项目有任何其他建议/建议,将予以通知。

共有1个答案

尹昂雄
2023-03-14

我认为最好的方法是创建另一个endpoint,它接收带有搜索条件的JSON对象。例如:

{
    "userFilter": {
        "userId": "1",
        "userFirstName": "John",
        "userLastName": "Doe",
        "userEmail": "john.doe@johndoe.com"
    }
}

在终结点中,将所有“null”属性替换为“*”。这样,您可以生成一个查询,其中将返回特定属性的所有数据(如果它不是筛选器参数的一部分)。

@PostMapping("/filter")
public ResponseEntity<?> filterUsers(@RequestBody UserFilter userFilter) {
    if(userFilter.getUserId() == null) {
        userFilter.setUserId("*");
    }
    // ... do this for all parameters of userFilter ...
    return ResponseEntity.body(userService.filterUsers(userFilter.getId(), userFilter.getUserFirstName(), userfilter.getUserLastName(), userFilter.getUserEmail()));
}

然后,在存储库中,我会这样做:

@Query("SELECT u FROM User u WHERE u.id like CONCAT('%', :id, '%') and u.first_name like CONCAT('%', :firstName, '%') and u.last_name like CONCAT('%', :lastName, '%') and u.email like CONCAT('%', :email, '%')")
List<User> filterUsers(@Param("id") Integer id, @Param("firstName") String firstName, @Param("lastName") String lastName, @Param("email") String userEmail); 

有关 JPQL 的参考:https://www.baeldung.com/spring-data-jpa-query

 类似资料:
  • 应用筛选器之前的示例使用者记录是(在值中查找GP_ID): 当我在kafkaListenerContainerFactory()中按如下方式设置recordFilterStrategy时: KafKareCordvo.ConvertByteBufferToLong正在将bytebuffer值转换为long值。 但是,当它被Kafka听众按以下方式消费时: 这将返回删除我筛选的字段值的记录:“gp_

  • 我需要过滤一个列表

  • 首先,我试图使选择所有复选框,如果我单击表头中的选择所有复选框,整个表行将选择并显示一个复选框反向消息,即我选择了多少复选框。这里的问题是,如果我单击select all复选框,反向消息不会显示楼上的表,即我选择了多少行。 其次,如果我从任何列中筛选任何数字,相同的数字将显示同一列中有多少行具有相同的数字。如果我选中了所有复选框,那么反向消息将显示我选中了多少行复选框。这里,问题是显示整个表行计数

  • 问题内容: 我想要从表中选择记录,或将它们插入新的空白表中,其中多个列与数据库中的另一条记录相同。问题类似于此问题。 在MySQL中查找重复记录 但是,仅比较一列。另外,我的一列,例如下面的示例中的C列,是整数。就像上面链接中的问题一样,我希望返回每一行。不幸的是,我对联接如何如何自行解决还不够熟悉。我知道下面的代码与实际的SQL代码完全不同,这只是我可以想到的最清晰的方式来描述我要进行的比较。

  • 我正在使用谷歌表单的过滤功能,但无法按我想要的方式使用,已经3天了。。。 基本上,我有第1页,有一列“电子邮件”和一列“潜在客户ID”。表2具有相同的“潜在客户ID”,但已过滤。含义,第1页,其“顺序为1,2,3,4,5…”。。。第二张不是,像是2,4,5,23,41。。。我想在表1中找到正确的电子邮件地址,该地址在两个表中具有相同的Lead ID。我使用了Filter函数,它工作得非常好,因为它

  • 如何使用RxJava过滤项目列表? 我有以下代码,发出: 并且我想在之后应用筛选器。您可以在下一段代码中看到我的解决方案,但也许还有更好的方法?