SpringData使用Specification构造复杂查询和多表关联查询,物理分页和逻辑分页

1、关联查询

edifice与edificeAdmin 是一对多的关系,在实体类中配置根据情况配置@OneToMany, @ManyToOne..即可实现关联查询

public class Edifice{
    @Id
    @GeneratedValue
    private Long id;
    private String name;
}
public class EdificeAdmin{

    @ManyToOne
    @JoinColumn(name = "edificeId",insertable=false, updatable=false)
    @NotFound(action= NotFoundAction.IGNORE)
    private Edifice edifice;
    
     @Id
    @GeneratedValue
    private Long id;
    private Long edificeId;
    private Long userId;
}

出现如下异常,需要在private Edifice edifice上添加 insertable=false, updatable=false 即可解决 

MappingException: Repeated column in mapping for entity: com.domain.EdificeAdmin column: id (should be mapped with insert="false" update="false")

出现如下异常,因为 @JoinColumn 中 name 关联错,最开始使用 name="id",此时关联为 edificeAdmin.id = edifice.id ,所以出现没被关联的记录,正确应该为 edificeAdmin.edificeId = edifice.id ,@JoinColumn 中 name 应该按照实体类字段,如使用edifice_id会出现如下错误,将 edifice_id 修改为 edificeId即可解决 

Table [edifice_admin] contains physical column name [edifice_id] referred to by multiple physical column names: [edifice_id], [edificeId]  

出现如下异常,因为存在子表(被关联表)中没有主表(关联表)中所对应的关联记录,添加 @NotFound(action= NotFoundAction.IGNORE) 即可解决 

JpaObjectRetrievalFailureException: Unable to find com.domain.Edifice with id 24; nested exception is javax.persistence.EntityNotFoundException: Unable to find com.domain.Edifice with id 24 

 Repository中两个查询接口,在下面查询例子中用到

List findAll(Specification specification); //条件
Page findAll(Pageable pageable); //分页

 2、复杂查询

    public List findAllSpec(){
        return edificeRepository.findAll(whereConditions());
    }

    private Specification whereConditions(){
        return new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {

                List predicates = new ArrayList<>();
                predicates.add(cb.like(root. get("name"), "%史塔克%"));
                predicates.add(cb.equal(root. get("tenantId"), 6l));
                predicates.add(root. get("id").in(16l,17l,18l,19l,20l,21l));
                query.orderBy(cb.desc(root. get("id")));

                return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
            }
        };
    }

SELECT  ...  FROM
    edifice edifice0_ 
WHERE
    ( edifice0_.NAME LIKE ? ) 
    AND edifice0_.tenant_id = 6 
    AND ( edifice0_.id IN ( 16, 17, 18, 19, 20, 21 ) ) 
ORDER BY
    edifice0_.id DESC;

3、表关联复杂查询

    public List findalllike(){
        return edificeAdminRepository.findAll(whereConditions());
    }

    private Specification whereConditions(){
        return new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {

                List predicates = new ArrayList<>();
                Join edificeJoin = root.join("edifice",JoinType.INNER);
                Predicate predicate = cb.like(edificeJoin.get("name"), "%史塔克%");
                predicates.add(predicate);
                return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
            }
        };
    }

 SELECT  ...  FROM
    edifice_admin edificeadm0_
    INNER JOIN edifice edifice1_ ON edificeadm0_.edifice_id = edifice1_.id 
WHERE
    edifice1_.NAME LIKE ?;

 4、物理分页

    public Page findAllPage(){
        return edificeRepository.findAll(new PageRequest(1,6));
    }

SELECT  ... FROM edifice edifice0_  LIMIT ?,  ?;

5、逻辑分页 

    public Page findAllPage(){
        List edifices = edificeRepository.findAll();
        return edificePage(edifices,1,6);
    }

    public Page edificePage(List list, Integer page, Integer pageSize){
        if (page==null) page = 0;
        if (pageSize==null) pageSize = 30;

        int fistIndex = page * pageSize;
        int lastIndex = (page + 1) * pageSize;

        if (lastIndex > list.size())
            lastIndex = list.size();

        List subList = new ArrayList<>();
        if (fistIndex < lastIndex)
            subList = rescuers.subList(fistIndex, lastIndex);
        return new PageImpl<>(subList,new PageRequest(page,pageSize),list.size());
    }

以下错误,是因为执行subList时,list只有2条数据,但是开始截取是从第30条开始,所以加个fistIndex < lastIndex判断是否截取

java.lang.IllegalArgumentException: fromIndex(30) > toIndex(2)

你可能感兴趣的:(Java,SSH)