Repository
是一个空接口,即:是一个标记接口,表示任何继承它的接口都是仓库接口类Repository
,则该接口会被Ioc容器表示为一个Repository Bean,放入到IOC容器中,进而可以在该接口中定义满足一定规范的方法@RepositoryDefinition(domainClass = Person.class, idClass = Long.class)
来替代继承Repository
接口CrudRepository
:继承Repository
,实现一组CURD相关的方法PagingAndSortingRespository
:继承CrudRepository
,实现了一组分页排序相关的方法JpaRepository
:继承PagingAndSortingRespository
,实现了一组JPA规范相关的方法XxxRepository
:需要继承JpaRepository
,这样该接口就具备了通用的数据访问控制层的能力JpaSpecificationExecutor
:不属于Repository
体系,实现一组 JPA Criteria
查询相关的方法方法必须以find|read|get
开头
涉及查询条件时,条件的实行用条件关键字连接,
支持属性的级联查询
若当前类有符合条件的属性,会优先使用属性,而不是使用级联属性
若要使用级联属性,则属性之间用 _ 连接。而为了避免歧义,推荐使用 _ 分隔的写法。如:
// Address类
@Entity
@Table(name = "t_address")
public class Address implements Serializable {
private static final long serialVersionUID = -682608034116202529L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String province;
private String city;
@ManyToOne
@JoinColumn(name = "person_id")
private Person person;
}
// Person类
@Entity
@Table(name = "t_person")
public class Person implements Serializable {
private static final long serialVersionUID = -5964437048712784999L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Integer age;
private String gender;
private String email;
@Column(name = "address_id")
// 捣乱的字段
private Long addressId;
@OneToMany(mappedBy = "person")
private Set<Address> address = new HashSet<>();
}
// PersonDao中的getByAddress_Id必须使用 _ 分隔,而不能直接写 getByAddressId
public interface PersonDao extends Repository<Person, Long> {
List<Person> getByNameLike(String name);
Person getByAddress_Id(Long id);
}
缺点:
@Query
可以执行自定义的JPQL语句以更灵活的查询
// 查询id最大的那个person
@Query("from Person p1 where p1.id = (select max(p2.id) from Person p2)")
Person getPersonByMaxId();
注解传递参数
使用占位符:参数顺序必须和JPQL中的顺序一致
@Query("from Person p where p.name = ?1 and p.gender = ?2")
Person query_getPersonByNameAndGender(String name, String gender);
使用命名参数:这种写法可以随便设置参数顺序
@Query("from Person p where p.name = :name and p.age = :age")
Person query_getPersonByNameAndAge(@Param("age") Integer age, @Param("name") String name);
org.springframework.data.repository.query.Param;
spring data允许在占位符上添加%(适用于模糊查询like:%占位符%
)
@Query支持原生sql查询
@Query(value = "select count(1) from t_person", nativeQuery = true)
Long getTotal();
@Modifying:可以使用该注解来实现通过JPQL修改和删除(JPQL不支持添加)
@Modifying
@Query(value = "update Person p set p.name = ?1, p.age = ?2 where p.id = ?3")
void updatePerson(String name, Integer age, Long id);
Repository
方法都有一个事务,但是却是只读事务该接口提供了排序和分页的方法:方法的参数Pagable里面包含的有Sort
测试
测试分页:pageNum(页码)从0开始计数
@Test
public void test08() {
Pageable pageable = PageRequest.of(0, 10);
Page<Person> personPage = personDao.findAll(pageable);
System.out.println("总记录条数:" + personPage.getTotalElements());
System.out.println("总页数:" + personPage.getTotalPages());
System.out.println("当前页:" + personPage.getNumber());
System.out.println("当前页内容(数据):" + personPage.getContent());
System.out.println("当前页记录数:" + personPage.getNumberOfElements());
}
测试排序
@Test
public void test09() {
Sort sort = Sort.by(Sort.Direction.DESC, "id");
Iterable<Person> persons = personDao.findAll(sort);
persons.forEach(System.out::println);
}
测试分页排序
@Test
public void test10() {
// Pageable pageable = PageRequest.of(0, 10, Sort.Direction.DESC, "age", "id");
// Sort sort = Sort.by(Sort.Direction.DESC, "age", "id");
Sort.Order order1 = new Sort.Order(Sort.Direction.DESC, "age");
Sort.Order order2 = new Sort.Order(Sort.Direction.ASC, "name");
Sort sort = Sort.by(order1, order2);
Pageable pageable = PageRequest.of(0, 10, sort);
Page<Person> personPage = personDao.findAll(pageable);
personPage.forEach(System.out::println);
}
JpaRepository
中定义了一些新的方法,最主要是批量操作的方法<S extends T> List<S> saveAll(Iterable<S> var1):批量保存
void flush():刷新。同步Jpa缓存和数据库
<S extends T> S saveAndFlush(S var1):相当于JPA的merge方法
void deleteInBatch(Iterable<T> var1):批量删除
void deleteAllInBatch():批量删除所有
通过查询条件查询
方法
Optional<T> findOne(@Nullable Specification<T> spec)
:根据条件查询
findAll
:查询所有
List<T> findAll(@Nullable Specification<T> spec)
:根据条件查询所有
Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable)
:根据条件分页[排序]
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);
TypeQuery
对象本节代码:点击此处
原文:https://www.cnblogs.com/ann-zhgy/p/12022520.html