相对于iBatis,Spring Data更容易支持动态查询。本文将简单介绍一下其在nGrinder中的应用。
本例中会用到nGrinder 代码中的 测试项目类 PerfTest.java
/**
* Peformance Test Entity
*
*/
@Entity
@Table(name = "PERF_TEST")
public class PerfTest extends BaseModel<PerfTest> {
/**
* UUID
*/
private static final long serialVersionUID = 1369809450686098944L;
@Column(name = "name")
private String name;
@Column(length = 2048)
private String description;
@Enumerated(EnumType.STRING)
private Status status = Status.READY;
...
}
现在想做一个查询,条件是所有状态为 (FINISHED, ENDED)的测试项目
如果用SQL语句实现为
select * from perf_test where status in (‘FINISHED’, ‘ENDED’)
为了代码更有延伸性,我们在
PerfTestRepository加入了
JpaSpecificationExecutor<PerfTest>
import java.util.List;
import org.ngrinder.perftest.model.PerfTest;
import org.ngrinder.perftest.model.Status;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface PerfTestRepository extends JpaRepository<PerfTest, Integer>, JpaSpecificationExecutor<PerfTest> {
List<PerfTest> findAllByStatusOrderByCreateDateAsc(Status status);
}
在PerfTestRepository中会有常用的方法
/**
* Returns a single entity matching the given {@link Specification}.
*
* @param spec
* @return
*/
T findOne(Specification<T> spec);
/**
* Returns all entities matching the given {@link Specification}.
*
* @param spec
* @return
*/
List<T> findAll(Specification<T> spec);
/**
* Returns a {@link Page} of entities matching the given {@link Specification}.
*
* @param spec
* @param pageable
* @return
*/
Page<T> findAll(Specification<T> spec, Pageable pageable);
/**
* Returns all entities matching the given {@link Specification} and {@link Sort}.
*
* @param spec
* @param sort
* @return
*/
List<T> findAll(Specification<T> spec, Sort sort);
/**
* Returns the number of instances that the given {@link Specification} will return.
*
* @param spec the {@link Specification} to count instances for
* @return the number of instances
*/
long count(Specification<T> spec);
这些方法会根据对应的
查询规范(Specification)动态的生成SQL语句,以下为在PerfTest中加入的“
查询规范”
/**
* Peformance Test Entity
*
*/
@Entity
@Table(name = "PERF_TEST")
public class PerfTest extends BaseModel<PerfTest> {
....
public static Specification<PerfTest> statusSetEqual(final Status... statuses) {
return new Specification<PerfTest>() {
@Override
public Predicate toPredicate(Root<PerfTest> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.not(root.get("status").in((Object[]) statuses));
}
};
}
}
下面会测试代码
public class PerfTestRepositoryTest extends NGrinderIocTransactionalTestBase {
@Autowired
public PerfTestRepository repo;
@Before
public void before() {
PerfTest entity = new PerfTest();
entity.setStatus(Status.FINISHED);
repo.save(entity);
PerfTest entity2 = new PerfTest();
entity2.setStatus(Status.CANCELED);
repo.save(entity2);
PerfTest entity3 = new PerfTest();
entity3.setStatus(Status.READY);
repo.save(entity3);
}
@Test
public void testPerfTest() {
List<PerfTest> findAll = repo.findAll(PerfTest.statusSetEqual(Status.FINISHED, Status.CANCELED));
assertThat(findAll.size(), is(2));
}
}