Skip to content

Commit f2935fc

Browse files
committed
impl controller layer for search
add classes need for new search platform also implement basic feature in controller layer. and improve code
1 parent 9b501ca commit f2935fc

8 files changed

Lines changed: 98 additions & 24 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ This project, implement instance of basic feature, <br> you maybe want use for A
6262
2 - use pagination for search <br>
6363
3 - create query dynamic base on search request <br>
6464
4 - use order and direction for sort data <br>
65+
5 - sample rest search request: <br>
66+
- http://localhost:9090/api/v1/user/search/v2?firstName=h&orderBy=firstName_asc, gender_desc&page=1&size=5 <br>
6567

6668
### test feature
6769
1 - generate sample data baseOn model with javaFaker <br>

src/main/java/ir/bigz/springbootreal/commons/util/Utils.java

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,12 @@ else if (condition == IN) {
111111
public static <T> void buildNativeQueryCondition(Map<String, String> queryString,
112112
Map<String, String> conditionsMap,
113113
Map<String, Object> parametersMap,
114-
String fieldName,
115-
String parameter,
114+
String fieldNameOnDataBase,
115+
String parameterQueryStringMap,
116116
SqlOperation operation,
117117
Class<T> type) {
118118
if (queryString != null) {
119-
String value = queryString.get(parameter);
119+
String value = queryString.get(parameterQueryStringMap);
120120
T parameterVal = null;
121121
String queryCondition = "";
122122
if (type.equals(String.class)) {
@@ -144,32 +144,36 @@ public static <T> void buildNativeQueryCondition(Map<String, String> queryString
144144
if (type.equals(String.class)) {
145145
parameterVal = (T) value;
146146
}
147-
parametersMap.put(parameter, parameterVal);
148-
queryCondition = "and " + fieldName + " " + operation.operationSign + " " + ":" + parameter;
147+
parametersMap.put(parameterQueryStringMap, parameterVal);
148+
queryCondition = "and " + fieldNameOnDataBase + " " + operation.operationSign + " " + ":" + parameterQueryStringMap;
149149
} else if (operation == SqlOperation.CONTAINS || operation == SqlOperation.NOT_CONTAINS) {
150150
if (type.equals(String.class)) {
151-
parametersMap.put(parameter, "%" + value + "%");
152-
queryCondition = "and " + fieldName + " " + operation.operationSign + " :" + parameter;
151+
parametersMap.put(parameterQueryStringMap, "%" + value + "%");
152+
queryCondition = "and " + fieldNameOnDataBase + " " + operation.operationSign + " :" + parameterQueryStringMap;
153153
}
154154
} else if (operation == SqlOperation.STARTS_WITH) {
155155
if (type.equals(String.class)) {
156-
parametersMap.put(parameter, value + "%");
157-
queryCondition = "and " + fieldName + " " + operation.operationSign + " " + ":" + parameter;
156+
parametersMap.put(parameterQueryStringMap, value + "%");
157+
queryCondition = "and " + fieldNameOnDataBase + " " + operation.operationSign + " " + ":" + parameterQueryStringMap;
158158
}
159159
} else if (operation == SqlOperation.ENDS_WITH) {
160160
if (type.equals(String.class)) {
161-
parametersMap.put(parameter, "%" + value);
162-
queryCondition = "and " + fieldName + " " + operation.operationSign + " " + ":" + parameter;
161+
parametersMap.put(parameterQueryStringMap, "%" + value);
162+
queryCondition = "and " + fieldNameOnDataBase + " " + operation.operationSign + " " + ":" + parameterQueryStringMap;
163163
}
164164
} else if (operation == SqlOperation.IN) {
165165
String[] listArray = value.split(",");
166-
parametersMap.put(parameter, Arrays.asList(listArray));
167-
queryCondition = "and " + fieldName + " " + operation.operationSign + " (" + ":" + parameter + ")";
166+
parametersMap.put(parameterQueryStringMap, Arrays.asList(listArray));
167+
queryCondition = "and " + fieldNameOnDataBase + " " + operation.operationSign + " (" + ":" + parameterQueryStringMap + ")";
168168
}
169-
}
170169

171-
conditionsMap.put(parameter, queryCondition);
170+
conditionsMap.put(parameterQueryStringMap, queryCondition);
171+
}
172172
}
173173

174174
}
175+
176+
public static String getWhereSimple(){
177+
return " where 1=1 ";
178+
}
175179
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package ir.bigz.springbootreal.controller;
2+
3+
import ir.bigz.springbootreal.dto.PagedQuery;
4+
import org.springframework.web.context.request.RequestContextHolder;
5+
import org.springframework.web.context.request.ServletRequestAttributes;
6+
7+
import javax.servlet.http.HttpServletRequest;
8+
import java.util.HashMap;
9+
import java.util.Map;
10+
import java.util.stream.Collectors;
11+
12+
public abstract class AbstractController {
13+
14+
protected HttpServletRequest request() {
15+
return ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
16+
}
17+
18+
protected PagedQuery getPagedQuery() {
19+
return new PagedQuery(request().getParameterMap().entrySet().stream()
20+
.collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()[0])));
21+
}
22+
23+
protected PagedQuery getPagedQuery(Map<String, String> extraParams) {
24+
var params = request().getParameterMap().entrySet().stream()
25+
.collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()[0]));
26+
if (extraParams != null)
27+
params.putAll(extraParams);
28+
return new PagedQuery(params);
29+
}
30+
31+
protected Map<String, String> getQueryString() {
32+
Map<String, String> result = new HashMap<>();
33+
result.putAll(request().getParameterMap().entrySet().stream()
34+
.collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()[0])));
35+
return result;
36+
}
37+
38+
protected Map<String, String> getUnlimitedSizeParam() {
39+
return new HashMap() {
40+
{
41+
put("size", request().getParameter("size") == null ? "-1" : request().getParameter("size"));
42+
}
43+
};
44+
}
45+
}

