Skip to content

Commit d627f8b

Browse files
committed
data-fast support page query
1 parent 1aab90a commit d627f8b

File tree

10 files changed

+182
-14
lines changed

10 files changed

+182
-14
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.codingapi.springboot.example.infrastructure.dto;
2+
3+
import com.codingapi.springboot.framework.dto.request.PageRequest;
4+
import lombok.Getter;
5+
import lombok.Setter;
6+
7+
public class DemoDTO {
8+
9+
@Setter
10+
@Getter
11+
public static class DemoQuery extends PageRequest {
12+
13+
private String name;
14+
}
15+
}
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
package com.codingapi.springboot.example.infrastructure.query;
22

3+
import com.codingapi.springboot.example.infrastructure.dto.DemoDTO;
34
import com.codingapi.springboot.example.infrastructure.entity.DemoEntity;
45
import com.codingapi.springboot.fast.annotation.FastController;
56
import com.codingapi.springboot.fast.annotation.FastMapping;
7+
import com.codingapi.springboot.framework.dto.response.MultiResponse;
68
import org.springframework.web.bind.annotation.RequestMethod;
7-
import org.springframework.web.bind.annotation.RequestParam;
8-
9-
import java.util.List;
109

1110
@FastController
1211
public interface FastDemoApi {
1312

14-
@FastMapping(method = RequestMethod.GET,mapping = "/open/fast/demo/findAll",hql = "select d from DemoEntity d where name = ?1")
15-
List<DemoEntity> findAll(@RequestParam("name") String name);
13+
@FastMapping(method = RequestMethod.GET,
14+
mapping = "/open/fast/demo/findAll",
15+
hql = "select d from DemoEntity d where name = :name",
16+
countHql = "select count(d) from DemoEntity d where name = :name")
17+
MultiResponse<DemoEntity> findAll(DemoDTO.DemoQuery query);
1618

1719
}

springboot-example/src/main/java/com/codingapi/springboot/example/ui/controller/OpenController.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package com.codingapi.springboot.example.ui.controller;
22

33
import com.codingapi.springboot.example.application.executor.DemoExecutor;
4+
import com.codingapi.springboot.example.infrastructure.entity.DemoEntity;
5+
import com.codingapi.springboot.example.infrastructure.jap.repository.DemoEntityRepository;
6+
import com.codingapi.springboot.framework.dto.request.PageRequest;
7+
import com.codingapi.springboot.framework.dto.response.MultiResponse;
48
import com.codingapi.springboot.framework.dto.response.Response;
59
import lombok.AllArgsConstructor;
610
import org.springframework.web.bind.annotation.GetMapping;
@@ -15,9 +19,16 @@ public class OpenController {
1519

1620
private final DemoExecutor executor;
1721

22+
private final DemoEntityRepository demoEntityRepository;
23+
1824
@GetMapping("/save")
1925
public Response save(@RequestParam("name") String name){
2026
executor.create(name);
2127
return Response.buildSuccess();
2228
}
29+
30+
@GetMapping("/list")
31+
public MultiResponse<DemoEntity> list(PageRequest pageRequest){
32+
return MultiResponse.of(demoEntityRepository.findAll(pageRequest));
33+
}
2334
}

springboot-example/src/main/resources/application.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
server.port=8085
1+
server.port=8080
22
spring.datasource.driver-class-name=org.h2.Driver
33
spring.datasource.url=jdbc:h2:file:./demo.db
44
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/annotation/FastMapping.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
String hql() default "";
1818

19+
20+
String countHql() default "";
21+
1922
RequestMethod method() default RequestMethod.GET;
2023

2124

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.codingapi.springboot.fast.exception;
2+
3+
public class FastMappingErrorException extends Exception{
4+
5+
public FastMappingErrorException(String message) {
6+
super(message);
7+
}
8+
}
Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,36 @@
11
package com.codingapi.springboot.fast.executor;
22

3+
import com.codingapi.springboot.framework.dto.response.MultiResponse;
4+
import com.codingapi.springboot.framework.dto.response.SingleResponse;
35
import lombok.AllArgsConstructor;
6+
import org.springframework.data.domain.Page;
47

58
import javax.persistence.EntityManager;
6-
import javax.persistence.Query;
9+
import java.util.Collection;
710

