Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @Override
- public Page<UserOutput> filterUsers(UserFilterOptions userFilterOptions, Pageable pageable) {
- // Step 1: Build the dynamic query
- StringBuilder queryBuilder = new StringBuilder("SELECT NEW com.example.virtualwallet.models.dtos.user.UserOutput(");
- queryBuilder.append("u.id, u.username, u.email, u.phoneNumber, u.role, u.status, COALESCE(SUM(w.balance), 0) AS totalBalance) ");
- queryBuilder.append("FROM User u LEFT JOIN Wallet w ON u.id = w.owner.id WHERE 1=1 ");
- Map<String, Object> parameters = new HashMap<>();
- // Step 2: Add filters dynamically
- userFilterOptions.getUsername().ifPresent(username -> {
- queryBuilder.append("AND u.username LIKE :username ");
- parameters.put("username", "%" + username + "%");
- });
- userFilterOptions.getEmail().ifPresent(email -> {
- queryBuilder.append("AND u.email LIKE :email ");
- parameters.put("email", "%" + email + "%");
- });
- userFilterOptions.getPhoneNumber().ifPresent(phoneNumber -> {
- queryBuilder.append("AND u.phoneNumber LIKE :phoneNumber ");
- parameters.put("phoneNumber", "%" + phoneNumber + "%");
- });
- userFilterOptions.getRole().ifPresent(role -> {
- queryBuilder.append("AND u.role = :role ");
- parameters.put("role", role);
- });
- userFilterOptions.getAccountStatus().ifPresent(accountStatus -> {
- queryBuilder.append("AND u.status = :accountStatus ");
- parameters.put("accountStatus", accountStatus);
- });
- userFilterOptions.getMinTotalBalance().ifPresent(minTotalBalance -> {
- queryBuilder.append("AND (COALESCE(SUM(w.balance), 0) >= :minTotalBalance OR w IS NULL) ");
- parameters.put("minTotalBalance", minTotalBalance);
- });
- userFilterOptions.getMaxTotalBalance().ifPresent(maxTotalBalance -> {
- queryBuilder.append("AND (COALESCE(SUM(w.balance), 0) <= :maxTotalBalance OR w IS NULL) ");
- parameters.put("maxTotalBalance", maxTotalBalance);
- });
- // Step 3: Group by user ID to calculate total balance
- queryBuilder.append("GROUP BY u.id, u.username, u.email, u.phoneNumber, u.role, u.status ");
- // Step 4: Add sorting dynamically
- userFilterOptions.getSortBy().ifPresent(sortBy -> {
- queryBuilder.append("ORDER BY ").append(sortBy);
- userFilterOptions.getSortOrder().ifPresent(sortOrder ->
- queryBuilder.append(" ").append(sortOrder)
- );
- });
- // If no sorting is provided, apply default sorting by 'username ASC'
- if (!queryBuilder.toString().contains("ORDER BY")) {
- queryBuilder.append("ORDER BY u.username ASC");
- }
- // Step 5: Create the query
- TypedQuery<UserOutput> query = entityManager.createQuery(queryBuilder.toString(), UserOutput.class);
- // Step 5: Set parameters
- for (Map.Entry<String, Object> entry : parameters.entrySet()) {
- query.setParameter(entry.getKey(), entry.getValue());
- }
- // Step 6: Apply pagination
- query.setFirstResult((int) pageable.getOffset());
- query.setMaxResults(pageable.getPageSize());
- // Step 7: Execute the query and fetch results
- List<UserOutput> content = query.getResultList();
- // Step 8: Count total results for pagination
- long total = countFilteredUsers(userFilterOptions);
- // Step 9: Return paginated result
- return new PageImpl<>(content, pageable, total);
- }
- private long countFilteredUsers(UserFilterOptions userFilterOptions) {
- StringBuilder countQueryBuilder = new StringBuilder("SELECT COUNT(DISTINCT u.id) FROM User u LEFT JOIN Wallet w ON u.id = w.owner.id WHERE 1=1 ");
- Map<String, Object> parameters = new HashMap<>();
- userFilterOptions.getUsername().ifPresent(username -> {
- countQueryBuilder.append("AND u.username LIKE :username ");
- parameters.put("username", "%" + username + "%");
- });
- userFilterOptions.getEmail().ifPresent(email -> {
- countQueryBuilder.append("AND u.email LIKE :email ");
- parameters.put("email", "%" + email + "%");
- });
- userFilterOptions.getPhoneNumber().ifPresent(phoneNumber -> {
- countQueryBuilder.append("AND u.phoneNumber LIKE :phoneNumber ");
- parameters.put("phoneNumber", "%" + phoneNumber + "%");
- });
- userFilterOptions.getRole().ifPresent(role -> {
- countQueryBuilder.append("AND u.role = :role ");
- parameters.put("role", role);
- });
- userFilterOptions.getAccountStatus().ifPresent(accountStatus -> {
- countQueryBuilder.append("AND u.status = :accountStatus ");
- parameters.put("accountStatus", accountStatus);
- });
- userFilterOptions.getMinTotalBalance().ifPresent(minTotalBalance -> {
- countQueryBuilder.append("AND (COALESCE(SUM(w.balance), 0) >= :minTotalBalance OR w IS NULL) ");
- parameters.put("minTotalBalance", minTotalBalance);
- });
- userFilterOptions.getMaxTotalBalance().ifPresent(maxTotalBalance -> {
- countQueryBuilder.append("AND (COALESCE(SUM(w.balance), 0) <= :maxTotalBalance OR w IS NULL) ");
- parameters.put("maxTotalBalance", maxTotalBalance);
- });
- // Create and execute the count query
- Query countQuery = entityManager.createQuery(countQueryBuilder.toString());
- for (Map.Entry<String, Object> entry : parameters.entrySet()) {
- countQuery.setParameter(entry.getKey(), entry.getValue());
- }
- // Handle empty results gracefully
- try {
- Number countResult = (Number) countQuery.getSingleResult();
- return countResult.longValue();
- } catch (NoResultException | NullPointerException e) {
- return 0; // Return 0 if no results are found
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment