相對於iBatis,Spring Data更容易支持動態查詢。本文將簡單介紹一下其在nGrinder中的應用。 java
本例中會用到nGrinder 代碼中的 測試項目類 PerfTest.java spring
/** * 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
若是用SQL語句實現爲 ide
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)); } }