发布于 2015-12-31 12:05:47 | 710 次阅读 | 评论: 0 | 来源: PHPERZ
Spring Data JPA 轻松实现基于 JPA 的库
Spring Data JPA 的目标是通过让一些必须的工作变得更简单,来显著提高数据访问层的实现。作为一个开发者,你写你的仓库界面,包括自定义查询方法,而 Spring 给你提供自动实现。
前段时间项目使用Spring Data JPA,本人初次涉猎对于新的技术总是热情满满,后面使用了一段时间总之有利有弊吧。现在把对于Spring Data JPA的使用心得写下来,欢迎同道人士指正交流。
Spring Data JPA是由Spring提供的一个用于简化JPA开发的框架,可以极大的简化JPA的写法,可以在几乎不用写实现的情况下,实现对数据的访问和操作。除了CRUD外,还包括如分页、排序等一些常用的功能。下面开始说如何使用 Spring Data JPA。
一、pom.xml引入jar包
其他相关的包我就不说了,上面的链接里也有,一般标准的springMVC项目都应该有那些包。
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.8.0.RELEASE</version>
</dependency>
二、dao继承相应的接口
Spring Data JPA提供的接口,也是Spring Data JPA的核心概念:
1:Repository:最顶层的接口,是一个空的接口,目的是为了统一所有Repository的类型,且能让组件扫描的时候自动识别。
2:CrudRepository :是Repository的子接口,提供CRUD的功能
3:PagingAndSortingRepository:是CrudRepository的子接口,添加分页和排序的功能
4:JpaRepository:是PagingAndSortingRepository的子接口,增加了一些实用的功能,比如:批量操作等。
5:JpaSpecificationExecutor:用来做负责查询的接口
6:Specification:是Spring Data JPA提供的一个查询规范,要做复杂的查询,只需围绕这个规范来设置查询条件即可
上面几种接口的说明,每个接口封装的方法不一样,这里我们继承其中两个JpaRepository、JpaSpecificationExecutor
//JpaRepository<Account, String>中的Account为规定该持久层能操作的持久对象,String为主键类型
public interface AccountRepository extends JpaRepository<Account, String>,JpaSpecificationExecutor<Account> {
public Account findByName(String name);
public List<Acount> findByArea(String area);
@Query("from Account where xxx = ?1")
public Account findByXXX(String xxx);
}
三、service注入相应repository
也许大家注意到了我没有说关于repository的实现,这个我后面会说明,这就是DataJpa的魅力。
@Service
@Transactional
public Class AccountServiceImpl implements AccountService{
@Autowired
private AccountRepository accountRepository;
public void repositoryTest(){
//---------列举repository集成相关类后部分自带方法,更多自行查看文档------------------
//通过ID查找account
Account account = accountRepository.findOne(id);
//保存或更新 account
//该方法会自动根据account对象里是否包含有id且数据库是否存在该id的对象去采取新增还是更新操作
accountRepository.save(account);
//删除指定account
//除了ID也可直接传入实体 更多方式自行查看文档
accountRepository.delete(id);
//批量删除 更多方式自行查看文档
accountRepository.deleteInBatch(account的集合)
//查询所有account
accountRepository.findAll();
//---------调用自定义的方法---------
Account account = accountRepository.findByName(name);
List<Acount> list = findByArea(rea);
Account account = findByXXX(xxx);
}
}
通过上面的代码可以看出通过repository继承JpaRepository、JpaSpecificationExecutor后我们可以很方便的进行CRUD操作。但findByName这种又是怎么实现查询的呢?
1.<Query creation from method names>
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Like | findByFirstnameLike | … where x.firstname like ?1 |
OrderBy | findByAgeOrderByLastnameDesc |
… where x.age = ?1 order by x.lastname desc |
以上我只列举了部分,具体查看官方文档:
http://docs.spring.io/springdata/jpa/docs/1.8.0.RELEASE/reference/html/#jpa.repositories
由此可见只要以findBy开头+对象的字段(首字母大写)+条件规则 的方法名 data jpa就会自动解析成响应的ql语句进行查询。
2.使用@Query注解
@Query是相比规范式方法名的做法更加灵活或且方便不知道规范式命名的人员更加方便的使用data jpa
public interface UserRepository extends JpaRepository<User, Long> {
//jpql语句格式
@Query("select u from User u where u.firstname like %?1")
List<User> findByFirstnameEndsWith(String firstname);
//nativeQuery 可以让你使用sql语句来查询
@Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?0", nativeQuery = true)
User findByEmailAddress(String emailAddress);
//@Param可以指定一个名称与query注解中的某个占位名称相对应
@Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")
User findByLastnameOrFirstname(@Param("lastname") String lastname, @Param("firstname") String firstname);
}
3.修改查询Modifying queries
@Modifying @Query("update User u set u.firstname = ?1 where u.lastname = ?2") int setFixedFirstnameFor(String firstname, String lastname);
以上就是对于Spring Data JPA的简单应用,它还有很多功能可以使用SpEL表达式、可以调用存储过程查询、以及后面我单独写一篇关于复杂多表以及分页要用到的Specifications查询等等,有兴趣的同志们可以多看看官方文档,本人英语老差了,都是一点点用工具翻译结合其他大神的帖子看的,那么累啊!