Skip to content

Commit 4e8c9d7

Browse files
committed
support FastRepository#pageRequest x.x.x search
1 parent 2766951 commit 4e8c9d7

File tree

7 files changed

+239
-25
lines changed

7 files changed

+239
-25
lines changed

springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/jpa/repository/QueryRequest.java

Lines changed: 83 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,20 @@
33
import com.codingapi.springboot.framework.dto.request.Filter;
44
import com.codingapi.springboot.framework.dto.request.PageRequest;
55
import com.codingapi.springboot.framework.dto.request.RequestFilter;
6-
import javax.persistence.criteria.CriteriaBuilder;
7-
import javax.persistence.criteria.Order;
8-
import javax.persistence.criteria.Predicate;
9-
import javax.persistence.criteria.Root;
106
import org.springframework.beans.BeanUtils;
117
import org.springframework.data.domain.Example;
128

9+
import javax.persistence.ManyToMany;
10+
import javax.persistence.ManyToOne;
11+
import javax.persistence.OneToMany;
12+
import javax.persistence.OneToOne;
13+
import javax.persistence.criteria.*;
1314
import java.beans.PropertyDescriptor;
15+
import java.lang.reflect.Field;
1416
import java.util.ArrayList;
1517
import java.util.Date;
1618
import java.util.List;
19+
import java.util.Set;
1720

