├── .gitignore
├── LICENSE
├── README.md
├── pom.xml
└── src
├── main
└── java
│ └── com
│ └── beyt
│ └── jdq
│ ├── annotation
│ ├── EnableJpaDynamicQuery.java
│ ├── EnableJpaDynamicQueryArgumentResolvers.java
│ └── model
│ │ ├── JdqField.java
│ │ ├── JdqIgnoreField.java
│ │ ├── JdqModel.java
│ │ └── JdqSubModel.java
│ ├── config
│ ├── ArgumentResolversInitConfig.java
│ ├── DeserializerConfig.java
│ └── EntityManagerProviderConfig.java
│ ├── deserializer
│ ├── BasicDeserializer.java
│ ├── IDeserializer.java
│ └── JacksonDeserializer.java
│ ├── dto
│ ├── Criteria.java
│ ├── CriteriaList.java
│ ├── DynamicQuery.java
│ └── enums
│ │ ├── CriteriaOperator.java
│ │ ├── JoinType.java
│ │ └── Order.java
│ ├── exception
│ ├── DynamicQueryIllegalArgumentException.java
│ ├── DynamicQueryNoAvailableEnumException.java
│ ├── DynamicQueryNoAvailableOperationException.java
│ ├── DynamicQueryNoAvailableOrOperationUsageException.java
│ ├── DynamicQueryNoAvailableParenthesesOperationUsageException.java
│ ├── DynamicQueryNoAvailableValueException.java
│ ├── DynamicQueryNoFirstValueException.java
│ └── DynamicQueryValueSerializeException.java
│ ├── provider
│ └── IEntityManagerProvider.java
│ ├── query
│ ├── DynamicQueryManager.java
│ ├── DynamicSpecification.java
│ ├── builder
│ │ ├── QueryBuilder.java
│ │ ├── QuerySimplifier.java
│ │ └── interfaces
│ │ │ ├── DistinctWhereOrderByPage.java
│ │ │ ├── OrderByPage.java
│ │ │ ├── PageableResult.java
│ │ │ ├── Result.java
│ │ │ └── WhereOrderByPage.java
│ └── rule
│ │ ├── sort
│ │ ├── ISortFilterRule.java
│ │ ├── SortFilterAscRule.java
│ │ └── SortFilterDescRule.java
│ │ ├── specification
│ │ ├── ISpecificationFilterRule.java
│ │ ├── SpecificationFilterDoesNotContainRule.java
│ │ ├── SpecificationFilterDoubleLikeRule.java
│ │ ├── SpecificationFilterEqualRule.java
│ │ ├── SpecificationFilterGreaterThanOrEqualToRule.java
│ │ ├── SpecificationFilterGreaterThanRule.java
│ │ ├── SpecificationFilterLeftLikeRule.java
│ │ ├── SpecificationFilterLessThanOrEqualToRule.java
│ │ ├── SpecificationFilterLessThanRule.java
│ │ ├── SpecificationFilterNotEqualRule.java
│ │ ├── SpecificationFilterRightLikeRule.java
│ │ └── SpecificationFilterSpecifiedRule.java
│ │ └── top
│ │ ├── IPageFilterRule.java
│ │ ├── PageFilterAscRule.java
│ │ ├── PageFilterDescRule.java
│ │ ├── TopFilterAscRule.java
│ │ └── TopFilterDescRule.java
│ ├── repository
│ ├── DynamicSpecificationRepository.java
│ ├── DynamicSpecificationRepositoryFactoryBean.java
│ ├── DynamicSpecificationRepositoryImpl.java
│ └── JpaDynamicQueryRepository.java
│ ├── resolver
│ ├── CriteriaListArgumentResolver.java
│ └── DynamicQueryArgumentResolver.java
│ └── util
│ ├── ApplicationContextUtil.java
│ ├── ListConsumer.java
│ ├── ReflectionUtil.java
│ ├── SpecificationUtil.java
│ ├── StringUtil.java
│ └── field
│ ├── FieldUtil.java
│ └── helper
│ ├── BooleanFieldHelper.java
│ ├── DateFieldHelper.java
│ ├── DoubleFieldHelper.java
│ ├── EnumFieldHelper.java
│ ├── IFieldHelper.java
│ ├── InstantFieldHelper.java
│ ├── IntegerFieldHelper.java
│ ├── LocalDateFieldHelper.java
│ ├── LongFieldHelper.java
│ ├── StringFieldHelper.java
│ ├── TimestampFieldHelper.java
│ └── ZonedDateTimeFieldHelper.java
└── test
├── java
└── com
│ └── beyt
│ └── jdq
│ ├── BaseTestInstance.java
│ ├── TestApplication.java
│ ├── TestUtil.java
│ ├── context
│ └── DBSelectionContext.java
│ ├── controller
│ └── PresentationTestController.java
│ ├── deserializer
│ └── DateTimeDeserializer.java
│ ├── interceptor
│ └── DatabaseSelectionInterceptor.java
│ ├── presetation
│ ├── S10_Argument_Resolvers.java
│ ├── S11_Additional_Features.java
│ ├── S1_Operators.java
│ ├── S2_Multi_Value_Operators.java
│ ├── S3_AND_OR_Operator.java
│ ├── S4_SCOPE_Operator.java
│ ├── S5_Join.java
│ ├── S6_Advenced_Join.java
│ ├── S7_Select_Distinct_Order.java
│ ├── S8_Advenced_Projection.java
│ └── S9_Query_Builder.java
│ ├── query
│ ├── DynamicQueryManagerTest.java
│ └── DynamicSpecificationTest.java
│ ├── resolver
│ └── ArgumentResolversTests.java
│ ├── testenv
│ ├── config
│ │ └── DynamicSpecificationRepositoryConfiguration.java
│ ├── controller
│ │ └── TestController.java
│ ├── entity
│ │ ├── Customer.java
│ │ ├── User.java
│ │ ├── authorization
│ │ │ ├── AdminUser.java
│ │ │ ├── Authorization.java
│ │ │ ├── Role.java
│ │ │ └── RoleAuthorization.java
│ │ └── school
│ │ │ ├── Address.java
│ │ │ ├── Course.java
│ │ │ ├── Department.java
│ │ │ └── Student.java
│ └── repository
│ │ ├── AddressRepository.java
│ │ ├── AdminUserRepository.java
│ │ ├── AuthorizationRepository.java
│ │ ├── CourseRepository.java
│ │ ├── CustomerRepository.java
│ │ ├── DepartmentRepository.java
│ │ ├── RoleAuthorizationRepository.java
│ │ ├── RoleRepository.java
│ │ ├── StudentRepository.java
│ │ ├── UserRepository.java
│ │ └── field
│ │ └── FieldUtilTest.java
│ └── util
│ └── PresentationUtil.java
└── resources
└── config
├── application.yml
├── data.sql
└── init.sql
/.gitignore:
--------------------------------------------------------------------------------
1 | ######################
2 | # Project Specific
3 | ######################
4 | /src/main/webapp/content/css/main.css
5 | /src/test/javascript/coverage/
6 |
7 | ######################
8 | # Node
9 | ######################
10 | /node/
11 | node_tmp/
12 | node_modules/
13 | npm-debug.log.*
14 | /.awcache/*
15 | /.cache-loader/*
16 |
17 | ######################
18 | # SASS
19 | ######################
20 | .sass-cache/
21 |
22 | ######################
23 | # Eclipse
24 | ######################
25 | *.pydevproject
26 | .project
27 | .metadata
28 | tmp/
29 | tmp/**/*
30 | *.tmp
31 | *.bak
32 | *.swp
33 | *~.nib
34 | local.properties
35 | .classpath
36 | .settings/
37 | .loadpath
38 | .factorypath
39 | /src/main/resources/rebel.xml
40 |
41 | # External tool builders
42 | .externalToolBuilders/**
43 |
44 | # Locally stored "Eclipse launch configurations"
45 | *.launch
46 |
47 | # CDT-specific
48 | .cproject
49 |
50 | # PDT-specific
51 | .buildpath
52 |
53 | # STS-specific
54 | /.sts4-cache/*
55 |
56 | ######################
57 | # IntelliJ
58 | ######################
59 | .idea/
60 | *.iml
61 | *.iws
62 | *.ipr
63 | *.ids
64 | *.orig
65 | classes/
66 | out/
67 |
68 | ######################
69 | # Visual Studio Code
70 | ######################
71 | .vscode/
72 |
73 | ######################
74 | # Maven
75 | ######################
76 | /log/
77 |
78 | ######################
79 | # Gradle
80 | ######################
81 | .gradle/
82 | /build/
83 |
84 | ######################
85 | # Package Files
86 | ######################
87 | *.jar
88 | *.war
89 | *.ear
90 | *.db
91 |
92 | ######################
93 | # Windows
94 | ######################
95 | # Windows image file caches
96 | Thumbs.db
97 |
98 | # Folder config file
99 | Desktop.ini
100 |
101 | ######################
102 | # Mac OSX
103 | ######################
104 | .DS_Store
105 | .svn
106 |
107 | # Thumbnails
108 | ._*
109 |
110 | # Files that might appear on external disk
111 | .Spotlight-V100
112 | .Trashes
113 |
114 | ######################
115 | # Directories
116 | ######################
117 | /bin/
118 | /deploy/
119 |
120 | ######################
121 | # Logs
122 | ######################
123 | *.log*
124 |
125 | ######################
126 | # Others
127 | ######################
128 | *.class
129 | *.*~
130 | *~
131 | .merge_file*
132 |
133 | ######################
134 | # Gradle Wrapper
135 | ######################
136 | !gradle/wrapper/gradle-wrapper.jar
137 |
138 | ######################
139 | # Maven Wrapper
140 | ######################
141 | !.mvn/wrapper/maven-wrapper.jar
142 |
143 | ######################
144 | # ESLint
145 | ######################
146 | .eslintcache
147 |
148 | */target/**
149 |
150 | /nexts/
151 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | org.springframework.boot
9 | spring-boot-starter-parent
10 | 3.3.3
11 |
12 |
13 |
14 | io.github.tdilber
15 | spring-boot-starter-jpa-dynamic-query
16 | 0.3.0
17 | jar
18 | Spring Jpa Dynamic Query
19 | Spring Jpa Dynamic Query (JDQ) Project
20 | https://github.com/tdilber/spring-jpa-generic-criteria
21 |
22 |
23 |
24 | The Apache License, Version 2.0
25 | http://www.apache.org/licenses/LICENSE-2.0.txt
26 |
27 |
28 |
29 |
30 |
31 | Talha Dilber
32 | dilber.talha@gmail.com
33 |
34 |
35 |
36 |
37 | scm:git:git://github.com/tdilber/spring-jpa-generic-criteria.git
38 | scm:git:ssh://github.com:tdilber/spring-jpa-generic-criteria.git
39 | http://github.com/tdilber/spring-jpa-generic-criteria/tree/master
40 |
41 |
42 |
43 |
44 | 17
45 | UTF-8
46 |
47 |
48 |
49 |
50 | org.springframework
51 | spring-web
52 |
53 |
54 | org.springframework
55 | spring-webmvc
56 |
57 |
58 | com.fasterxml.jackson.core
59 | jackson-databind
60 |
61 |
62 | org.springframework.boot
63 | spring-boot-autoconfigure
64 |
65 |
66 | org.springframework.data
67 | spring-data-commons
68 |
69 |
70 | org.springframework.data
71 | spring-data-jpa
72 |
73 |
74 | jakarta.persistence
75 | jakarta.persistence-api
76 |
77 |
78 | org.hibernate
79 | hibernate-core
80 | ${hibernate.version}
81 |
82 |
83 | org.projectlombok
84 | lombok
85 | true
86 |
87 |
88 | org.apache.commons
89 | commons-collections4
90 | 4.4
91 |
92 |
93 | org.apache.commons
94 | commons-lang3
95 |
96 |
97 |
98 |
99 | org.springframework.boot
100 | spring-boot-starter-test
101 | test
102 |
103 |
104 | org.springframework.boot
105 | spring-boot-starter-web
106 | test
107 |
108 |
109 | org.springframework.boot
110 | spring-boot-starter-data-jpa
111 | test
112 |
113 |
114 | com.h2database
115 | h2
116 | test
117 |
118 |
119 | com.google.code.gson
120 | gson
121 | test
122 |
123 |
124 |
125 |
126 |
127 | ossrh
128 | https://s01.oss.sonatype.org/content/repositories/snapshots
129 |
130 |
131 | ossrh
132 | https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/
133 |
134 |
135 |
136 |
137 |
138 |
139 | org.apache.maven.plugins
140 | maven-source-plugin
141 | ${maven-source-plugin.version}
142 |
143 |
144 | attach-sources
145 |
146 | jar-no-fork
147 |
148 |
149 |
150 |
151 |
152 | org.apache.maven.plugins
153 | maven-javadoc-plugin
154 | ${maven-javadoc-plugin.version}
155 |
156 |
157 | attach-javadocs
158 | package
159 |
160 | jar
161 |
162 |
163 |
164 |
165 |
166 | org.apache.maven.plugins
167 | maven-gpg-plugin
168 | 1.5
169 |
170 |
171 | sign-artifacts
172 | verify
173 |
174 | sign
175 |
176 |
177 |
178 |
179 |
180 | org.sonatype.central
181 | central-publishing-maven-plugin
182 | 0.3.0
183 | true
184 |
185 | central
186 | true
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
--------------------------------------------------------------------------------
/src/main/java/com/beyt/jdq/annotation/EnableJpaDynamicQuery.java:
--------------------------------------------------------------------------------
1 | package com.beyt.jdq.annotation;
2 |
3 | import com.beyt.jdq.config.DeserializerConfig;
4 | import com.beyt.jdq.config.EntityManagerProviderConfig;
5 | import com.beyt.jdq.util.ApplicationContextUtil;
6 | import org.springframework.context.annotation.Import;
7 |
8 | import java.lang.annotation.ElementType;
9 | import java.lang.annotation.Retention;
10 | import java.lang.annotation.RetentionPolicy;
11 | import java.lang.annotation.Target;
12 |
13 | @Retention(RetentionPolicy.RUNTIME)
14 | @Target({ElementType.TYPE})
15 | @Import({ApplicationContextUtil.class, EntityManagerProviderConfig.class, DeserializerConfig.class})
16 | public @interface EnableJpaDynamicQuery {
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/beyt/jdq/annotation/EnableJpaDynamicQueryArgumentResolvers.java:
--------------------------------------------------------------------------------
1 | package com.beyt.jdq.annotation;
2 |
3 | import com.beyt.jdq.config.ArgumentResolversInitConfig;
4 | import com.beyt.jdq.resolver.CriteriaListArgumentResolver;
5 | import com.beyt.jdq.resolver.DynamicQueryArgumentResolver;
6 | import org.springframework.context.annotation.Import;
7 |
8 | import java.lang.annotation.ElementType;
9 | import java.lang.annotation.Retention;
10 | import java.lang.annotation.RetentionPolicy;
11 | import java.lang.annotation.Target;
12 |
13 | @Retention(RetentionPolicy.RUNTIME)
14 | @Import({ArgumentResolversInitConfig.class, CriteriaListArgumentResolver.class, DynamicQueryArgumentResolver.class})
15 | @Target({ElementType.TYPE})
16 | @EnableJpaDynamicQuery
17 | public @interface EnableJpaDynamicQueryArgumentResolvers {
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/beyt/jdq/annotation/model/JdqField.java:
--------------------------------------------------------------------------------
1 | package com.beyt.jdq.annotation.model;
2 |
3 |
4 | import java.lang.annotation.ElementType;
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 | import java.lang.annotation.Target;
8 |
9 | @Retention(RetentionPolicy.RUNTIME)
10 | @Target({ElementType.FIELD})
11 | public @interface JdqField {
12 | String value();
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/beyt/jdq/annotation/model/JdqIgnoreField.java:
--------------------------------------------------------------------------------
1 | package com.beyt.jdq.annotation.model;
2 |
3 |
4 | import java.lang.annotation.ElementType;
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 | import java.lang.annotation.Target;
8 |
9 | @Retention(RetentionPolicy.RUNTIME)
10 | @Target({ElementType.FIELD})
11 | public @interface JdqIgnoreField {
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/beyt/jdq/annotation/model/JdqModel.java:
--------------------------------------------------------------------------------
1 | package com.beyt.jdq.annotation.model;
2 |
3 |
4 | import java.lang.annotation.ElementType;
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 | import java.lang.annotation.Target;
8 |
9 | @Retention(RetentionPolicy.RUNTIME)
10 | @Target({ElementType.TYPE})
11 | public @interface JdqModel {
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/beyt/jdq/annotation/model/JdqSubModel.java:
--------------------------------------------------------------------------------
1 | package com.beyt.jdq.annotation.model;
2 |
3 |
4 | import java.lang.annotation.ElementType;
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 | import java.lang.annotation.Target;
8 |
9 | @Retention(RetentionPolicy.RUNTIME)
10 | @Target({ElementType.FIELD})
11 | public @interface JdqSubModel {
12 | String value() default "";
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/beyt/jdq/config/ArgumentResolversInitConfig.java:
--------------------------------------------------------------------------------
1 | package com.beyt.jdq.config;
2 |
3 | import com.beyt.jdq.resolver.CriteriaListArgumentResolver;
4 | import com.beyt.jdq.resolver.DynamicQueryArgumentResolver;
5 | import org.springframework.beans.factory.config.BeanDefinition;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.context.annotation.Role;
8 | import org.springframework.web.method.support.HandlerMethodArgumentResolver;
9 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
10 |
11 | import java.util.List;
12 |
13 | @Configuration
14 | @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
15 | public class ArgumentResolversInitConfig implements WebMvcConfigurer {
16 |
17 | private final CriteriaListArgumentResolver criteriaListArgumentResolver;
18 | private final DynamicQueryArgumentResolver dynamicQueryArgumentResolver;
19 |
20 | public ArgumentResolversInitConfig(CriteriaListArgumentResolver criteriaListArgumentResolver, DynamicQueryArgumentResolver dynamicQueryArgumentResolver) {
21 | this.criteriaListArgumentResolver = criteriaListArgumentResolver;
22 | this.dynamicQueryArgumentResolver = dynamicQueryArgumentResolver;
23 | }
24 |
25 | @Override
26 | public void addArgumentResolvers(List resolvers) {
27 | resolvers.add(criteriaListArgumentResolver);
28 | resolvers.add(dynamicQueryArgumentResolver);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/beyt/jdq/config/DeserializerConfig.java:
--------------------------------------------------------------------------------
1 | package com.beyt.jdq.config;
2 |
3 | import com.beyt.jdq.deserializer.BasicDeserializer;
4 | import com.beyt.jdq.deserializer.IDeserializer;
5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 |
9 | @Configuration
10 | public class DeserializerConfig {
11 |
12 | @Bean
13 | @ConditionalOnMissingBean
14 | public IDeserializer basicDeserializer() {
15 | return new BasicDeserializer();
16 | // return new JacksonDeserializer();// TODO
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/beyt/jdq/config/EntityManagerProviderConfig.java:
--------------------------------------------------------------------------------
1 | package com.beyt.jdq.config;
2 |
3 | import com.beyt.jdq.provider.IEntityManagerProvider;
4 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.context.annotation.Configuration;
7 |
8 | import jakarta.persistence.EntityManager;
9 |
10 | @Configuration
11 | public class EntityManagerProviderConfig {
12 |
13 | @Bean
14 | @ConditionalOnMissingBean
15 | public IEntityManagerProvider entityManagerProvider(EntityManager entityManager) {
16 | return () -> entityManager;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/beyt/jdq/deserializer/BasicDeserializer.java:
--------------------------------------------------------------------------------
1 | package com.beyt.jdq.deserializer;
2 |
3 | import com.beyt.jdq.util.ReflectionUtil;
4 |
5 | public class BasicDeserializer implements IDeserializer {
6 | @Override
7 | public T deserialize(Object value, Class clazz) throws Exception {
8 | return ReflectionUtil.deserializeObject(value.toString(), clazz);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/beyt/jdq/deserializer/IDeserializer.java:
--------------------------------------------------------------------------------
1 | package com.beyt.jdq.deserializer;
2 |
3 | public interface IDeserializer {
4 | T deserialize(Object value, Class clazz) throws Exception;
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/com/beyt/jdq/deserializer/JacksonDeserializer.java:
--------------------------------------------------------------------------------
1 | package com.beyt.jdq.deserializer;
2 |
3 | import com.fasterxml.jackson.databind.DeserializationFeature;
4 | import com.fasterxml.jackson.databind.MapperFeature;
5 | import com.fasterxml.jackson.databind.ObjectMapper;
6 | import com.fasterxml.jackson.databind.json.JsonMapper;
7 |
8 | public class JacksonDeserializer implements IDeserializer {
9 |
10 | public static final ObjectMapper mapper;
11 |
12 | static {
13 | mapper = JsonMapper.builder()
14 | .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS)
15 | .build();
16 | mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
17 | }
18 |
19 | @Override
20 | public T deserialize(Object value, Class clazz) throws Exception {
21 | if (value.getClass().isAssignableFrom(clazz)) {
22 | return (T) value;
23 | }
24 |
25 | if (clazz.isEnum()) {
26 | return (T) Enum.valueOf((Class) clazz, value.toString());
27 | }
28 | return mapper.readValue(value.toString(), clazz);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/beyt/jdq/dto/Criteria.java:
--------------------------------------------------------------------------------
1 | package com.beyt.jdq.dto;
2 |
3 |
4 | import com.beyt.jdq.dto.enums.CriteriaOperator;
5 | import lombok.Getter;
6 | import lombok.Setter;
7 |
8 | import java.io.Serializable;
9 | import java.util.Arrays;
10 | import java.util.Collection;
11 | import java.util.List;
12 |
13 | /**
14 | * Created by tdilber at 24-Aug-19
15 | */
16 | @Getter
17 | @Setter
18 | public class Criteria implements Serializable {
19 | protected String key;
20 | protected CriteriaOperator operation;
21 | protected List