JPA
JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
场景介绍
在日常开发的过程中会使用到JPA动态分页查询,但是JPA又没有Mybatis那么灵活,为了方便学习交流,记录下解决方法。
详细教程
1.首先写一个公有的类,里面有你要展示的字段(到时候传参也是在这里面传),还有排序方式,排序字段以及页大小和当前的一些字段。
public class TaskInfoQuery {
private String userid;
private String type;
private Sort.Direction order = Sort.Direction.DESC; //排序方式
private String sort = "createTime"; //排序字段
private int page = 1;
private int size = 50;
}
2.然后在Controller类里面写一个访问地址,方法里面的参数就是你之前定义的类,然后将Pageable对象所需要的参数传进去,再将参数传到Page对象中,这里就不展示Taskinfo的实体类了。
@Controller
public class Taskinfoservice {
@RequestMapping("test")
@ResponseBody
public Page<TaskInfo> taskquery(TaskInfoQuery tquery) {
System.out.println("收到查询参数:" + tquery);
//如果没有写公有类可以这样写new Sort(Sort.Direction.DESC, sortProperty)=new Sort(排序方式, 排序字段)
//Pageable pageable = new PageRequest(page, size, new Sort(direction, sortProperty));
Pageable pageable = new PageRequest(tquery.getPage(), tquery.getSize(),tquery.getOrder(), tquery.getSort());
Page<TaskInfo> taskInfos = taskInfoBusiness.findTaskInfoByUserIdAndStatusAndBrandId(tquery, pageable);
return taskInfos;
}
}
然后就到了serviceImpl中,直接在实现类中重写接口方法,为了方便就不展示所有的接口类了,通过findAll()方法去创建一个new Specification<TaskInfo>()的方法然后会要求你重新它自带的方法,然后判断你的查询条件参数,添加到定义的集合中去,通过query.where拼接参数
@Service
public class TaskInfoImpl implements TaskInfoBusiness{
@Override
public Page<TaskInfo> findTaskInfoByUserIdAndStatusAndBrandId(TaskInfoQuery taskInfoQuery,
Pageable pageable) {
Page<TaskInfo> taskinfo=taskInfoRepository.findAll(new Specification<TaskInfo>() {
@Override
public Predicate toPredicate(Root<TaskInfo> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//查询条件集合
List<Predicate> predicates = new ArrayList<Predicate>();
//root.get("xx")是pojo的字段
if(StringUtils.isNotBlank(taskInfoQuery.getBrandId())) {
predicates.add(cb.equal(root.get("brandId").as(String.class), taskInfoQuery.getBrandId()));
}
if(StringUtils.isNotBlank(taskInfoQuery.getUserid())) {
predicates.add(cb.equal(root.get("userId").as(String.class), taskInfoQuery.getUserid()));
}
/* if(StringUtils.isNotBlank(taskInfoQuery.getFullname())) {
predicates.add(cb.like(root.get("fullname").as(String.class), "%"+taskInfoQuery.getFullname()+"%"));这种是用来做模糊查询的
}
下面两个判断是判断时间在什么范围之内的
if(StringUtils.isNotBlank(taskInfoQuery.getCreateTime())) {
predicates.add(cb.greaterThanOrEqualTo(root.get("createTime").as(String.class), taskInfoQuery.getCreateTime()));开始时间
}
if(StringUtils.isNotBlank(taskInfoQuery.getEndTime())) {
predicates.add(cb.lessThanOrEqualTo(root.get("createTime").as(String.class), taskInfoQuery.getEndTime()));结束时间
}*/
query.where(predicates.toArray(new Predicate[predicates.size()]));
return null;
}},pageable);
return taskinfo;
}}
Dao层 注:一定实现 JpaSpecificationExecutor<Taskinfo>
@Repository
public interface Taskinfo extends JpaRepository<Taskinfo,Long>,JpaSpecificationExecutor<Taskinfo>{
}
然后前台传参就可以了,小编使用的是AngularJs传参和展示数据,不过万变不离其宗嘛!
<tr style="font-size:15px;">
<td class="text-center">用户ID</td>
<td class="text-center">订单状态</td>
</tr>
<tr id="show" ng-repeat="item in items">
<td class="text-center" >{
{item.userId}}</td>
<td class="text-center">{
{item.status}}</td>
</tr>
<tr>
<td colspan="20" id="show01" class="text-center">
<button class="btn btn-default" ng-click="home()">首页</button>
<button class="btn btn-default" ng-click="sh()">上一页</button>
<button class="btn btn-default" ng-click="next(page)">下一页</button>
<button class="btn btn-default" ng-click="last(page)">尾页
</button>
</td>
</tr>
/*初始化查询异常订单*/
$http({
method:'POST',
params:{page:0,size:50},
url:test,
}).then(function successCallback(data){
console.log(data.data);
$scope.items = data.data.content
},function errorCallback(data){
console.log("网络异常,请稍后重试~~~~~~")
});
//根据条件查询
$scope.doQuery = function(){
var status1 = $scope.statusData;
var userIds = $.trim($scope.userId);
$http({
method:'POST',
params:{status:status1,userid:userIds,size:50},
url:test,
}).then(function successCallback(data){
console.log(data.data.content);
$scope.items = data.data.content
},function errorCallback(data){
console.log(data);
alert("网络异常,请稍后重试~~~~~~")
});
};
/*回到首页*/
$scope.home = function(){
$http({
method:'GET',
params:{size:50,page:1},
url: test
}).then(function successCallback(data){
console.log(data.data)
$scope.items = data.data.content
}, function errorCallback(data) {
console.log("网络异常,请稍后重试~~~~~~")
console.log(data)
});
}
/*到达最后一页*/
$scope.last = function(page){
console.log(page);
$http({
method:'GET',
params:{size:50,page:page-1,brandId:brandid},
url: test
}).then(function successCallback(data){
console.log(data.data)
$scope.items = data.data.content
}, function errorCallback(data) {
console.log("网络异常,请稍后重试~~~~~~")
console.log(data)
});
$scope.ye = page
}
/*下一页*/
$scope.next = function(page){
var ye = $scope.ye+=1;
console.log(ye-1)
$http({
method:'GET',
params:{size:50,page:ye-1,brandid:brandid},
url: test
}).then(function successCallback(data){
console.log(data.data)
$scope.items = data.data.content
}, function errorCallback(data) {
console.log("网络异常,请稍后重试~~~~~~")
console.log(data)
});
}
/*上一页*/
$scope.sh = function(){
var ye = $scope.ye-=1;
console.log(ye);
if(ye <= 0){
$scope.ye = 1;
console.log(ye)
}
$http({
method:'GET',
params:{size:50,page:ye,brandid:brandid},
url: path1205
}).then(function successCallback(data){
console.log(data.data)
$scope.items = data.data.content
}, function errorCallback(data) {
console.log("网络异常,请稍后重试~~~~~~")
console.log(data)
});
}