Georgi_Benchev

Untitled

Mar 4th, 2025
964
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.08 KB | None | 0 0
  1.   @Override
  2.     public Page<UserOutput> filterUsers(UserFilterOptions userFilterOptions, Pageable pageable) {
  3.         // Step 1: Build the dynamic query
  4.         StringBuilder queryBuilder = new StringBuilder("SELECT NEW com.example.virtualwallet.models.dtos.user.UserOutput(");
  5.         queryBuilder.append("u.id, u.username, u.email, u.phoneNumber, u.role, u.status, COALESCE(SUM(w.balance), 0) AS totalBalance) ");
  6.         queryBuilder.append("FROM User u LEFT JOIN Wallet w ON u.id = w.owner.id WHERE 1=1 ");
  7.  
  8.         Map<String, Object> parameters = new HashMap<>();
  9.  
  10.         // Step 2: Add filters dynamically
  11.         userFilterOptions.getUsername().ifPresent(username -> {
  12.             queryBuilder.append("AND u.username LIKE :username ");
  13.             parameters.put("username", "%" + username + "%");
  14.         });
  15.  
  16.         userFilterOptions.getEmail().ifPresent(email -> {
  17.             queryBuilder.append("AND u.email LIKE :email ");
  18.             parameters.put("email", "%" + email + "%");
  19.         });
  20.  
  21.         userFilterOptions.getPhoneNumber().ifPresent(phoneNumber -> {
  22.             queryBuilder.append("AND u.phoneNumber LIKE :phoneNumber ");
  23.             parameters.put("phoneNumber", "%" + phoneNumber + "%");
  24.         });
  25.  
  26.         userFilterOptions.getRole().ifPresent(role -> {
  27.             queryBuilder.append("AND u.role = :role ");
  28.             parameters.put("role", role);
  29.         });
  30.  
  31.         userFilterOptions.getAccountStatus().ifPresent(accountStatus -> {
  32.             queryBuilder.append("AND u.status = :accountStatus ");
  33.             parameters.put("accountStatus", accountStatus);
  34.         });
  35.  
  36.         userFilterOptions.getMinTotalBalance().ifPresent(minTotalBalance -> {
  37.             queryBuilder.append("AND (COALESCE(SUM(w.balance), 0) >= :minTotalBalance OR w IS NULL) ");
  38.             parameters.put("minTotalBalance", minTotalBalance);
  39.         });
  40.  
  41.         userFilterOptions.getMaxTotalBalance().ifPresent(maxTotalBalance -> {
  42.             queryBuilder.append("AND (COALESCE(SUM(w.balance), 0) <= :maxTotalBalance OR w IS NULL) ");
  43.             parameters.put("maxTotalBalance", maxTotalBalance);
  44.         });
  45.  
  46.         // Step 3: Group by user ID to calculate total balance
  47.         queryBuilder.append("GROUP BY u.id, u.username, u.email, u.phoneNumber, u.role, u.status ");
  48.  
  49.         // Step 4: Add sorting dynamically
  50.         userFilterOptions.getSortBy().ifPresent(sortBy -> {
  51.             queryBuilder.append("ORDER BY ").append(sortBy);
  52.             userFilterOptions.getSortOrder().ifPresent(sortOrder ->
  53.                     queryBuilder.append(" ").append(sortOrder)
  54.             );
  55.         });
  56.  
  57.         // If no sorting is provided, apply default sorting by 'username ASC'
  58.         if (!queryBuilder.toString().contains("ORDER BY")) {
  59.             queryBuilder.append("ORDER BY u.username ASC");
  60.         }
  61.  
  62.         // Step 5: Create the query
  63.         TypedQuery<UserOutput> query = entityManager.createQuery(queryBuilder.toString(), UserOutput.class);
  64.  
  65.         // Step 5: Set parameters
  66.         for (Map.Entry<String, Object> entry : parameters.entrySet()) {
  67.             query.setParameter(entry.getKey(), entry.getValue());
  68.         }
  69.  
  70.         // Step 6: Apply pagination
  71.         query.setFirstResult((int) pageable.getOffset());
  72.         query.setMaxResults(pageable.getPageSize());
  73.  
  74.         // Step 7: Execute the query and fetch results
  75.         List<UserOutput> content = query.getResultList();
  76.  
  77.         // Step 8: Count total results for pagination
  78.         long total = countFilteredUsers(userFilterOptions);
  79.  
  80.         // Step 9: Return paginated result
  81.         return new PageImpl<>(content, pageable, total);
  82.     }
  83.  
  84.     private long countFilteredUsers(UserFilterOptions userFilterOptions) {
  85.         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 ");
  86.  
  87.         Map<String, Object> parameters = new HashMap<>();
  88.  
  89.         userFilterOptions.getUsername().ifPresent(username -> {
  90.             countQueryBuilder.append("AND u.username LIKE :username ");
  91.             parameters.put("username", "%" + username + "%");
  92.         });
  93.  
  94.         userFilterOptions.getEmail().ifPresent(email -> {
  95.             countQueryBuilder.append("AND u.email LIKE :email ");
  96.             parameters.put("email", "%" + email + "%");
  97.         });
  98.  
  99.         userFilterOptions.getPhoneNumber().ifPresent(phoneNumber -> {
  100.             countQueryBuilder.append("AND u.phoneNumber LIKE :phoneNumber ");
  101.             parameters.put("phoneNumber", "%" + phoneNumber + "%");
  102.         });
  103.  
  104.         userFilterOptions.getRole().ifPresent(role -> {
  105.             countQueryBuilder.append("AND u.role = :role ");
  106.             parameters.put("role", role);
  107.         });
  108.  
  109.         userFilterOptions.getAccountStatus().ifPresent(accountStatus -> {
  110.             countQueryBuilder.append("AND u.status = :accountStatus ");
  111.             parameters.put("accountStatus", accountStatus);
  112.         });
  113.  
  114.         userFilterOptions.getMinTotalBalance().ifPresent(minTotalBalance -> {
  115.             countQueryBuilder.append("AND (COALESCE(SUM(w.balance), 0) >= :minTotalBalance OR w IS NULL) ");
  116.             parameters.put("minTotalBalance", minTotalBalance);
  117.         });
  118.  
  119.         userFilterOptions.getMaxTotalBalance().ifPresent(maxTotalBalance -> {
  120.             countQueryBuilder.append("AND (COALESCE(SUM(w.balance), 0) <= :maxTotalBalance OR w IS NULL) ");
  121.             parameters.put("maxTotalBalance", maxTotalBalance);
  122.         });
  123.  
  124.         // Create and execute the count query
  125.         Query countQuery = entityManager.createQuery(countQueryBuilder.toString());
  126.         for (Map.Entry<String, Object> entry : parameters.entrySet()) {
  127.             countQuery.setParameter(entry.getKey(), entry.getValue());
  128.         }
  129.  
  130.         // Handle empty results gracefully
  131.         try {
  132.             Number countResult = (Number) countQuery.getSingleResult();
  133.             return countResult.longValue();
  134.         } catch (NoResultException | NullPointerException e) {
  135.             return 0; // Return 0 if no results are found
  136.         }
  137.     }
  138.  
  139.    
Advertisement
Add Comment
Please, Sign In to add comment