Spring Data JPA 简单介绍

背景 

考虑到公司应用中数据库访问的多样性和复杂性,目前正在开发UDSL(统一数据访问层),开发到一半的时候,偶遇SpringData 工程。发现两者的思路惊人的一致。

于是就花了点时间了解SpringData,可能UDSLII期会基于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/(非常详细)

SpringDataJPAExamples:https://github.com/SpringSource/spring-data-jpa-examples(非常详细的例子)

Spring-Data-Jpa简介

SpringDataJpa极大简化了数据库访问层代码,只要3步,就能搞定一切

1.编写Entity类,依照JPA规范,定义实体

2.编写Repository接口,依靠SpringData规范,定义数据访问接口(注意,只要接口,不需要任何实现)

3.写一小陀配置文件(SpringScheme配置方式极大地简化了配置方式)

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

User.java
Spring Data JPA 简单介绍

1/**

2*UserEntitySample

3*

4*@author<ahref="mailto:li.jinl@alibaba-inc.com">Stone.J</a>Aug25,2011

5*/

6@Entity

7publicclassUserextendsAbstractPersistable<Long>{

8

9privatestaticfinallongserialVersionUID=-2952735933715107252L;

10

11@Column(unique=true)

12privateStringusername;

13privateStringfirstname;

14privateStringlastname;

15

16publicStringgetUsername(){

17returnusername;

18}

19

20publicvoidsetUsername(Stringusername){

21this.username=username;

22}

23

24publicStringgetFirstname(){

25returnfirstname;

26}

27

28publicvoidsetFirstname(Stringfirstname){

29this.firstname=firstname;

30}

31

32publicStringgetLastname(){

33returnlastname;

34}

35

36publicvoidsetLastname(Stringlastname){

37this.lastname=lastname;

38}

39  

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

Spring Data JPA 简单介绍

1/**

2*UserRepositoryInterface.

3*

4*@author<ahref="mailto:li.jinl@alibaba-inc.com">Stone.J</a>Aug25,2011

5*/

6publicinterfaceSimpleUserRepositoryextendsCrudRepository<User,Long>,JpaSpecificationExecutor<User>{

7

8publicUserfindByTheUsersName(Stringusername);

9

10publicList<User>findByLastname(Stringlastname);

11

12@Query("selectufromUseruwhereu.firstname=?")

13publicList<User>findByFirstname(Stringfirstname);

14

15@Query("selectufromUseruwhereu.firstname=:nameoru.lastname=:name")

16publicList<User>findByFirstnameOrLastname(@Param("name")Stringname);

17

18  

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

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

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

SpringConfiguration

Spring Data JPA 简单介绍

1<beans>

2<beanid="entityManagerFactory"class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

3<propertyname="dataSource"ref="dataSource"/>

4<propertyname="jpaVendorAdapter">

5<beanclass="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:repositoriesbase-package="org.springframework.data.jpa.example.repository.simple"/>即可。上面的仅仅是数据源,事务的配置而已。

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

Spring Data JPA 简单介绍

1/**

2*Intergrationtestshowingthebasicusageof{@linkSimpleUserRepository}.

3*

4*@author<ahref="mailto:li.jinl@alibaba-inc.com">Stone.J</a>Aug25,2011

5*/

6@RunWith(SpringJUnit4ClassRunner.class)

7@ContextConfiguration(locations="classpath:simple-repository-context.xml")

8@Transactional

9publicclassSimpleUserRepositorySample{

10

11@Autowired

12SimpleUserRepositoryrepository;

13Useruser;

14

15@Before

16publicvoidsetUp(){

17user=newUser();

18user.setUsername("foobar");

19user.setFirstname("firstname");

20user.setLastname("lastname");

21}

22

23//crud方法测试

24@Test

25publicvoidtestCrud(){

26user=repository.save(user);

27assertEquals(user,repository.findOne(user.getId()));

28}

29

30//methodquery测试

31@Test

32publicvoidtestMethodQuery()throwsException{

33user=repository.save(user);

34List<User>users=repository.findByLastname("lastname");

35assertNotNull(users);

36assertTrue(users.contains(user));

37}

38

39//namedquery测试

40@Test

41publicvoidtestNamedQuery()throwsException{

42user=repository.save(user);

43List<User>users=repository.findByFirstnameOrLastname("lastname");

44assertTrue(users.contains(user));

45}

46

47//criteriaquery测试

48@Test

49publicvoidtestCriteriaQuery()throwsException{

50user=repository.save(user);

51List<User>users=repository.findAll(newSpecification<User>(){

52

53@Override

54publicPredicatetoPredicate(Root<User>root,CriteriaQuery<?>query,CriteriaBuildercb){

55returncb.equal(root.get("lastname"),"lastname");

56}

57});

58assertTrue(users.contains(user));

59}

60

其中,写操作相对比较简单,我不做详细介绍,针对读操作,我稍微描述下:

MethodQuery:方法级别的查询,针对findBy,find,readBy,read,getBy等前缀的方法,解析方法字符串,生成查询语句,其中支持的关键词有:

NamedQuery:针对一些复杂的SQL,支持原生SQL方式,进行查询,保证性能

Criteria Query: 支持JPA标准中的Criteria Query

相关推荐