例:
@Query(value = "select * from Customer where name = ?", nativeQuery = true) public Customer findByNameAndSQL(String name); // 查询全部 @Query(value = "select * from Customer", nativeQuery = true) public List<Customer> findAllBySQL();其中的@Query的第三个参数默认是false 表示不是sql查询,而是jpql查询
例
// jpql 查询全部 @Query(value = "from Customer where name =?1", nativeQuery = false) public Customer findAllByNameAndJpql();SpringDataJpa对jpql再次进行了封装,支持方法命名规则查询:
查询方式 命名规则根据某个字段查询 find实体类名By字段名
模糊查询 find实体类名By字段名Like , 注意传参时不要忘了添加%
多条件并列查询 find实体类名By字段名And字段名 ,使用and关键字隔开
多条件或查询 find实体类名By字段名Or字段名 ,使用Or关键字隔开
复杂查询 Optional<T> findOne(@Nullable Specification<T> spec); List<T> findAll(@Nullable Specification<T> spec); //Page 是 SpringDataJpa提供的 Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable); // 查询条件spec // 排序条件 sort List<T> findAll(@Nullable Specification<T> spec, Sort sort); // 按照条件统计 long count(@Nullable Specification<T> spec);
他们的公共入参都有Specification 这是个接口,我们需要自己实现, 重写它的抽象方法
Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder);其中:
root: 是我们查询的根对象(查询的任何属性都能从根对象中获取)
CriteriaQuery: 顶层的查询对象
CriteriaBuilder: 查询的构造器, 封装了很多查询条件
例:
分页查询
排序
/** * 参数1 ; 正序 / 倒叙 * 参数2 : 属性名 */ Sort orders = new Sort(Sort.Direction.DESC,"id"); List<Customer> list= customerRepository.findAll((root,query,criteriaBuilder)->{ Path<Object> name = root.get("name"); Predicate like = criteriaBuilder.like(name.as(String.class), "武%"); return like; },orders);模糊查询
List<Customer> list= customerRepository.findAll((root,query,criteriaBuilder)->{ Path<Object> name = root.get("name"); Predicate like = criteriaBuilder.like(name.as(String.class), "武%"); return like; });多条件查询
/** * root 获取属性 * criteriaBuilder: 构造查询条件 */ Optional<Customer> customer= customerRepository.findOne((root,query,criteriaBuilder)->{ Path<Object> name = root.get("name"); Path<Object> industry = root.get("industry"); Predicate namepre = criteriaBuilder.equal(name, "张三"); Predicate indpre = criteriaBuilder.equal(industry, "学生"); /* 组合条件 1. 满足条件1和条件2 2. 满足条件1或条件2 * */ Predicate andpre = criteriaBuilder.and(namepre, indpre); // Predicate or = criteriaBuilder.and(namepre, indpre); // 以 或的条件查询 return andpre; });注意点:
分页两种: 带条件的分页findAll(Specification spec,Pageable pageable),和不带条件的分页findAll(Pageable pageable)
此外: 对于criteriaBuilder的equals方法,可以直接使用path对象,但是对于 gt lt le like我们需要分步, 1,得到path对象,2.根据path对象指定比较的参数类型在进行下一步比较,因为可能比较的是字符串, 也可能是数字
多表操作的级联相关 一对多配置数据库表之间难免会出现彼此的约束, 如商品分类表和商品表之间,就是典型的一对多的关系,同一个分类下有多种不同的商品,下面就是jpa如何通过注解控制一对多的关系
双方都有一个彼此之间的引用, 如在one的一方,维护着多的一方的一个集合,一般使用HashSet,而在many的一方维护着一的一方的引用
在一的一方使用注解@OneToMany
在多的一方使用注解@ManyToOne
维护主键的一方需要使用@JoinColumn(name = "customer_id",referencedColumnName = "id") 注解, 作用是指明外键列名,以及引用的主键列名