Spring Data Jpa

Repository关系图

在这里插入图片描述

Domain的注解

@MappedSuperclass
表示不要把这个类建成一个表 这个表仅仅是一个父类

简单的CRUD

该接口需要继承JpaRepository<Employee,Long>

查询所有

employeeRepository.findAll()

查找单个

getOne与findOne的区别

  • getOne具有懒加载的功能,如果在测试阶段,这个问题是解决不了的,我们一般解决只能在web跑起来的时候,解决方案就是延长EntityManager的生命周期
  • findOne及时加载,不会存在懒加载的问题,所以推荐使用
    employeeRepository.getOne(1L);

根据id删除数据

employeeRepository.delete(273L);

保存数据

employeeRepository.save(employee);

修改数据

修改数据和保存数据用的是同一个方法 他们根据传入的数据是否有id来进行判断 如果有id那就是修改 如果没有id就是新增

JpaRepository中的批量删除与CRUDRepository中的批量删除的区别

  • JPARepository
    employeeRepository.deleteInBatch(employeeslist);
    产生的sql语句: delete from employee where id=? or id=?
  • CRUDRepository
    employeeRepository.delete(employees);
    会产生4条sql语句,2条循环查,2条循环删除,性能超级低下,所以建议使用子类的方法

查询并排序

Sort sort = new Sort(Sort.Direction.DESC, "age","username");
List<Employee> all = employeeRepository.findAll(sort);

分页查询

Pageable pageable = new PageRequest(13,10);
Page<Employee> pages = employeeRepository.findAll(pageable);
for (Employee page : pages) {
    System.out.println(page);
}
System.out.println("=============Page对象API的讲解======================");
System.out.println(pages.getTotalElements());//总条数
System.out.println(pages.getTotalPages());//总页数
System.out.println(pages.getContent());//查询每页的数据
System.out.println(pages.getNumber());//当前页
System.out.println(pages.getNumberOfElements());//当前页查询出来的数据条数
System.out.println(pages.getSize());//每页条数

分页并且排序

Sort sort = new Sort(Sort.Direction.DESC, "age");
Pageable pageable = new PageRequest(0,5,sort);
Page<Employee> all = employeeRepository.findAll(pageable);

条件查询1:根据名字查询

List<Employee> employees = employeeRepository.findByUsername("admin");
springDataJpa支持条件查询: 所谓条件查询,就是说,你的方法名字必须有一定规则,它在你的方法名字中可以看出条件
需要在Repository中定义的抽象方法
List<Employee> findByUsername(String username);

条件查询2:根据名字模糊查询

List<Employee> employees = employeeRepository.findByUsernameLike("%1%");
需要在Repository中定义的抽象方法
List<Employee> findByUsernameLike(String username);

query注解查询

在Repository中定义的抽象方法

方式一

@Query("select o from Employee o where o.username like ?1 and o.age>=?2")
List<Employee> loadByUsername1(String username,Integer age);

方式二

@Query("select o from Employee o where o.username like :username and o.age>=:age")
List<Employee> loadByUsername2(@Param("username") String username, @Param("age") Integer age);

用法:
List<Employee> employees = employeeRepository.loadByUsername2("%1%",26);

同时也支持原生sql语句

@Query(nativeQuery = true,value = "select count(*) from employee")
Long  getCount();

JpaSpecificationExecutor(了解)

@param root 查询哪个表(定位到表和字段-> 用于拿到表中的字段)
@param criteriaQuery 查询哪些字段,排序是什么(主要是把多个查询的条件连系起来)
@param criteriaBuilder 字段之间是什么关系,如何生成一个查询条件,每一个查询条件都是什么方式
主要判断关系(和这个字段是相等,大于,小于like等)

