实现 Repository 接口,控制对外公开方法。(如 只包含某一个查询,不提供增加修改方法。)
实现 CrudRepository 接口,包含基本的CRUD。
实现 PagingAndSortingRepository 接口,可使用spring实现分页、排序。
JPA 不能通过命名查询单个字段,在find后加上字段名没有作用。
使用 @Query 执行修改操作时 必须添加 @Modifying 和 @Transaction。如果 JDK 版本小于8,在入参处还要加上 @Param 注解以指定参数名
@Modifying
@Transactional
@Query("update Commodity c set c.lastUpdateTime = :lastUpdateTime where c.id = :id") // jpql
int updateLastUpdateTimeById(@Param("id") String id, @Param("lastUpdateTime") Date lastUpdateTime);
1.JPA 自动配置
- 配置了 DataSource(spring.datasource)
- ClassPath 中包含 org.springframework.data.jpa.repository.JpaRepository(引入Data JPA模块。排他)
Spring Boot 就会自动配置JPA,无需显示使用 @EnableJpaRepositories 开启JPA。
具体可以看 org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration 配置类。
使用 主键生成器
先看一个实体的主键定义(以下JPA 皆为 java JPA)
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid",strategy = "uuid2")
private String id;
@GeneratedValue 是 JPA 注解,其 generator 属性指定自定义主键生成器。strategy 属性指定JPA提供的生成策略。
@GenericGenerator 是 Hibernate 提供的主键生成器,其 name 属性指定该主键生成器的名称。strategy 指定策略名,也可以是全限类名。
其 策略 和 对应的全限类名 可以在 org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory 类的构造方法中找到
参考地址
分页查询
SJPA 和 JJPA 用于区分 Spring Data JPA 和 java JPA 规范。
@PageableDefault 注解
@RequestMapping(value = "", method=RequestMethod.GET)
public Page getEntryByPageable(@PageableDefault(value = 15, sort = { "id" }, direction = Sort.Direction.DESC) Pageable pageable) {
return blogRepository.findAll(pageable);
}
我们可以看到,我们只需要在方法的参数中直接定义一个pageable类型的参数,当Spring发现这个参数时,Spring会自动的根据request的参数来组装该pageable对象,Spring支持的request参数如下:
page,第几页,从0开始,默认为第0页
size,每一页的大小,默认为20
sort,排序相关的信息,以property,property(,ASC|DESC)的方式组织,
例如: sort=firstname&sort=lastname,desc表示在按firstname正序排列基础上按lastname倒序排列 这样,我们就可以通过url的参数来进行多样化、个性化的查询,而不需要为每一种情况来写不同的方法了。
通过url来定制pageable很方便,但唯一的缺点是不太美观,因此我们需要为pageable设置一个默认配置,这样很多情况下我们都能够通过一个简洁的url来获取信息了。
Spring提供了@PageableDefault帮助我们个性化的设置pageable的默认配置。例如@PageableDefault(value = 15, sort = { "id" }, direction = Sort.Direction.DESC)表示默认情况下我们按照id倒序排列,每一页的大小为15。
PagingAndSortingRepository 接口
SJPA 提供了 PagingAndSortingRepository 接口以实现分页和排序功能。其中定义了两个接口,
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);
}
一个提供分页,一个提供排序。
不过大多数时候,分页和排序都会同时使用,所以 Pageable 参数更为常用,功能也更强。Pageable 是一个分页信息的抽象接口。在idea中可以通过在接口上按F4查看其类型上下文关系。
其中常用实现为 PageRequest,共有3个构造方法,
第一个构造方法很简单,参数分别为 页码(起始页为0) 和 每页数据条数。
第二个构造 增加了两个参数,Direction 为 Sort 静态内部类,是一个枚举类型,用于指定排序方式,String... 为排序属性(非数据库字段)。该构造方法是第三构造的简单形式,其内部创建 Sort 实例,调用第三构造。
public PageRequest(int page, int size, Direction direction, String... properties) {
this(page, size, new Sort(direction, properties));
}
第三个构造已经很清楚了。看下 Sort类,其中有一个泛型为Order的List,用于储存当前所有的排序规则,如果要进行复杂的排序还是要通过构造Order来实现。
查询方法
除了接口,也可以通过方法命名来排序,下面根据CreateTime的降序 和 UpdateTime的降序排序数据。
List findAllOrderByCreateTimeDescLastUpdateTimeDesc();
返回数据
通过 org.springframework.data.domain.Page 来接收分页查询后的数据。
注:页码起始页为0。
参与排序的参数为实体属性名,不是数据库字段。