#86 开始实现动态搜索条件组合的功能, 测试下移到showcase项目,不需要依赖em后,改为静态方法。

This commit is contained in:
Calvin
2012-09-20 00:27:54 +08:00
parent 7acad180dc
commit 30a93b7600
6 changed files with 107 additions and 88 deletions
@@ -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<Task> buildSpecification(Long userId, Map<String, Object> filterParams) {
List<SearchFilter> filters = SearchFilter.parse(filterParams);
filters.add(new SearchFilter("user.id", Operator.EQ, userId));
Specification<Task> spec = specBuilder.byWebFilter(filters, Task.class);
Specification<Task> spec = DynamicSpecifications.bySearchFilter(filters, Task.class);
return spec;
}
@@ -42,7 +42,6 @@
<!-- Spring Data Jpa配置 -->
<jpa:repositories base-package="org.springside.examples.quickstart" transaction-manager-ref="transactionManager" entity-manager-factory-ref="entityManagerFactory"/>
<bean class="org.springside.modules.persistence.BySearchFilterSpecification"/>
<!-- Jpa 事务配置 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
@@ -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<Task> 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());
}
}
@@ -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<User, Long> {
public interface UserDao extends PagingAndSortingRepository<User, Long>, JpaSpecificationExecutor<User> {
User findByName(String name);
@@ -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<User> 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<SearchFilter>(), 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());
}
}
@@ -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 <T> Specification<T> byWebFilter(final Collection<SearchFilter> filters, final Class<T> clazz) {
public static <T> Specification<T> bySearchFilter(final Collection<SearchFilter> filters, final Class<T> clazz) {
return new Specification<T>() {
@Override
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder) {