List<Employee> employees = employeeRepository.findAll(new Specification<Employee>() {
/**
 *
 * @param root   查询哪个表(定位到表和字段-> 用于拿到表中的字段)
 * @param criteriaQuery  查询哪些字段,排序是什么(主要是把多个查询的条件连系起来)
 * @param criteriaBuilder 字段之间是什么关系,如何生成一个查询条件,每一个查询条件都是什么方式
 *                      主要判断关系(和这个字段是相等,大于,小于like等)
 * @return
 */
@Override
public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
    //我要查询username这个字段
    Path username = root.get("username");
    Path age = root.get("age");
    //字段的关系   username like ?
    Predicate like = criteriaBuilder.like(username, "%1%");
    // age>=?
    Predicate ge = criteriaBuilder.ge(age, 26);
    //
    Predicate and = criteriaBuilder.or(like, ge);
    return and;
}

jpa-spec插件

需要EmployeeRepository继承JpaSpecificationExecutor

没经过抽取

都是and语句

public void testSpec1(){
     Specification<Employee> specification = Specifications.<Employee>and()
             .like("username", "%1%")
             .ge("age",26)
             .eq("email","amdin1@itsource.cn")
             .build();
 
     List<Employee> employees = employeeRepository.findAll(specification);
     for (Employee employee : employees) {
         System.out.println(employee);
     }
 
 }

有and和or

public void testSpec2(){
    Specification<Employee> specification1 = Specifications.<Employee>and()
            .like("username", "%1%")
            .ge("age",26)
            .build();
    Specification<Employee> specification2 = Specifications.<Employee>or().
            eq("email", "121231").
           predicate(specification1).build();


    List<Employee> employees = employeeRepository.findAll(specification2);
    for (Employee employee : employees) {
        System.out.println(employee);
    }

}

分页排序条件查询

public void testSpec3(){
     Specification<Employee> specification1 = Specifications.<Employee>and()
             .like("username", "%1%")
             .ge("age",26)
             .build();
     Specification<Employee> specification2 = Specifications.<Employee>or().
             eq("email", "121231").
             predicate(specification1).
             build();
 
     Pageable pageable = new PageRequest(0, 5, new Sort(Sort.Direction.DESC, "age"));
     Page<Employee> employees = employeeRepository.findAll(specification2,pageable);
     for (Employee employee : employees) {
         System.out.println(employee);
     }
 
 }

经过抽取后

BaseQuery:

    //当前页
    private Integer page = 1;
    //每页条数
    private Integer pageSize = 10;
    //根据指定的字段进行排序
    private String orderByName;
    //默认是升序
    private String orderByType = "ASC";

    /**
     * 约束着子类必须拥有此方法
     * @return
     * 该方法就是每个domain中查询条件
     */
    public abstract Specification createSpec();

    /**
     * 抽取公共的排序
     * @return
     */
    public Sort createSort(){
        Sort sort = null;
        if(StringUtils.isNotBlank(this.orderByName)){
            sort = new Sort("ASC".equals(this.orderByType.toUpperCase()) ?
                    Sort.Direction.ASC : Sort.Direction.DESC, this.getOrderByName());
        }
        return sort;
    }

    /**
     * 当前页(它是从索引0开始的)
     * @return
     */
    public Integer getBegin(){
        return this.page - 1;
    }

	getter和setter语句....

EmployeeQuery 继承 BaseQuery:

private String username;
private Integer age;
private String email;

@Override
public Specification createSpec() {
    Specification<Employee> specification = Specifications.<Employee>and()
            .like(StringUtils.isNotBlank(username),"username", "%" +username + "%")
            .eq(StringUtils.isNotBlank(email),"email",email)
            .build();
    return specification;
}

getter和setter语句...

条件查询语句

EmployeeQuery query = new EmployeeQuery();
query.setUsername("1");
query.setEmail("amdin1@itsource.cn");

List<Employee> employees = employeeRepository.findAll(query.createSpec());

分页排序条件查询语句

EmployeeQuery query = new EmployeeQuery();
query.setUsername("1");
query.setEmail("amdin1@itsource.cn");
query.setOrderByName("email");
query.setOrderByType("desc");


Pageable pageable = new PageRequest(query.getBegin(), query.getPageSize(),query.createSort());
Page<Employee> employees = employeeRepository.findAll(query.createSpec(),pageable);

补充

-eq:等于 -ne:不等于 -le:小于等于 -ge:大于等于 -lt:小于

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值