811
@AllArgsConstructor
912
public class JpaExecutor {
1013

1114
private final EntityManager entityManager;
1215

13-
public Object execute(String jpaSql,Object[] args){
14-
Query query = entityManager.createQuery(jpaSql);
15-
if(args!=null) {
16-
for (int i = 0; i < args.length; i++) {
17-
query.setParameter(i+1,args[i]);
16+
public Object execute(String hql,String countHql,Object[] args,Class<?> returnType){
17+
JpaQuery query = new JpaQuery(hql,countHql,args,entityManager);
18+
19+
if(returnType.equals(SingleResponse.class)){
20+
return SingleResponse.of(query.getSingleResult());
21+
}
22+
23+
if(returnType.equals(MultiResponse.class)){
24+
Object returnData = query.getResultList();
25+
if(Page.class.isAssignableFrom(returnData.getClass())) {
26+
return MultiResponse.of((Page)returnData);
27+
}
28+
29+
if(Collection.class.isAssignableFrom(returnData.getClass())) {
30+
return MultiResponse.of((Collection) returnData);
1831
}
1932
}
33+
2034
return query.getResultList();
2135
}
2236
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package com.codingapi.springboot.fast.executor;
2+
3+
import lombok.SneakyThrows;
4+
import lombok.extern.slf4j.Slf4j;
5+
import org.springframework.data.domain.PageImpl;
6+
import org.springframework.data.domain.Pageable;
7+
import org.springframework.util.ReflectionUtils;
8+
import org.springframework.util.StringUtils;
9+
10+
import javax.persistence.EntityManager;
11+
import javax.persistence.Parameter;
12+
import javax.persistence.Query;
13+
import java.lang.reflect.Field;
14+
import java.util.Set;
15+
16+
@Slf4j
17+
public class JpaQuery {
18+
private final Object[] args;
19+
private final Query query;
20+
private final String hql;
21+
private final String countHql;
22+
23+
private final EntityManager entityManager;
24+
25+
public JpaQuery(String hql,String countHql,Object[] args, EntityManager entityManager) {
26+
this.hql = hql;
27+
this.countHql = countHql;
28+
this.args = args;
29+
this.entityManager = entityManager;
30+
this.query = entityManager.createQuery(hql);
31+
this.setParameter(query);
32+
}
33+
34+
@SneakyThrows
35+
private void setParameter(Query query){
36+
if(args!=null&&args.length>0) {
37+
Set<Parameter<?>> parameters = query.getParameters();
38+
for(Parameter<?> parameter:parameters){
39+
Integer position = parameter.getPosition();
40+
if(position!=null){
41+
query.setParameter(position, args[position - 1]);
42+
}
43+
if(StringUtils.hasText(parameter.getName())){
44+
String name = parameter.getName();
45+
Object obj = args[0];
46+
Field field = ReflectionUtils.findField(obj.getClass(),name);
47+
if(field!=null) {
48+
field.setAccessible(true);
49+
query.setParameter(name, field.get(obj));
50+
}
51+
}
52+
}
53+
54+
}
55+
}
56+
57+
private boolean isPageable() {
58+
if(args!=null&& args.length>0){
59+
Object lastObj = args[args.length-1];
60+
return lastObj instanceof Pageable;
61+
}
62+
return false;
63+
}
64+
65+
private Pageable getPageable(){
66+
if(args!=null&& args.length>0){
67+
Object lastObj = args[args.length-1];
68+
if(lastObj instanceof Pageable){
69+
return (Pageable) lastObj;
70+
}
71+
}
72+
return null;
73+
}
74+
75+
public Object getResultList() {
76+
if(isPageable()&&StringUtils.hasText(countHql)){
77+
Pageable pageable = getPageable();
78+
query.setFirstResult((int) pageable.getOffset());
79+
query.setMaxResults(pageable.getPageSize());
80+
long total = getCount();
81+
return new PageImpl<>(query.getResultList(),pageable,total);
82+
}
83+
return query.getResultList();
84+
}
85+
86+
87+
private long getCount(){
88+
Query countQuery = entityManager.createQuery(countHql);
89+
setParameter(countQuery);
90+
return (Long) countQuery.getSingleResult();
91+
}
92+
93+
94+
public Object getSingleResult(){
95+
return query.getSingleResult();
96+
}
97+
98+
99+
}

springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/executor/MvcMethodProxy.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public Object invoke(Object proxy, Method method, Object[] args)
2121
return hashCode();
2222
}
2323
FastMapping fastMapping = method.getAnnotation(FastMapping.class);
24-
return jpaExecutor.execute(fastMapping.hql(),args);
24+
Class<?> returnType = method.getReturnType();
25+
return jpaExecutor.execute(fastMapping.hql(),fastMapping.countHql(),args,returnType);
2526
}
2627
}

springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/registrar/MvcMappingRegistrar.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package com.codingapi.springboot.fast.registrar;
22

33
import com.codingapi.springboot.fast.annotation.FastMapping;
4+
import com.codingapi.springboot.fast.exception.FastMappingErrorException;
45
import com.codingapi.springboot.fast.executor.JpaExecutor;
56
import com.codingapi.springboot.fast.executor.MvcMethodProxy;
67
import com.codingapi.springboot.fast.mapping.MvcEndpointMapping;
78
import lombok.AllArgsConstructor;
89
import lombok.SneakyThrows;
910
import lombok.extern.slf4j.Slf4j;
11+
import org.springframework.data.domain.Pageable;
12+
import org.springframework.util.StringUtils;
1013

1114
import java.lang.reflect.Method;
1215
import java.lang.reflect.Proxy;
@@ -26,7 +29,7 @@ public void registerMvcMapping() {
2629
Method[] methods = clazz.getDeclaredMethods();
2730
for(Method method:methods){
2831
FastMapping fastMapping = method.getAnnotation(FastMapping.class);
29-
if(fastMapping!=null) {
32+
if(fastMapping!=null&&isVerify(fastMapping,method)) {
3033
MvcMethodProxy handler = new MvcMethodProxy(jpaExecutor);
3134
Object methodProxy = Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, handler);
3235
mvcEndpointMapping.addMapping(fastMapping.mapping(), fastMapping.method(), methodProxy, method);
@@ -35,4 +38,16 @@ public void registerMvcMapping() {
3538
}
3639
}
3740

41+
private boolean isVerify(FastMapping fastMapping,Method method) throws FastMappingErrorException {
42+
Class<?>[] parameterTypes = method.getParameterTypes();
43+
for(Class<?> parameter:parameterTypes){
44+
if(Pageable.class.isAssignableFrom(parameter)){
45+
if(!StringUtils.hasText(fastMapping.countHql())){
46+
throw new FastMappingErrorException(String.format("fast mapping %s missing countHql .",fastMapping.mapping()));
47+
}
48+
}
49+
}
50+
return true;
51+
}
52+
3853
}

0 commit comments

Comments
 (0)