SpringJPA: Querydsl VS Spring Specifications
authorGustavo Martin Morcuende <gu.martinm@gmail.com>
Mon, 11 Jul 2016 20:00:41 +0000 (22:00 +0200)
committerGustavo Martin Morcuende <gu.martinm@gmail.com>
Mon, 11 Jul 2016 20:00:41 +0000 (22:00 +0200)
Querydsl is easier than Specifications and JPA Criterias.

SpringJava/JPA/src/main/java/de/spring/example/persistence/domain/specifications/AdSpectifications.java [new file with mode: 0644]
SpringJava/JPA/src/main/java/de/spring/example/persistence/repository/AdRepository.java
SpringJava/JPA/src/main/java/de/spring/example/services/AdService.java [new file with mode: 0644]
SpringJava/JPA/src/main/java/de/spring/example/services/impl/AdDescriptionServiceImpl.java
SpringJava/JPA/src/main/java/de/spring/example/services/impl/AdServiceImpl.java [new file with mode: 0644]

diff --git a/SpringJava/JPA/src/main/java/de/spring/example/persistence/domain/specifications/AdSpectifications.java b/SpringJava/JPA/src/main/java/de/spring/example/persistence/domain/specifications/AdSpectifications.java
new file mode 100644 (file)
index 0000000..6ee3644
--- /dev/null
@@ -0,0 +1,42 @@
+package de.spring.example.persistence.domain.specifications;
+
+import java.time.LocalDate;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.springframework.data.jpa.domain.Specification;
+
+import de.spring.example.persistence.domain.Ad;
+
+public class AdSpectifications {
+       
+       public static Specification<Ad> createdToday() {
+               return new Specification<Ad>() {
+
+                       @Override
+                       public Predicate toPredicate(Root<Ad> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
+                               final LocalDate date = LocalDate.now();
+                               
+                               return cb.equal(root.get("createdAt"), date);
+                       }
+
+               };
+               
+       }
+       
+       public static Specification<Ad> mobileImage(String image) {
+               return new Specification<Ad>() {
+
+                       @Override
+                       public Predicate toPredicate(Root<Ad> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
+                               
+                               return cb.equal(root.get("adMobileImage"), image);
+                       }
+
+               };
+               
+       }
+}
index 592e241..bc73359 100644 (file)
@@ -1,5 +1,6 @@
 package de.spring.example.persistence.repository;
 
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.PagingAndSortingRepository;
 import org.springframework.data.repository.query.Param;
@@ -13,7 +14,7 @@ import de.spring.example.persistence.domain.Ad;
  * Be careful with <code>@Transactional</code>. SimpleJpaRepository has annotated methods.
  *
  */
-public interface AdRepository extends PagingAndSortingRepository<Ad, Long> {
+public interface AdRepository extends PagingAndSortingRepository<Ad, Long>, JpaSpecificationExecutor<Ad> {
        
        // Named Native Query (using the native language of the store) It is not portable.
        // See de.spring.persistence.example.domain.Ad
diff --git a/SpringJava/JPA/src/main/java/de/spring/example/services/AdService.java b/SpringJava/JPA/src/main/java/de/spring/example/services/AdService.java
new file mode 100644 (file)
index 0000000..c491be8
--- /dev/null
@@ -0,0 +1,12 @@
+package de.spring.example.services;
+
+import org.resthub.common.service.CrudService;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+
+import de.spring.example.persistence.domain.Ad;
+
+public interface AdService extends CrudService<Ad, Long> {
+       
+       public Page<Ad> queryCriteriaExample(Pageable pageRequest);
+}
index 6218840..7f5a681 100644 (file)
@@ -33,6 +33,12 @@ public class AdDescriptionServiceImpl
        
        /**
         * Using Querydsl. Giving some business logic to this service :)
+        * 
+        * Querydsl: fluent interface done easy. There is no effort because it is already implemented.
+        * 
+        * Criteria using Specifications requires some effort.
+        * 
+        * See: de.spring.example.services.impl.AdServiceImpl
         */
        @Override
        public Page<AdDescription> queryDslExample(Pageable pageRequest) {
diff --git a/SpringJava/JPA/src/main/java/de/spring/example/services/impl/AdServiceImpl.java b/SpringJava/JPA/src/main/java/de/spring/example/services/impl/AdServiceImpl.java
new file mode 100644 (file)
index 0000000..619fcb2
--- /dev/null
@@ -0,0 +1,41 @@
+package de.spring.example.services.impl;
+
+import static org.springframework.data.jpa.domain.Specifications.where;
+
+import javax.inject.Inject;
+
+import org.resthub.common.service.CrudServiceImpl;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+
+import de.spring.example.persistence.domain.Ad;
+import de.spring.example.persistence.domain.specifications.AdSpectifications;
+import de.spring.example.persistence.repository.AdRepository;
+import de.spring.example.services.AdService;
+
+public class AdServiceImpl
+       extends CrudServiceImpl<Ad, Long, AdRepository>
+       implements AdService {
+       
+       @Override
+       @Inject
+    public void setRepository(AdRepository repository) {
+        this.repository = repository;
+    }
+
+       /**
+        * Criteria using Specifications.
+        * 
+        * It is more complicated that when using Querydsl because I have to implement the
+        * Specifications. Querydsl is doing everything for me.
+        * 
+        * See: de.spring.example.services.impl.AdDescriptionServiceImpl
+        */
+       @Override
+       public Page<Ad> queryCriteriaExample(Pageable pageRequest) {
+               return repository.findAll(
+                               where(AdSpectifications.createdToday()).and(AdSpectifications.mobileImage("picasso")),
+                               pageRequest);           
+       }
+
+}