Spring Data JPA 简单介绍

背景
考虑到公司应用中数据库访问的多样性和复杂性,目前正在开发UDSL(统一数据访问层),开发到一半的时候,偶遇SpringData工程。发现两者的思路惊人的一致。
于是就花了点时间了解SpringData,可能UDSL II期会基于SpringData做扩展

SpringData相关资料
介绍:针对关系型数据库,KV数据库,Document数据库,Graph数据库,Map-Reduce等一些主流数据库,采用统一技术进行访问,并且尽可能简化访问手段。
目前已支持的数据库有(主要):MongoDB,Neo4j,Redis,Hadoop,JPA等

SpringData官方资料(强烈推荐,文档非常详细)
SpringData主页:http://www.springsource.org/spring-data
SpringDataJPA 指南文档:http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html/(非常详细)
SpringDataJPA Examples:https://github.com/SpringSource/spring-data-jpa-examples (非常详细的例子)

Spring-Data-Jpa简介
Spring Data Jpa 极大简化了数据库访问层代码,只要3步,就能搞定一切
1. 编写Entity类,依照JPA规范,定义实体
2. 编写Repository接口,依靠SpringData规范,定义数据访问接口(注意,只要接口,不需要任何实现)
3. 写一小陀配置文件 (Spring Scheme配置方式极大地简化了配置方式)

下面,我依赖Example中的例子,简单地介绍下以上几个步骤
User.java


1 /**
2 *UserEntitySample
3 *
4 * @author <ahref="mailto:[email protected]">Stone.J</a>Aug25,2011
5 */
6@Entity
7 public classUser extendsAbstractPersistable<Long>{
8
9 private static final longserialVersionUID=-2952735933715107252L;
10
11@Column(unique= true)
12 privateStringusername;
13 privateStringfirstname;
14 privateStringlastname;
15
16 publicStringgetUsername(){
17 returnusername;
18}
19
20 public voidsetUsername(Stringusername){
21 this.username=username;
22}
23
24 publicStringgetFirstname(){
25 returnfirstname;
26}
27
28 public voidsetFirstname(Stringfirstname){
29 this.firstname=firstname;
30}
31
32 publicStringgetLastname(){
33 returnlastname;
34}
35
36 public voidsetLastname(Stringlastname){
37 this.lastname=lastname;
38}
39

没什么技术,JPA规范要求怎么写,它就怎么写

Repository.java


1 /**
2 *UserRepositoryInterface.
3 *
4 * @author <ahref="mailto:[email protected]">Stone.J</a>Aug25,2011
5 */
6 public interfaceSimpleUserRepository extendsCrudRepository<User,Long>,JpaSpecificationExecutor<User>{
7
8 publicUserfindByTheUsersName(Stringusername);
9
10 publicList<User>findByLastname(Stringlastname);
11
12@Query("selectufromUseruwhereu.firstname=?")
13 publicList<User>findByFirstname(Stringfirstname);
14
15@Query("selectufromUseruwhereu.firstname=:nameoru.lastname=:name")
16 publicList<User>findByFirstnameOrLastname(@Param("name")Stringname);
17
18

需要关注它继承的接口,我简单介绍几个核心接口

Repository: 仅仅是一个标识,表明任何继承它的均为仓库接口类,方便Spring自动扫描识别
CrudRepository: 继承Repository,实现了一组CRUD相关的方法
PagingAndSortingRepository: 继承CrudRepository,实现了一组分页排序相关的方法
JpaRepository: 继承PagingAndSortingRepository,实现一组JPA规范相关的方法
JpaSpecificationExecutor: 比较特殊,不属于Repository体系,实现一组JPA Criteria查询相关的方法

不需要写任何实现类,Spring Data Jpa框架帮你搞定这一切。

Spring Configuration

1<beans>
2<beanid="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
3<propertyname="dataSource"ref="dataSource"/>
4<propertyname="jpaVendorAdapter">
5<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
6<propertyname="generateDdl"value="true"/>
7<propertyname="database"value="HSQL"/>
8</bean>
9</property>
10<propertyname="persistenceUnitName"value="jpa.sample"/>
11</bean>
12
13<beanid="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
14<propertyname="entityManagerFactory"ref="entityManagerFactory"/>
15</bean>
16
17<jdbc:embedded-databaseid="dataSource"type="HSQL"/>
18
19
20<jpa:repositoriesbase- package="org.springframework.data.jpa.example.repository.simple"/>
21</beans>

核心代码只要配置一行:<jpa:repositories base-package="org.springframework.data.jpa.example.repository.simple" />即可。上面的仅仅是数据源,事务的配置而已。

至此,大功告成,即可运行

1 /**
2 *Intergrationtestshowingthebasicusageof{ @link SimpleUserRepository}.
3 *
4 * @author <ahref="mailto:[email protected]">Stone.J</a>Aug25,2011
5 */
6@RunWith(SpringJUnit4ClassRunner. class)
7@ContextConfiguration(locations="classpath:simple-repository-context.xml")
8@Transactional
9 public classSimpleUserRepositorySample{
10
11@Autowired
12SimpleUserRepositoryrepository;
13Useruser;
14
15@Before
16 public voidsetUp(){
17user= newUser();
18user.setUsername("foobar");
19user.setFirstname("firstname");
20user.setLastname("lastname");
21}
22
23 // crud方法测试
24@Test
25 public voidtestCrud(){
26user=repository.save(user);
27assertEquals(user,repository.findOne(user.getId()));
28}
29
30 // methodquery测试
31@Test
32 public voidtestMethodQuery() throwsException{
33user=repository.save(user);
34List<User>users=repository.findByLastname("lastname");
35assertNotNull(users);
36assertTrue(users.contains(user));
37}
38
39 // namedquery测试
40@Test
41 public voidtestNamedQuery() throwsException{
42user=repository.save(user);
43List<User>users=repository.findByFirstnameOrLastname("lastname");
44assertTrue(users.contains(user));
45}
46
47 // criteriaquery测试
48@Test
49 public voidtestCriteriaQuery() throwsException{
50user=repository.save(user);
51List<User>users=repository.findAll( newSpecification<User>(){
52
53@Override
54 publicPredicatetoPredicate(Root<User>root,CriteriaQuery<?>query,CriteriaBuildercb){
55 returncb.equal(root.get("lastname"),"lastname");
56}
57});
58assertTrue(users.contains(user));
59}
60

其中,写操作相对比较简单,我不做详细介绍,针对读操作,我稍微描述下:
Method Query: 方法级别的查询,针对 findBy,find,readBy,read,getBy等前缀的方法,解析方法字符串,生成查询语句,其中支持的关键词有:
Spring Data JPA 简单介绍_第1张图片

Named Query: 针对一些复杂的SQL,支持原生SQL方式,进行查询,保证性能
Criteria Query: 支持JPA标准中的Criteria Query

备注:
本文只是简单介绍SpringDataJpa功能,要深入了解的同学,建议直接传送到 官方网站

你可能感兴趣的:(spring)