src/main/java/ir/bigz/springbootreal/controller/SampleController.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package ir.bigz.springbootreal.controller;
22

3+
import ir.bigz.springbootreal.dto.PageResult;
34
import ir.bigz.springbootreal.service.UserService;
45
import ir.bigz.springbootreal.viewmodel.UserModel;
56
import ir.bigz.springbootreal.viewmodel.search.UserSearchDto;
@@ -16,7 +17,7 @@
1617
@RestController
1718
@CrossOrigin
1819
@RequestMapping("/api/v1")
19-
public class SampleController {
20+
public class SampleController extends AbstractController{
2021

2122
final
2223
UserService userService;
@@ -75,6 +76,13 @@ public ResponseEntity<?> getUserWithSearch(@RequestBody UserSearchDto userSearch
7576
return ResponseEntity.ok(userPageResult);
7677
}
7778

79+
@GetMapping(path = "/user/search/v2", produces = MediaType.APPLICATION_JSON_VALUE)
80+
@ResponseStatus(HttpStatus.OK)
81+
public ResponseEntity<?> getUserWithSearchV2() {
82+
PageResult<UserModel> userPageResult = userService.getUserSearchV2(getQueryString(), getPagedQuery());
83+
return ResponseEntity.ok(userPageResult);
84+
}
85+
7886

7987
@GetMapping(path = "/user/all/pagerquest", produces = MediaType.APPLICATION_JSON_VALUE)
8088
@ResponseStatus(HttpStatus.OK)

src/main/java/ir/bigz/springbootreal/dal/DaoRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public interface DaoRepository<T, K extends Serializable> {
3131
<S extends T> List<S> find(String entityName);
3232
List<T> genericSearch(String query);
3333
List<T> nativeQuery(String query, Map<String, Object> parameters);
34-
PageResult<T> pageCreateQuery(String nativeQuery, PagedQuery pagedQuery, Map<String, Object> parameterMap);
34+
PageResult<T> pageCreateQuery(String nativeQuery, PagedQuery pagedQuery, Map<String, Object> parameterMap, boolean getTotalCount);
3535
void flush();
3636
void clear();
3737

src/main/java/ir/bigz/springbootreal/dal/DaoRepositoryImpl.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.lang.reflect.Field;
2020
import java.lang.reflect.ParameterizedType;
2121
import java.lang.reflect.Type;
22+
import java.math.BigInteger;
2223
import java.text.MessageFormat;
2324
import java.util.*;
2425
import java.util.stream.Stream;
@@ -138,7 +139,7 @@ public List<T> nativeQuery(String query, Map<String, Object> parameters) {
138139

139140
@Override
140141
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
141-
public PageResult<T> pageCreateQuery(String nativeQuery, PagedQuery pagedQuery, Map<String, Object> parameterMap) {
142+
public PageResult<T> pageCreateQuery(String nativeQuery, PagedQuery pagedQuery, Map<String, Object> parameterMap, boolean getTotalCount) {
142143

143144
StringBuffer orderString = new StringBuffer();
144145
String queryString = nativeQuery;
@@ -168,7 +169,7 @@ public PageResult<T> pageCreateQuery(String nativeQuery, PagedQuery pagedQuery,
168169
);
169170

170171
if (orderString.length() > 0) {
171-
queryString = "SELECT * FROM (" + removeDefaultOrderBy(queryString) + ") as q ORDER BY " + orderString;
172+
queryString = "SELECT * FROM (" + removeDefaultOrderBy(queryString) + ") q ORDER BY " + orderString;
172173
}
173174

174175
Query query = entityManager.createNativeQuery(queryString, daoType);
@@ -191,12 +192,17 @@ public PageResult<T> pageCreateQuery(String nativeQuery, PagedQuery pagedQuery,
191192

192193
List<T> resultQuery = query.getResultList();
193194

195+
Long total = 0L;
196+
if (getTotalCount && pagedQuery.getPageSize() > -1) {
197+
total = totalCountOfSearch(queryString, parameterMap);
198+
}
199+
194200
PageResult<T> pagedResult = new PageResult<T>(
195201
resultQuery
196202
, (pagedQuery.getPageSize() > -1 ? pagedQuery.getPageSize() : resultQuery.size())
197203
, pagedQuery.getPageNumber()
198204
, pagedQuery.getOffset()
199-
, resultQuery.size()
205+
, total != 0 ? total : resultQuery.size()
200206
);
201207
return pagedResult;
202208
}
@@ -302,6 +308,14 @@ protected long totalCountOfEntities() {
302308
return typedQuery.getSingleResult();
303309
}
304310

311+
protected Long totalCountOfSearch(String queryString, Map<String, Object> parameterMap) {
312+
queryString = MessageFormat.format("SELECT count(*) count FROM (SELECT * FROM ({0}) query) counter", queryString);
313+
Query query = entityManager.createNativeQuery(queryString);
314+
parameterMap.keySet().forEach(s -> query.setParameter(s, parameterMap.get(s)));
315+
List resultList = query.getResultList();
316+
return ((BigInteger)resultList.get(0)).longValue();
317+
}
318+
305319
protected List<Order> orderByClauseBuilder(Root<T> root, Sort sort){
306320

307321
List<Order> orders = new ArrayList<>();

src/main/java/ir/bigz/springbootreal/service/UserServiceImpl.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class UserServiceImpl implements UserService {
2929

3030
private final UserRepository userRepository;
3131
private final UserMapper userMapper;
32-
private static final String USER_QUERY = "select * from users where 1=1 ";
32+
private static final String USER_QUERY = "select * from users";
3333

3434

3535
public UserServiceImpl(UserRepository userRepository,
@@ -160,7 +160,8 @@ public PageResult<UserModel> getUserSearchV2(Map<String, String> queryString, Pa
160160
Map<String, Object> parametersMap = new HashMap<>();
161161
Map<String, String> conditionsMap = new HashMap<>();
162162
StringBuffer stringBuffer = new StringBuffer();
163-
stringBuffer.append(USER_QUERY);
163+
stringBuffer.append(USER_QUERY); //base query
164+
stringBuffer.append(Utils.getWhereSimple()); //add where to query
164165
Utils.buildNativeQueryCondition(queryString,
165166
conditionsMap,
166167
parametersMap,
@@ -171,7 +172,7 @@ public PageResult<UserModel> getUserSearchV2(Map<String, String> queryString, Pa
171172

172173
conditionsMap.keySet().forEach(s -> stringBuffer.append(conditionsMap.get(s)));
173174

174-
PageResult<User> userPageResult = userRepository.pageCreateQuery(stringBuffer.toString(), pagedQuery, parametersMap);
175+
PageResult<User> userPageResult = userRepository.pageCreateQuery(stringBuffer.toString(), pagedQuery, parametersMap, true);
175176

176177
List<UserModel> collect = userPageResult.getResult().stream().map(userMapper::userToUserModel).collect(Collectors.toList());
177178

src/test/groovy/ir/bigz/springbootreal/web/RepositoryTest.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class RepositoryTest extends InitTestContainerDB {
9595
when: "call method"
9696
Map<String, Object> queryParams = new HashMap<>()
9797
queryParams.put("number", 1)
98-
def resultList = userRepository.pageCreateQuery(query, pagedQuery, queryParams)
98+
def resultList = userRepository.pageCreateQuery(query, pagedQuery, queryParams, true)
9999

100100
then: "query result size not equal zero"
101101
resultList.getResult().size() >= 0

0 commit comments

Comments
 (0)