Page与Pageable
Page是spring data jpa提供的一个接口。包含了部分数据集合以及相关的下一部分数据集合以及数据总数等信息。可以获得当前的页面的记录以及总页数和总数据数,以及数据是否能够再分页。
PageImpl是Page接口的实现类。重写了 hashcode(),equals(),toString()
方法。
Pageable也是spring data jpa提供的接口,包含了分页的信息,页数getPageNumber()和每页的数据数getPageSzie()。以便JPA通过
Pageable得到一个带分页信息的sql语句。PageRequest是Pageable的实现类。提供了排序功能。
使用Page实现分页
数据库访问层的接口继承JpaRepository接口和JpaSpecificationExecutor接口
public interface UserRepository extends JpaRepository<User, String>,JpaSpecificationExecutor<User> {
public User findByName(String name);
@Query(value="select count(*) from user",nativeQuery = true)
public int countUser();
public User findByUserId(String userId);
@Modifying
@Query(value="update user set password=?1 where user_id=?2",nativeQuery = true)
public void updatePassword(String newpassword,String userId);
@Modifying
@Query(value="update user set permission=?1 where user_id=?2",nativeQuery = true)
public void updatePermission(String permission,String userId);
}
这样可以实现Page实现分页查询
定义sql语句中的Pageable参数
定义Pageable参数使用了Pageable接口的实现类PageRequest。之前的new PageRequest()方式已被弃用。现在使用PageRequest.of来定义Pageable接口的具体内容,如数据为总集合的第几页以及页数。
Pageable pageable;
pageable= PageRequest.of(page,pageSize, Sort.by(Sort.Direction.DESC,"time"));
这段代码定义了查询数据集的第几页数据以及每页的数据数。并按time属性的倒序排序查询的结果。
@Query定义的sql语句声明pagable参数
@Query(value="select * from camera where user_id=?1 order by ?#{#pageable}",nativeQuery = true)
public Page<Camera> findAllByUserId(String userId, Pageable pageable);
使用?#{#pageable}声明pageable参数。
List转换为Page
有时数据库操作需要执行动态sql语句,我们可以通过entityManager实现动态sql。但是如果采用entityManager执行访问数据库操作的话,我们需要借助NativeQuery执行sql语句,这样返回的结果一般是List类型的。那么,如何让结果转换为Page类型呢?其实,只需要借助Pageable接口和Page接口的实现PageImpl。
具体的代码如下:
String sql="select * from "+tableName+" order by time desc";//" limit "+Integer.toString(page*pageSize)+","+Integer.toString(pageSize);
Query nativeQuery=entityManager.createNativeQuery(sql);
List<WeighData> resultList=nativeQuery.getResultList();
int begin= (int) pageable.getOffset();
int en=(begin+pageable.getPageSize())>resultList.size()?resultList.size():(begin+pageable.getPageSize());
return new PageImpl<WeighData>(resultList.subList(begin,en),pageable,resultList.size());
其中通过getOffset获得这一页的开头在原结果集中的位置,并且通过判断开头的位置加上每页数据数后的结果是否大于最后一个数据在原数据集的位置获取每页的最后数据的位置。(末页的数据数可能不够一个pagesize),最终获取到一个Page。完成(类似于sql中的limit)分页查询。