Jpa 笔记 (2)

例:

@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: 查询的构造器, 封装了很多查询条件

例:
分页查询

// 当前查询第几页, 每一页查询的条数 Pageable pageable = PageRequest.of(0,2); Page<Customer> page = customerRepository.findAll((root, query, criteriaBuilder)->{ return null; }, pageable); System.out.println("page.getTotalElements(): "+ page.getTotalElements()); // 总条数 System.out.println("page.getTotalPages(): "+ page.getTotalPages()); // 总页数 page.getContent().forEach(System.out::println); // 当前页结果

排序

/** * 参数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") 注解, 作用是指明外键列名,以及引用的主键列名

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjsfz.html