网站做动态图片大全,新闻类网站开发特点,网站栏目做树形结构图,seo网站排名优化服务这是Project Student的一部分。 其他职位包括带有Jersey的Webservice Client#xff0c;带有Jersey的 Webservice Server #xff0c; 业务层 #xff0c; 具有Spring Data的持久性 #xff0c;分片集成测试数据和Webservice Integration 。 我们已经介绍了CRUD的基本操作… 这是Project Student的一部分。 其他职位包括带有Jersey的Webservice Client带有Jersey的 Webservice Server 业务层 具有Spring Data的持久性 分片集成测试数据和Webservice Integration 。 我们已经介绍了CRUD的基本操作但是并没有花太多时间。 Spring Data使包含基本搜索变得容易但是拥有其他标准选项也很重要。 JPA标准查询是最重要的查询之一。 Spring Data JPA教程– JPA Criteria Queries [http://www.petrikainulainen.net]是对该材料的很好介绍。 设计决策 JPA标准 –我使用的是JPA标准搜索而不是querydsl。 稍后我将返回querydsl。 局限性 违反封装 –此设计需要打破使每个层完全不了解其他层的实现细节的体系结构目标。 这是一个非常小的违反行为-仅JPA规范-我们仍然必须处理分页。 将它们放在一起我觉得此时过分担心这个还为时过早。 Web服务 -不更新web服务客户端和服务器。 同样我们仍然必须处理分页并且无论如何我们现在要做的任何事情都必须更改。 重构先前的工作 我对以前的工作有三点改变。 findCoursesByTestRun 我已经定义了方法 List findCoursesByTestRun(TestRun testRun); 在课程库中。 那没有预期的效果。 我需要的是 List findCoursesByTestRun_Uuid(String uuid); 对调用代码进行适当的更改。 或者您可以只使用下面讨论的JPA标准查询。 FinderService和ManagerService 这来自Jumpstart网站上的研究。 作者将标准服务接口分为两部分 FinderService –只读操作搜索 ManagerService –读写操作创建更新删除 这很有道理例如当我们可以在类与方法级别上进行操作时通过AOP添加行为会容易得多。 我在现有代码中做了适当的更改。 查找错误 我已经修复了FindBugs发现的许多问题。 元数据 我们首先启用对持久对象的元数据访问权限。 这使我们能够创建可以通过JPA实现进行优化的查询。 import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.StaticMetamodel;StaticMetamodel(Course.class)
public class Course_ {public static volatile SingularAttributeCourse, TestRun testRun;
} 和 StaticMetamodel(TestRun.class)
public class TestRun_ {public static volatile SingularAttributeTestRun, String uuid;
} 由于约定优于配置因此需要类的名称。 有关此功能的讨论请参见静态元数据 [jboss.org]。 技术指标 现在我们可以使用现在可用的元数据创建查询规范。 这是一个稍微复杂的查询因为我们需要深入研究结构。 由于testrun uuid用作外键因此这不需要实际的联接。 public class CourseSpecifications {/*** Creates a specification used to find courses with the specified testUuid.* * param testRun* return*/public static SpecificationCourse testRunIs(final TestRun testRun) {return new SpecificationCourse() {Overridepublic Predicate toPredicate(RootCourse courseRoot, CriteriaQuery? query, CriteriaBuilder cb) {Predicate p null;if (testRun null || testRun.getUuid() null) {p cb.isNull(courseRoot.Course_ get(testRun));} else {p cb.equal(courseRoot.Course_ get(testRun).TestRun_ get(uuid), testRun.getUuid());}return p;}};}
} 一些文档建议我可以使用getCourse_.testRun代替get“ testRun”但是eclipse在get方法上将其标记为类型冲突。 你的旅费可能会改变。 Spring数据仓库 我们必须告诉Spring Data我们正在使用JPA Criteria查询。 这是通过扩展JpaSpecificationExecutor接口来完成的。 Repository
public interface CourseRepository extends JpaRepositoryCourse, Integer,JpaSpecificationExecutorCourse {Course findCourseByUuid(String uuid);List findCoursesByTestRunUuid(String uuid);
}FinderService实施 现在我们可以在服务实现中使用JPA规范。 如上所述使用JPA标准规范违反了封装。 import static com.invariantproperties.sandbox.student.specification.CourseSpecifications.testRunIs;Service
public class CourseFinderServiceImpl implements CourseFinderService {Resourceprivate CourseRepository courseRepository;/*** see com.invariantproperties.sandbox.student.business.FinderService#* count()*/Transactional(readOnly true)Overridepublic long count() {return countByTestRun(null);}/*** see com.invariantproperties.sandbox.student.business.FinderService#* countByTestRun(com.invariantproperties.sandbox.student.domain.TestRun)*/Transactional(readOnly true)Overridepublic long countByTestRun(TestRun testRun) {long count 0;try {count courseRepository.count(testRunIs(testRun));} catch (DataAccessException e) {if (!(e instanceof UnitTestException)) {log.info(internal error retrieving classroom count by testRun, e);}throw new PersistenceException(unable to count classrooms by testRun, e, 0);}return count;}/*** see com.invariantproperties.sandbox.student.business.CourseFinderService#* findAllCourses()*/Transactional(readOnly true)Overridepublic ListCourse findAllCourses() {return findCoursesByTestRun(null);}/*** see com.invariantproperties.sandbox.student.business.CourseFinderService#* findCoursesByTestRun(java.lang.String)*/Transactional(readOnly true)Overridepublic ListCourse findCoursesByTestRun(TestRun testRun) {ListCourse courses null;try {courses courseRepository.findAll(testRunIs(testRun));} catch (DataAccessException e) {if (!(e instanceof UnitTestException)) {log.info(error loading list of courses: e.getMessage(), e);}throw new PersistenceException(unable to get list of courses., e);}return courses;}....
}单元测试 我们的单元测试需要稍做更改才能使用规范。 public class CourseFinderServiceImplTest {private final ClassSpecificationCourse sClass null;Testpublic void testCount() {final long expected 3;final CourseRepository repository Mockito.mock(CourseRepository.class);when(repository.count(any(sClass))).thenReturn(expected);final CourseFinderService service new CourseFinderServiceImpl(repository);final long actual service.count();assertEquals(expected, actual);}Testpublic void testCountByTestRun() {final long expected 3;final TestRun testRun new TestRun();final CourseRepository repository Mockito.mock(CourseRepository.class);when(repository.count(any(sClass))).thenReturn(expected);final CourseFinderService service new CourseFinderServiceImpl(repository);final long actual service.countByTestRun(testRun);assertEquals(expected, actual);}Test(expected PersistenceException.class)public void testCountError() {final CourseRepository repository Mockito.mock(CourseRepository.class);when(repository.count(any(sClass))).thenThrow(new UnitTestException());final CourseFinderService service new CourseFinderServiceImpl(repository);service.count();}Testpublic void testFindAllCourses() {final ListCourse expected Collections.emptyList();final CourseRepository repository Mockito.mock(CourseRepository.class);when(repository.findAll(any(sClass))).thenReturn(expected);final CourseFinderService service new CourseFinderServiceImpl(repository);final ListCourse actual service.findAllCourses();assertEquals(expected, actual);}Test(expected PersistenceException.class)public void testFindAllCoursesError() {final CourseRepository repository Mockito.mock(CourseRepository.class);final ClassSpecificationCourse sClass null;when(repository.findAll(any(sClass))).thenThrow(new UnitTestException());final CourseFinderService service new CourseFinderServiceImpl(repository);service.findAllCourses();}Testpublic void testFindCourseByTestUuid() {final TestRun testRun new TestRun();final Course course new Course();final ListCourse expected Collections.singletonList(course);final CourseRepository repository Mockito.mock(CourseRepository.class);when(repository.findAll(any(sClass))).thenReturn(expected);final CourseFinderService service new CourseFinderServiceImpl(repository);final List actual service.findCoursesByTestRun(testRun);assertEquals(expected, actual);}Test(expected PersistenceException.class)public void testFindCourseByTestUuidError() {final TestRun testRun new TestRun();final CourseRepository repository Mockito.mock(CourseRepository.class);when(repository.findAll(any(sClass))).thenThrow(new UnitTestException());final CourseFinderService service new CourseFinderServiceImpl(repository);service.findCoursesByTestRun(testRun);}Testpublic void testFindCoursesByTestUuid() {final TestRun testRun new TestRun();final Course course new Course();final ListCourse expected Collections.singletonList(course);final CourseRepository repository Mockito.mock(CourseRepository.class);when(repository.findAll(any(sClass))).thenReturn(expected);final CourseFinderService service new CourseFinderServiceImpl(repository);final ListCourse actual service.findCoursesByTestRun(testRun);assertEquals(expected, actual);}Test(expected PersistenceException.class)public void testFindCoursesByTestUuidError() {final TestRun testRun new TestRun();final CourseRepository repository Mockito.mock(CourseRepository.class);when(repository.findAll(any(sClass))).thenThrow(new UnitTestException());final CourseFinderService service new CourseFinderServiceImpl(repository);service.findCoursesByTestRun(testRun);}....
} 通过使用Begin方法我可以消除很多重复的代码但是我决定反对它来支持并行测试。 整合测试 我们终于来进行集成测试了。 我们知道我们做对了因为只有一行可以测试附加功能-计算数据库中的课程数量。 RunWith(SpringJUnit4ClassRunner.class)
ContextConfiguration(classes { BusinessApplicationContext.class, TestBusinessApplicationContext.class,TestPersistenceJpaConfig.class })
Transactional
TransactionConfiguration(defaultRollback true)
public class CourseServiceIntegrationTest {Resourceprivate CourseFinderService fdao;Resourceprivate CourseManagerService mdao;Resourceprivate TestRunService testService;Testpublic void testCourseLifecycle() throws Exception {final TestRun testRun testService.createTestRun();final String name Calculus 101 : testRun.getUuid();final Course expected new Course();expected.setName(name);assertNull(expected.getId());// create courseCourse actual mdao.createCourseForTesting(name, testRun);expected.setId(actual.getId());expected.setUuid(actual.getUuid());expected.setCreationDate(actual.getCreationDate());assertThat(expected, equalTo(actual));assertNotNull(actual.getUuid());assertNotNull(actual.getCreationDate());// get course by idactual fdao.findCourseById(expected.getId());assertThat(expected, equalTo(actual));// get course by uuidactual fdao.findCourseByUuid(expected.getUuid());assertThat(expected, equalTo(actual));// get all coursesfinal ListCourse courses fdao.findCoursesByTestRun(testRun);assertTrue(courses.contains(actual));// count coursesfinal long count fdao.countByTestRun(testRun);assertTrue(count 0);// update courseexpected.setName(Calculus 102 : testRun.getUuid());actual mdao.updateCourse(actual, expected.getName());assertThat(expected, equalTo(actual));// delete Coursemdao.deleteCourse(expected.getUuid(), 0);try {fdao.findCourseByUuid(expected.getUuid());fail(exception expected);} catch (ObjectNotFoundException e) {// expected}testService.deleteTestRun(testRun.getUuid());}
}源代码 可从http://code.google.com/p/invariant-properties-blog/source/browse/student获取源代码。 参考 项目学生 Invariant Properties博客上来自JCG合作伙伴 Bear Giles的JPA标准查询 。 翻译自: https://www.javacodegeeks.com/2014/01/project-student-jpa-criteria-queries.html