From 30a93b7600bcd7a8d2b5cd0d110920e0102b6dc4 Mon Sep 17 00:00:00 2001 From: Calvin Date: Thu, 20 Sep 2012 00:27:54 +0800 Subject: [PATCH] =?UTF-8?q?#86=20=E5=BC=80=E5=A7=8B=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E6=90=9C=E7=B4=A2=E6=9D=A1=E4=BB=B6=E7=BB=84?= =?UTF-8?q?=E5=90=88=E7=9A=84=E5=8A=9F=E8=83=BD,=20=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=B8=8B=E7=A7=BB=E5=88=B0showcase=E9=A1=B9=E7=9B=AE=EF=BC=8C?= =?UTF-8?q?=E4=B8=8D=E9=9C=80=E8=A6=81=E4=BE=9D=E8=B5=96em=E5=90=8E?= =?UTF-8?q?=EF=BC=8C=E6=94=B9=E4=B8=BA=E9=9D=99=E6=80=81=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../quickstart/service/task/TaskService.java | 7 +- .../src/main/resources/applicationContext.xml | 1 - .../quickstart/repository/TaskDaoTest.java | 80 +-------------- .../showcase/repository/jpa/UserDao.java | 3 +- .../jpa/DynamicSpecificationTest.java | 98 +++++++++++++++++++ ...cation.java => DynamicSpecifications.java} | 6 +- 6 files changed, 107 insertions(+), 88 deletions(-) create mode 100644 examples/showcase/src/test/java/org/springside/examples/showcase/repository/jpa/DynamicSpecificationTest.java rename modules/core/src/main/java/org/springside/modules/persistence/{BySearchFilterSpecification.java => DynamicSpecifications.java} (90%) diff --git a/examples/quickstart/src/main/java/org/springside/examples/quickstart/service/task/TaskService.java b/examples/quickstart/src/main/java/org/springside/examples/quickstart/service/task/TaskService.java index 33e2b863..0246f1c7 100644 --- a/examples/quickstart/src/main/java/org/springside/examples/quickstart/service/task/TaskService.java +++ b/examples/quickstart/src/main/java/org/springside/examples/quickstart/service/task/TaskService.java @@ -13,7 +13,7 @@ import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import org.springside.examples.quickstart.entity.Task; import org.springside.examples.quickstart.repository.TaskDao; -import org.springside.modules.persistence.BySearchFilterSpecification; +import org.springside.modules.persistence.DynamicSpecifications; import org.springside.modules.persistence.SearchFilter; import org.springside.modules.persistence.SearchFilter.Operator; @@ -25,9 +25,6 @@ public class TaskService { private TaskDao taskDao; - @Autowired - private BySearchFilterSpecification specBuilder; - public Task getTask(Long id) { return taskDao.findOne(id); } @@ -74,7 +71,7 @@ public class TaskService { private Specification buildSpecification(Long userId, Map filterParams) { List filters = SearchFilter.parse(filterParams); filters.add(new SearchFilter("user.id", Operator.EQ, userId)); - Specification spec = specBuilder.byWebFilter(filters, Task.class); + Specification spec = DynamicSpecifications.bySearchFilter(filters, Task.class); return spec; } diff --git a/examples/quickstart/src/main/resources/applicationContext.xml b/examples/quickstart/src/main/resources/applicationContext.xml index 926d7b3a..d53b92b3 100644 --- a/examples/quickstart/src/main/resources/applicationContext.xml +++ b/examples/quickstart/src/main/resources/applicationContext.xml @@ -42,7 +42,6 @@ - diff --git a/examples/quickstart/src/test/java/org/springside/examples/quickstart/repository/TaskDaoTest.java b/examples/quickstart/src/test/java/org/springside/examples/quickstart/repository/TaskDaoTest.java index d8bc5b6c..c12791da 100644 --- a/examples/quickstart/src/test/java/org/springside/examples/quickstart/repository/TaskDaoTest.java +++ b/examples/quickstart/src/test/java/org/springside/examples/quickstart/repository/TaskDaoTest.java @@ -2,9 +2,6 @@ package org.springside.examples.quickstart.repository; import static org.junit.Assert.*; -import java.util.ArrayList; -import java.util.List; - import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; @@ -12,13 +9,9 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort.Direction; import org.springframework.test.context.ContextConfiguration; import org.springside.examples.quickstart.entity.Task; -import org.springside.modules.persistence.BySearchFilterSpecification; -import org.springside.modules.persistence.SearchFilter; -import org.springside.modules.persistence.SearchFilter.Operator; +import org.springside.modules.persistence.DynamicSpecifications; import org.springside.modules.test.spring.SpringTransactionalTestCase; -import com.google.common.collect.Lists; - @ContextConfiguration(locations = { "/applicationContext.xml" }) public class TaskDaoTest extends SpringTransactionalTestCase { @@ -26,7 +19,7 @@ public class TaskDaoTest extends SpringTransactionalTestCase { private TaskDao taskDao; @Autowired - private BySearchFilterSpecification specBuilder; + private DynamicSpecifications specBuilder; @Test public void findTasksByUserId() throws Exception { @@ -37,73 +30,4 @@ public class TaskDaoTest extends SpringTransactionalTestCase { tasks = taskDao.findByUserId(99999L, new PageRequest(0, 100, Direction.ASC, "id")); assertEquals(0, tasks.getContent().size()); } - - @Test - public void fineTasksByFilter() { - - // EQ - SearchFilter filter = new SearchFilter("title", Operator.EQ, "Study PlayFramework 2.0"); - List tasks = taskDao.findAll(specBuilder.byWebFilter(Lists.newArrayList(filter), Task.class)); - assertEquals(1, tasks.size()); - // LIKE - filter = new SearchFilter("description", Operator.LIKE, "playframework"); - tasks = taskDao.findAll(specBuilder.byWebFilter(Lists.newArrayList(filter), Task.class)); - assertEquals(1, tasks.size()); - // GT - filter = new SearchFilter("id", Operator.GT, "1"); - tasks = taskDao.findAll(specBuilder.byWebFilter(Lists.newArrayList(filter), Task.class)); - assertEquals(4, tasks.size()); - - filter = new SearchFilter("id", Operator.GT, "5"); - tasks = taskDao.findAll(specBuilder.byWebFilter(Lists.newArrayList(filter), Task.class)); - assertEquals(0, tasks.size()); - // GTE - filter = new SearchFilter("id", Operator.GTE, "1"); - tasks = taskDao.findAll(specBuilder.byWebFilter(Lists.newArrayList(filter), Task.class)); - assertEquals(5, tasks.size()); - - filter = new SearchFilter("id", Operator.GTE, "5"); - tasks = taskDao.findAll(specBuilder.byWebFilter(Lists.newArrayList(filter), Task.class)); - assertEquals(1, tasks.size()); - - // LT - filter = new SearchFilter("id", Operator.LT, "5"); - tasks = taskDao.findAll(specBuilder.byWebFilter(Lists.newArrayList(filter), Task.class)); - assertEquals(4, tasks.size()); - - filter = new SearchFilter("id", Operator.LT, "1"); - tasks = taskDao.findAll(specBuilder.byWebFilter(Lists.newArrayList(filter), Task.class)); - assertEquals(0, tasks.size()); - // LTE - filter = new SearchFilter("id", Operator.LTE, "5"); - tasks = taskDao.findAll(specBuilder.byWebFilter(Lists.newArrayList(filter), Task.class)); - assertEquals(5, tasks.size()); - - filter = new SearchFilter("id", Operator.LTE, "1"); - tasks = taskDao.findAll(specBuilder.byWebFilter(Lists.newArrayList(filter), Task.class)); - assertEquals(1, tasks.size()); - - // Empty filters - tasks = taskDao.findAll(specBuilder.byWebFilter(new ArrayList(), Task.class)); - assertEquals(5, tasks.size()); - - tasks = taskDao.findAll(specBuilder.byWebFilter(null, Task.class)); - assertEquals(5, tasks.size()); - - // AND 2 Conditions - SearchFilter filter1 = new SearchFilter("title", Operator.EQ, "Study PlayFramework 2.0"); - SearchFilter filter2 = new SearchFilter("description", Operator.LIKE, "playframework"); - tasks = taskDao.findAll(specBuilder.byWebFilter(Lists.newArrayList(filter1, filter2), Task.class)); - assertEquals(1, tasks.size()); - - filter1 = new SearchFilter("title", Operator.EQ, "Study PlayFramework 2.0"); - filter2 = new SearchFilter("description", Operator.LIKE, "springfuse"); - tasks = taskDao.findAll(specBuilder.byWebFilter(Lists.newArrayList(filter1, filter2), Task.class)); - assertEquals(0, tasks.size()); - - // Nest Attribute - filter = new SearchFilter("user.id", Operator.EQ, "2"); - tasks = taskDao.findAll(specBuilder.byWebFilter(Lists.newArrayList(filter), Task.class)); - assertEquals(5, tasks.size()); - } } diff --git a/examples/showcase/src/main/java/org/springside/examples/showcase/repository/jpa/UserDao.java b/examples/showcase/src/main/java/org/springside/examples/showcase/repository/jpa/UserDao.java index 840623dd..c392f39c 100644 --- a/examples/showcase/src/main/java/org/springside/examples/showcase/repository/jpa/UserDao.java +++ b/examples/showcase/src/main/java/org/springside/examples/showcase/repository/jpa/UserDao.java @@ -1,9 +1,10 @@ package org.springside.examples.showcase.repository.jpa; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.PagingAndSortingRepository; import org.springside.examples.showcase.entity.User; -public interface UserDao extends PagingAndSortingRepository { +public interface UserDao extends PagingAndSortingRepository, JpaSpecificationExecutor { User findByName(String name); diff --git a/examples/showcase/src/test/java/org/springside/examples/showcase/repository/jpa/DynamicSpecificationTest.java b/examples/showcase/src/test/java/org/springside/examples/showcase/repository/jpa/DynamicSpecificationTest.java new file mode 100644 index 00000000..b6d8cafa --- /dev/null +++ b/examples/showcase/src/test/java/org/springside/examples/showcase/repository/jpa/DynamicSpecificationTest.java @@ -0,0 +1,98 @@ +package org.springside.examples.showcase.repository.jpa; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springside.examples.showcase.entity.User; +import org.springside.modules.persistence.DynamicSpecifications; +import org.springside.modules.persistence.SearchFilter; +import org.springside.modules.persistence.SearchFilter.Operator; +import org.springside.modules.test.spring.SpringTransactionalTestCase; + +import com.google.common.collect.Lists; + +@ContextConfiguration(locations = { "/applicationContext.xml" }) +public class DynamicSpecificationTest extends SpringTransactionalTestCase { + + @Autowired + private UserDao userDao; + + @Test + public void fineUserByFilter() { + + // EQ + SearchFilter filter = new SearchFilter("name", Operator.EQ, "Admin"); + List users = userDao + .findAll(DynamicSpecifications.bySearchFilter(Lists.newArrayList(filter), User.class)); + assertEquals(1, users.size()); + // LIKE + filter = new SearchFilter("loginName", Operator.LIKE, "min"); + users = userDao.findAll(DynamicSpecifications.bySearchFilter(Lists.newArrayList(filter), User.class)); + assertEquals(1, users.size()); + // GT + filter = new SearchFilter("id", Operator.GT, "1"); + users = userDao.findAll(DynamicSpecifications.bySearchFilter(Lists.newArrayList(filter), User.class)); + assertEquals(5, users.size()); + + filter = new SearchFilter("id", Operator.GT, "6"); + users = userDao.findAll(DynamicSpecifications.bySearchFilter(Lists.newArrayList(filter), User.class)); + assertEquals(0, users.size()); + // GTE + filter = new SearchFilter("id", Operator.GTE, "1"); + users = userDao.findAll(DynamicSpecifications.bySearchFilter(Lists.newArrayList(filter), User.class)); + assertEquals(6, users.size()); + + filter = new SearchFilter("id", Operator.GTE, "6"); + users = userDao.findAll(DynamicSpecifications.bySearchFilter(Lists.newArrayList(filter), User.class)); + assertEquals(1, users.size()); + + // LT + filter = new SearchFilter("id", Operator.LT, "6"); + users = userDao.findAll(DynamicSpecifications.bySearchFilter(Lists.newArrayList(filter), User.class)); + assertEquals(5, users.size()); + + filter = new SearchFilter("id", Operator.LT, "1"); + users = userDao.findAll(DynamicSpecifications.bySearchFilter(Lists.newArrayList(filter), User.class)); + assertEquals(0, users.size()); + // LTE + filter = new SearchFilter("id", Operator.LTE, "6"); + users = userDao.findAll(DynamicSpecifications.bySearchFilter(Lists.newArrayList(filter), User.class)); + assertEquals(6, users.size()); + + filter = new SearchFilter("id", Operator.LTE, "1"); + users = userDao.findAll(DynamicSpecifications.bySearchFilter(Lists.newArrayList(filter), User.class)); + assertEquals(1, users.size()); + + // Empty filters, select all + users = userDao.findAll(DynamicSpecifications.bySearchFilter(new ArrayList(), User.class)); + assertEquals(6, users.size()); + + users = userDao.findAll(DynamicSpecifications.bySearchFilter(null, User.class)); + assertEquals(6, users.size()); + + // AND 2 Conditions + SearchFilter filter1 = new SearchFilter("name", Operator.EQ, "Admin"); + SearchFilter filter2 = new SearchFilter("loginName", Operator.LIKE, "min"); + users = userDao.findAll(DynamicSpecifications.bySearchFilter(Lists.newArrayList(filter1, filter2), User.class)); + assertEquals(1, users.size()); + + filter1 = new SearchFilter("name", Operator.EQ, "Admin"); + filter2 = new SearchFilter("loginName", Operator.LIKE, "user"); + users = userDao.findAll(DynamicSpecifications.bySearchFilter(Lists.newArrayList(filter1, filter2), User.class)); + assertEquals(0, users.size()); + + // Nest Attribute + filter = new SearchFilter("team.id", Operator.EQ, "1"); + users = userDao.findAll(DynamicSpecifications.bySearchFilter(Lists.newArrayList(filter), User.class)); + assertEquals(6, users.size()); + + filter = new SearchFilter("team.id", Operator.EQ, "10"); + users = userDao.findAll(DynamicSpecifications.bySearchFilter(Lists.newArrayList(filter), User.class)); + assertEquals(0, users.size()); + } +} diff --git a/modules/core/src/main/java/org/springside/modules/persistence/BySearchFilterSpecification.java b/modules/core/src/main/java/org/springside/modules/persistence/DynamicSpecifications.java similarity index 90% rename from modules/core/src/main/java/org/springside/modules/persistence/BySearchFilterSpecification.java rename to modules/core/src/main/java/org/springside/modules/persistence/DynamicSpecifications.java index 3390f1cb..8bf5a23b 100644 --- a/modules/core/src/main/java/org/springside/modules/persistence/BySearchFilterSpecification.java +++ b/modules/core/src/main/java/org/springside/modules/persistence/DynamicSpecifications.java @@ -17,10 +17,10 @@ import org.springside.modules.utils.Collections3; import com.google.common.collect.Lists; -public class BySearchFilterSpecification { - private final ConversionService conversionService = new DefaultConversionService(); +public class DynamicSpecifications { + private static final ConversionService conversionService = new DefaultConversionService(); - public Specification byWebFilter(final Collection filters, final Class clazz) { + public static Specification bySearchFilter(final Collection filters, final Class clazz) { return new Specification() { @Override public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) {