1
Spring Data JPA
Calvin Xiao edited this page 2013-11-14 19:11:13 -08:00
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Spring Data JPA在JPA上又做了一层封装,只要编写接口就够了,不用写一行实现代码,CRUD方法啦,分页啦,自动将findByLoginName()的方法定义翻译成适当的QL啦都由它包了,以前每个项目自己写的BaseDao可以取消了。

	public interface UserDao extends PagingAndSortingRepository<User, Long> {
		User findByLoginName(String loginName);
	}

使用上很简单,快速浏览一下下面的资料就够了。

智能地翻译连LessThan, GreaterThan, Like, In, OrderBy, Not,And,Or都支持的方法名变成相应的JQL是它的一大卖点,比如下面的接口函数

   User findByLoginNameOrEmail(String loginName, String email);
    select user from User user where user.loginName=? or email =?

更厉害的是嵌套的属性也能翻译

   Task findByUserId(Long id)
   select task from Task task where task.user.id=?

它当然也可以直接用@Query在方法上标注复杂的查询语句。

如果要执行批量更新/删除语句,同样基于@Query编写。

 @Modifying 
 @Query("update AccountInfo a set a.salary = ?1 where a.salary < ?2") 
 public int increaseSalary(int after, int before);

预先封装好的分页与排序功能也是一大卖点,只要在接口定义时多丢一个Pageable或Sort参数就可以了,在Quickstart中有分页与排序的详细演示

Page<Task> findByUserId(Long id, Pageable pageRequest);

只有一个坑爹的地方,如果要为UserDao扩展方法(而不是接口),要新增一个UserDaoCustom接口,这时候,实现类的名字必须是UserDaoImpl,而不是UserDaoCustomImpl。

##动态组合查询条件 动态组合查询条件,指的是页面上有若干查询条件输入框,用户可能输入了其中的某一个或几个,这时候,固定的Query语句就不起作用了,必须动态组合。

JPA2.0的Criteria API的设计很傻,比Hibernate原来的设计难用多了,Gavin King周围是怎样一帮学院派啊,特别是什么Type Safe的定义,太傻了。

SpringData JPA额外封装了一个Specification,将JPA中的Predicate包起来了,可以使用如下。但对Predicate的创建就没有更多的支持了。

public interface TaskDao extends PagingAndSortingRepository<Task, Long>, JpaSpecificationExecutor<Task>{
...
}

taskDao.findAll(specification, pageRequest);

在Quickstart中沿用了SpringSide3.0以来的风格,通过在输入框中的约定名称,生成Predicate:

  1. 所有查询输入框的name有一个统一的前缀,如search_,而且将需要逻辑运算的关键字如EQ(equals), LE(less)也编码在name里,比如对title属性的模糊查询是”search_LIKE_title“,目前支持的关键字见SearchFilter.java
  2. 使用Servlets里那个copy自Spring WebUtils的getParametersStartingWith(),将所有查询框中非空的Parameter都拿出来。
  3. 将Parameter变为自定义的SearchFilter列表, 含Name,Value与运算符三元素。
  4. 使用SpringSide-Core中的DynamicSpecifications,自动根据SearchFilter生成Predicate。

DynamicSpecifications这段是精华,按约定的自动反射使得整个动态组合查询条件的代码量很少。如果你不想按照SpringSide的做法,也可以参考 DynamicSpecifications,自己在代码中构建Predicate,关键是不要随便抄网上的代码,特别是那些所谓类型安全的,还要每个Entity另外加一个POJO来定义所谓Meta-Data的.

##资料