1821
public class QueryRequest {
1922

@@ -52,10 +55,22 @@ public <T> Example<T> getExample() {
5255

5356

5457
private List<String> getClazzProperties() {
58+
return getClazzProperties(clazz);
59+
}
60+
61+
private List<String> getClazzProperties(Class<?> clazz) {
5562
List<String> properties = new ArrayList<>();
5663
PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(clazz);
5764
for (PropertyDescriptor descriptor : descriptors) {
58-
properties.add(descriptor.getName());
65+
Class<?> propertyType = descriptor.getPropertyType();
66+
String name = descriptor.getName();
67+
if (propertyType.getPackage() != null && !propertyType.getPackage().getName().startsWith("java")) {
68+
List<String> childProperties = getClazzProperties(propertyType);
69+
for (String child : childProperties) {
70+
properties.add(name + "." + child);
71+
}
72+
}
73+
properties.add(name);
5974
}
6075
return properties;
6176
}
@@ -73,91 +88,113 @@ public <T> List<Order> getOrder(Root<T> root, CriteriaBuilder criteriaBuilder) {
7388
return orderList;
7489
}
7590

91+
private Path getPathByKey(Root root, String key) {
92+
String[] keys = key.split("\\.");
93+
if (keys.length > 1) {
94+
String lastKey = keys[keys.length-1];
95+
From current = root;
96+
for (int i=0;i< keys.length-1;i++) {
97+
String item = keys[i];
98+
Set<Join> joins = current.getJoins();
99+
for (Join<?, ?> join : joins) {
100+
if (join.getModel().getBindableJavaType().getSimpleName().equalsIgnoreCase(item)) {
101+
current = join;
102+
}
103+
}
104+
}
105+
return current.get(lastKey);
106+
} else {
107+
return root.get(key);
108+
}
109+
}
110+
76111

77112
private <T> Predicate toPredicate(Filter filter, CriteriaBuilder criteriaBuilder, Root<T> root, List<String> properties) {
78113
String key = filter.getKey();
79114
if (filter.isAndFilters() || filter.isOrFilters() || properties.contains(key)) {
80115

116+
Path path = getPathByKey(root, key);
117+
81118
if (filter.isEqual()) {
82-
return criteriaBuilder.equal(root.get(key), filter.getValue()[0]);
119+
return criteriaBuilder.equal(path, filter.getValue()[0]);
83120
}
84121

85122
if (filter.isLike()) {
86123
String matchValue = (String) filter.getValue()[0];
87-
return criteriaBuilder.like(root.get(key), "%" + matchValue + "%");
124+
return criteriaBuilder.like(path, "%" + matchValue + "%");
88125
}
89126

90127
if (filter.isBetween()) {
91128
Object value1 = filter.getValue()[0];
92129
Object value2 = filter.getValue()[2];
93130
if (value1 instanceof Integer && value2 instanceof Integer) {
94-
return criteriaBuilder.between(root.get(key), (Integer) value1, (Integer) value2);
131+
return criteriaBuilder.between(path, (Integer) value1, (Integer) value2);
95132
}
96133

97134
if (value1 instanceof Long && value2 instanceof Long) {
98-
return criteriaBuilder.between(root.get(key), (Long) value1, (Long) value2);
135+
return criteriaBuilder.between(path, (Long) value1, (Long) value2);
99136
}
100137

101138
if (value1 instanceof Date && value2 instanceof Date) {
102-
return criteriaBuilder.between(root.get(key), (Date) value1, (Date) value2);
139+
return criteriaBuilder.between(path, (Date) value1, (Date) value2);
103140
}
104141
}
105142

106143
if (filter.isGreaterThan()) {
107144
Object value = filter.getValue()[0];
108145
if (value instanceof Integer) {
109-
return criteriaBuilder.greaterThan(root.get(key), (Integer) value);
146+
return criteriaBuilder.greaterThan(path, (Integer) value);
110147
}
111148
if (value instanceof Long) {
112-
return criteriaBuilder.greaterThan(root.get(key), (Long) value);
149+
return criteriaBuilder.greaterThan(path, (Long) value);
113150
}
114151
if (value instanceof Date) {
115-
return criteriaBuilder.greaterThan(root.get(key), (Date) value);
152+
return criteriaBuilder.greaterThan(path, (Date) value);
116153
}
117154
}
118155

119156
if (filter.isGreaterThanEqual()) {
120157
Object value = filter.getValue()[0];
121158
if (value instanceof Integer) {
122-
return criteriaBuilder.greaterThanOrEqualTo(root.get(key), (Integer) value);
159+
return criteriaBuilder.greaterThanOrEqualTo(path, (Integer) value);
123160
}
124161
if (value instanceof Long) {
125-
return criteriaBuilder.greaterThanOrEqualTo(root.get(key), (Long) value);
162+
return criteriaBuilder.greaterThanOrEqualTo(path, (Long) value);
126163
}
127164
if (value instanceof Date) {
128-
return criteriaBuilder.greaterThanOrEqualTo(root.get(key), (Date) value);
165+
return criteriaBuilder.greaterThanOrEqualTo(path, (Date) value);
129166
}
130167
}
131168

132169
if (filter.isLessThan()) {
133170
Object value = filter.getValue()[0];
134171
if (value instanceof Integer) {
135-
return criteriaBuilder.lessThan(root.get(key), (Integer) value);
172+
return criteriaBuilder.lessThan(path, (Integer) value);
136173
}
137174
if (value instanceof Long) {
138-
return criteriaBuilder.lessThan(root.get(key), (Long) value);
175+
return criteriaBuilder.lessThan(path, (Long) value);
139176
}
140177
if (value instanceof Date) {
141-
return criteriaBuilder.lessThan(root.get(key), (Date) value);
178+
return criteriaBuilder.lessThan(path, (Date) value);
142179
}
143180
}
144181

145182
if (filter.isLessThanEqual()) {
146183
Object value = filter.getValue()[0];
147184
if (value instanceof Integer) {
148-
return criteriaBuilder.lessThanOrEqualTo(root.get(key), (Integer) value);
185+
return criteriaBuilder.lessThanOrEqualTo(path, (Integer) value);
149186
}
150187
if (value instanceof Long) {
151-
return criteriaBuilder.lessThanOrEqualTo(root.get(key), (Long) value);
188+
return criteriaBuilder.lessThanOrEqualTo(path, (Long) value);
152189
}
153190
if (value instanceof Date) {
154-
return criteriaBuilder.lessThanOrEqualTo(root.get(key), (Date) value);
191+
return criteriaBuilder.lessThanOrEqualTo(path, (Date) value);
155192
}
156193
}
157194

158195
if (filter.isIn()) {
159196
Object[] value = filter.getValue();
160-
CriteriaBuilder.In<Object> in = criteriaBuilder.in(root.get(key));
197+
CriteriaBuilder.In<Object> in = criteriaBuilder.in(path);
161198
for (Object item : value) {
162199
in.value(item);
163200
}
@@ -192,10 +229,33 @@ private <T> Predicate toPredicate(Filter filter, CriteriaBuilder criteriaBuilder
192229
}
193230

194231

232+
private void fetchJoins(From root, Class<?> clazz) {
233+
Field[] fields = clazz.getDeclaredFields();
234+
for (Field field : fields) {
235+
if (field.getAnnotation(OneToOne.class) != null) {
236+
Join<?, ?> join = root.join(field.getName(), JoinType.INNER);
237+
this.fetchJoins(join, field.getType());
238+
}
239+
if (field.getAnnotation(ManyToOne.class) != null) {
240+
Join<?, ?> join = root.join(field.getName(), JoinType.INNER);
241+
this.fetchJoins(join, field.getType());
242+
}
243+
if (field.getAnnotation(OneToMany.class) != null) {
244+
Join<?, ?> join = root.join(field.getName(), JoinType.INNER);
245+
this.fetchJoins(join, field.getType());
246+
}
247+
if (field.getAnnotation(ManyToMany.class) != null) {
248+
Join<?, ?> join = root.join(field.getName(), JoinType.INNER);
249+
this.fetchJoins(join, field.getType());
250+
}
251+
}
252+
}
253+
195254
public <T> List<Predicate> getPredicate(Root<T> root, CriteriaBuilder criteriaBuilder) {
196255
List<Predicate> predicates = new ArrayList<>();
197256
List<String> properties = getClazzProperties();
198257
RequestFilter requestFilter = request.getRequestFilter();
258+
this.fetchJoins(root, clazz);
199259
for (Filter filter : requestFilter.getFilters()) {
200260
Predicate predicate = toPredicate(filter, criteriaBuilder, root, properties);
201261
if (predicate != null) {
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package com.codingapi.springboot.fast;
2+
3+
import com.codingapi.springboot.fast.entity.Demo;
4+
import com.codingapi.springboot.fast.entity.Profile;
5+
import com.codingapi.springboot.fast.entity.User;
6+
import com.codingapi.springboot.fast.repository.DemoRepository;
7+
import com.codingapi.springboot.fast.repository.ProfileRepository;
8+
import com.codingapi.springboot.fast.repository.UserRepository;
9+
import com.codingapi.springboot.framework.dto.request.PageRequest;
10+
import lombok.extern.slf4j.Slf4j;
11+
import org.junit.jupiter.api.Test;
12+
import org.springframework.beans.factory.annotation.Autowired;
13+
import org.springframework.boot.test.context.SpringBootTest;
14+
import org.springframework.data.domain.Page;
15+
16+
import static org.junit.jupiter.api.Assertions.assertTrue;
17+
18+
@Slf4j
19+
@SpringBootTest
20+
public class UserRepositoryTest {
21+
22+
@Autowired
23+
private DemoRepository demoRepository;
24+
25+
@Autowired
26+
private UserRepository userRepository;
27+
28+
@Autowired
29+
private ProfileRepository profileRepository;
30+
31+
32+
@Test
33+
void test1() {
34+
35+
Demo demo = new Demo();
36+
demo.setName("123");
37+
demoRepository.save(demo);
38+
39+
40+
Profile profile = new Profile();
41+
profile.setDemo(demo);
42+
profile.setName("123");
43+
profileRepository.save(profile);
44+
45+
46+
User user = new User();
47+
user.setName("li");
48+
user.setProfile(profile);
49+
userRepository.save(user);
50+
51+
assertTrue(demo.getId()>0);
52+
assertTrue(user.getId()>0);
53+
54+
PageRequest request = new PageRequest();
55+
request.addFilter("profile.demo.id",1);
56+
Page<User> page = userRepository.pageRequest(request);
57+
System.out.println(page.getContent());
58+
59+
}
60+
61+
62+
63+
@Test
64+
void test2() {
65+
66+
Demo demo = new Demo();
67+
demo.setName("123");
68+
demoRepository.save(demo);
69+
70+
71+
Profile profile = new Profile();
72+
profile.setDemo(demo);
73+
profile.setName("123");
74+
profileRepository.save(profile);
75+
76+
77+
User user = new User();
78+
user.setName("li");
79+
user.setProfile(profile);
80+
userRepository.save(user);
81+
82+
assertTrue(demo.getId()>0);
83+
assertTrue(user.getId()>0);
84+
85+
PageRequest request = new PageRequest();
86+
request.addFilter("name","li");
87+
Page<User> page = userRepository.pageRequest(request);
88+
System.out.println(page.getContent());
89+
90+
}
91+
92+
}

springboot-starter-data-fast/src/test/java/com/codingapi/springboot/fast/entity/Demo.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
package com.codingapi.springboot.fast.entity;
22

3-
import javax.persistence.*;
43
import lombok.Getter;
54
import lombok.Setter;
65
import lombok.ToString;
76

7+
import javax.persistence.*;
8+
89
@Setter
910
@Getter
1011
@Entity
11-
@Table(name = "t_demo")
1212
@ToString
13+
@Table(name = "t_demo")
1314
public class Demo {
1415
@Id
1516
@GeneratedValue(strategy = GenerationType.IDENTITY)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.codingapi.springboot.fast.entity;
2+
3+
import lombok.Getter;
4+
import lombok.Setter;
5+
6+
import javax.persistence.*;
7+
8+
@Entity
9+
@Setter
10+
@Getter
11+
public class Profile {
12+
13+
@Id
14+
@GeneratedValue(strategy = GenerationType.IDENTITY)
15+
private int id;
16+
17+
private String name;
18+
19+
@OneToOne
20+
private Demo demo;
21+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.codingapi.springboot.fast.entity;
2+
3+
import lombok.Getter;
4+
import lombok.Setter;
5+
6+
import javax.persistence.*;
7+
8+
@Entity
9+
@Setter
10+
@Getter
11+
@Table(name = "t_user")
12+
public class User {
13+
14+
@Id
15+
@GeneratedValue(strategy = GenerationType.IDENTITY)
16+
private Integer id;
17+
18+
private String name;
19+
20+
@OneToOne
21+
private Profile profile;
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.codingapi.springboot.fast.repository;
2+
3+
import com.codingapi.springboot.fast.entity.Profile;
4+
import com.codingapi.springboot.fast.jpa.repository.FastRepository;
5+
6+
public interface ProfileRepository extends FastRepository<Profile,Integer> {
7+
8+
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.codingapi.springboot.fast.repository;
2+
3+
import com.codingapi.springboot.fast.entity.User;
4+
import com.codingapi.springboot.fast.jpa.repository.FastRepository;
5+
6+
public interface UserRepository extends FastRepository<User,Integer> {
7+
8+
9+
}

0 commit comments

Comments
 (0)