一、JPA如何使用Spcification
dao层继承
public interface JpaSpecificationExecutor<T>
由此接口源码,看出有可以分页按条件查询和不分页按条件查询的功能
public interface JpaSpecificationExecutor<T> { T findOne(Specification<T> var1); List<T> findAll(Specification<T> var1); Page<T> findAll(Specification<T> var1, Pageable var2); List<T> findAll(Specification<T> var1, Sort var2); long count(Specification<T> var1); }
二、实体类
有两格表,tb_student和tb_teacher表。多对一的关系。
tb_student表:student_id、name、teacher_id
tb_teacher表:teacher_id、name
Student实体类:
@Entity @Table(name="tb_student") public class Student { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name="user_id") private Integer studentId; //学生Id为主键、自增 @Column private String name; @ManyToOne @JoinColumn(name = "teacher_id") private Teacher teacher; //set、get方法 }
Teacher实体类:
@Entity @Table(name="tb_teacher") public class Teacher { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name="user_id") private Integer teacherId; //老师Id为主键、自增 @Column private String name; // set、get方法 }
三、重写toPredicate方法
查询的key是实体类的属性;
多表查询,通过join方法连接;
集合通过in和not方法筛选结果;
Specification<User> specification = new Specification<User>() { @Override public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> list = new ArrayList<>(); // 1.等于 选择name是“张三”的用户 Predicate equal(Expression<?> var1, Object var2); list.add(cb.equal(root.get("name").as(String.class), "张三")); // 2.多表查询 选择teacher是“老师甲” list.add(cb.equal(root.join("teacher").get("name").as(String.class), "老师甲")); // 3.不包括集合 studentId不是7、8、9 List notInList = Arrays.asList(7,8,9); list.add(cb.not(root.get("studentId").in(notInList))); // 4.包括集合 studentId是4、5、6 List inList = Arrays.asList(4,5,6); list.add(root.get("studentId").in(inList)); Predicate[] p = new Predicate[list.size()]; // cb.and “and”表示这几个条件并且的关系 Predicate and(Predicate... var1); return cb.and(list.toArray(p)); } };