首页 > 编程语言 > 详细

05 Spring Data JPA基础查询方法

时间:2020-09-17 23:27:15      阅读:61      评论:0      收藏:0      [点我收藏+]

Spring Data JPA基础查询方法

Spring Data Common的Repository

Repository位于Spring Data Common的org/springframework/data/repository中,它是Spring Data里做数据库操作的最底层的抽象接口、最顶层的父类。

Repository源码:

package org.springframework.data.repository;

import org.springframework.stereotype.Indexed;

@Indexed
public interface Repository<T, ID> {
}

源码中其实没有方法,只是一个标识作用。该接口主要作为标记接口捕获要使用的类型,并帮助你发现扩展此接口,Spring底层做动态代理的时候发现只要是它的子类或者实现类都代表存储库操作

Repository的类层次关系

1、通过IDEA工具,打开Repository.class,通过查看组织结构可以看到

技术分享图片

2、通过打开类UserRepository.class,查看层次关系图。

技术分享图片

3、通过打开QueryDslJpaRepository.class,查看层次关系图。

技术分享图片

4、通过打开UserRepository.java,打开类结构图。

技术分享图片

以上三种视图是开发过程中经常用到的视图。

CrudRepository方法详解

提供了最基础的CRUD方法。包括根据ID查询,查询所有,根据ID删除等等。

CrudRepository源码:

package org.springframework.data.repository;

import java.util.Optional;

@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
    <S extends T> S save(S var1);

    <S extends T> Iterable<S> saveAll(Iterable<S> var1);

    Optional<T> findById(ID var1);

    boolean existsById(ID var1);

    Iterable<T> findAll();

    Iterable<T> findAllById(Iterable<ID> var1);

    long count();

    void deleteById(ID var1);

    void delete(T var1);

    void deleteAll(Iterable<? extends T> var1);

    void deleteAll();
}

1、<S extends T> S save(S var1):保存实体方法。(方法来源SimpleJpaRepository.class)

@Transactional
public <S extends T> S save(S entity) {
  if (this.entityInformation.isNew(entity)) {
  this.em.persist(entity);
  return entity;
  } else {
  return this.em.merge(entity);
  }
}

可以从上面代码中看到:首先检查传递进行的实体是否存在,然后判断是否为新增还是更新,检查的机制是通过主键判断,另一种方式是通过Version来判断。如果我们去JPA控制台打印输出sql,最少会由两条,一条是查询,一条是insert或update方法。

2、批量保存。实现方法同保存实体方法大同小异,实现方式就是for循环调用上面的save方法

3、根据主键查询实体

4、根据主键判断实体是否存在

5、查询实体的所有列表

6、根据主键列表查询实体列表

7、查询总数

8、void deleteAll()根据主键删除。(方法来源SimpleJpaRepository.class)

@Transactional
    public void deleteById(ID id) {
        Assert.notNull(id, "The given id must not be null!");
        this.delete(this.findById(id).orElseThrow(() -> {
            return new EmptyResultDataAccessException(String.format("No %s entity with id %s exists!", this.entityInformation.getJavaType(), id), 1);
        }));
    }

实现原理:先去查询一下,再做保存,不存在抛出异常。

CrudRepository使用示例

只需要自己的Repository继承CrudRepository即可。

例如,在我们有一个UserRepository继承CrudRepository

import org.springframework.data.repository.CrudRepository;

/**
 * TODO
 *
 * @author: Yizq
 * @data: 2020/8/23 4:40 下午
 */

public interface UserRepository extends CrudRepository<User,Long> {

}

PageingAndSortingRepository方法详解

它在CurdRepository的基础上增加了分页和排序等对查询结果进行限制的基本方法。

PageingAndSortingRepository源码:

package org.springframework.data.repository;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
  	// 根据排序取所有对象的集合
    Iterable<T> findAll(Sort var1);

  	// 根据分页和排序进行查询,并且Page对象封装。Pageable对象中包含分页和sort对象。
    Page<T> findAll(Pageable var1);
}

PageingAndSortingRepository使用示例

只需要继承PageingAndSortingRepository的接口即可,其他不需要做任何修改

import org.springframework.data.repository.PagingAndSortingRepository;

/**
 * TODO
 *
 * @author: Yizq
 * @data: 2020/8/23 4:40 下午
 */

public interface UserRepository extends PagingAndSortingRepository<User,Long> {

}

UserController修改操作如下:

/**
 * TODO
 *
 * @author: Yizq
 * @data: 2020/8/23 4:44 下午
 */
@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserRepository userRepository;

  
    @GetMapping("/page")
    @ResponseBody
    public Page<User> getAllUserByPage() {
        return userRepository.findAll(PageRequest.of(1,
                20,
                Sort.by(Sort.Direction.ASC, "name")
        ));
    }
}

ps:在版本Springboot2.2.1+中不再支持new PageRequest和new Sort来创建分页和排序对象,需要更改为以上操作

JpaRepository详解

JpaRepository到这里进入分水岭,以上的接口都是Spring Data为了兼容NoSQL而进行抽象封装,从JpaRepository开始对关系型数据进行抽象封装。

JpaRepository源码:

ackage org.springframework.data.jpa.repository;

import java.util.List;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;

@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
    List<T> findAll();

    List<T> findAll(Sort var1);

    List<T> findAllById(Iterable<ID> var1);

    <S extends T> List<S> saveAll(Iterable<S> var1);

    void flush();

    <S extends T> S saveAndFlush(S var1);

    void deleteInBatch(Iterable<T> var1);

    void deleteAllInBatch();

    T getOne(ID var1);

    <S extends T> List<S> findAll(Example<S> var1);

    <S extends T> List<S> findAll(Example<S> var1, Sort var2);
}

通过源码和CrudJRepository相比较,它支持Query By Example,批量删除,提高删除效率,手动刷新数据库的更该方法,并将默认实现的查询结果变成了List。

JpaRepository使用示例

只需要将自己的Repository继承JpaRepository即可,比如

import org.springframework.data.jpa.repository.JpaRepository;

/**
 * TODO
 *
 * @author: Yizq
 * @data: 2020/8/23 4:40 下午
 */

public interface UserRepository extends JpaRepository<User,Long> {

}

Repository的实现类SimpleJpaRepository

SimpleJpaRepository是JPA整个关联数据库的所有Repository的接口实现类。如果想扩展,可以继承此类,还有默认的处理机制。

技术分享图片

05 Spring Data JPA基础查询方法

原文:https://www.cnblogs.com/xianbeier/p/13688409.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!