一)JPA接口的继承结构

1.1)SpringData 加入的主要是两个包
		1.SpringData-Commons.jar
	2.SpringData-jpa.jar
		1.2)JPA接口分布在这两个包下每个接口主要的作用和方法介绍
		1.JapResposttory:接口
		该接口是开放是常用的接口,此接口为封装了对数据库常用的Curd操作。
		此接口存放于SpringData-jpa.jar包内
		主要的作用是:对父接口内的方法进行返回值类型的适配

Java JPA findAll 排除某些列 jpa findall sort_JPA

源码方法

List<T> findAll();//查询全部

List<T> findAll(Sort var1);//排序查询(默认查询全部)

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

<S extends T> List<S> save(Iterable<S> var1);//保存  :此方法有两个作用 一是保存,二是更新,时机为数据中没数据为添加,数据库有数据,但是传入的对象和数据库中的数据不一致为修改

void flush();//刷新同步

<S extends T> S saveAndFlush(S var1);//保存并刷新同步

void deleteInBatch(Iterable<T> var1);//批量删除

void deleteAllInBatch();//删除全部

T getOne(ID var1);//查询一个

2.PagingAndSortingReosutory接口,此接口封装了分页查询和排序操作

源码
注意:
1)PagingAndSortingReosutory接口存在SpringData-Commons.jar包内
2)PagingAndSortingReosutory接口内的分页方法默认是查询全部进行分页

Iterable<T> findAll(Sort var1);//条件查询全部

Page<T> findAll(Pageable var1);//分页查询

3.CrudRespostory接口

CrudRespostory接口位于SpringData-Commons.jar包下,同PagingAndSortingReosutory接口为一个包,封装了常见的对数据库的CURD操作
源码列表
publicinterface CrudRepository<T, ID extendsSerializable> extends Repository<T, ID> {
 
    <S extends T> S save(S entity);//保存 
    <S extends T> Iterable<S> save(Iterable<S> entities);//批量保存 
 
    T findOne(ID id);//根据id 查询一个对象。返回对象本身,当对象不存在时,返回null  
   Iterable<T> findAll();//查询所有的对象 
   Iterable<T> findAll(Iterable<ID> ids);//根据id列表查询所有的对象 
 
    boolean exists(ID id);//根据id 判断对象是否存在
    long count();//计算对象的总个数 
 
    void delete(ID id);//根据id 删除 
    void delete(T entity);//删除一个对象
    void delete(Iterable<? extendsT> entities);//批量删除,集合对象(后台执行时,一条一条删除)
    void deleteAll();//删除所有(后台执行时,一条一条删除)
}

4.Repostory接口
位于SpringData-Commons.jar包下
空接口为标识接口

public interface Repository<T, ID extends Serializable> {
}

5)JpaSpecificationExecutor

该接口封装了比PagingAndSortingReosutory接口更加强大的查询方法,包括带条件的分页查询,条件查询等
该接口提供了JPA Criteria(动态查询)的支持

public interface JpaSpecificationExecutor<T> {
    T findOne(Specification<T> var1); //返回一个

    List<T> findAll(Specification<T> var1);//查询全部带条件

    Page<T> findAll(Specification<T> var1, Pageable var2);//分页条件查询

    List<T> findAll(Specification<T> var1, Sort var2);//排序条件查询

    long count(Specification<T> var1);//计数
}

继承体系结构图

Java JPA findAll 排除某些列 jpa findall sort_Data_02

二)SpringData-JPA接口运行原理

使用 JPA接口进行持久化的操作的时候,并没对在接口内的书写任何的方法,接口是不能实例化的,那么SpingData是如何进行对数据库操作的呢?
1)dao接口

/**
 * @project_name:hibernate02
 * @date:2019/8/19:16:30
 * @author:shinelon
 * @Describe: 演示Spring Data JPA 进行持久层交互的时候,只需要继承指定的接口
 *              接口接收两个的泛型,
 *                 第一个是操作的表的实体类
 *                 第二个是主键的生成策略为主键的类型
 */

public interface UserDao  extends JpaRepository<Users, Integer> {
        //没有任何抽象方法
}

2)测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:ApplicationContext-hib.xml")
public class TestSpringDataJPA {

    @Autowired
    private UserDao userDao;

    @Test
    @Transactional
    @Rollback(false)
    public void testSpringDataJPASave(){
        Users users = new Users();
        users.setUsername("333");
        users.setPassword("444");
        this.userDao.save(users);
    }

首先查看注入的dao对象是什么

@Test
    public void test1(){
        System.out.println(this.userDao);
    }
}

注入的dao对象不是UserDao而是SimpleJpaRepository实现类
SimpleJpaRepository类其实就是Repostory接口体系的实现类
它实现了JpaRepository接口和JpaSpecificationExecutor接口,SpringData在进行数据库操作的时候实际上是将dao接口对象变成了SimpleJpaRepository对象

public class SimpleJpaRepository<T, ID extends Serializable> implements JpaRepository<T, ID>, JpaSpecificationExecutor<T> {
    private static final String ID_MUST_NOT_BE_NULL = "The given id must not be null!";
    private final JpaEntityInformation<T, ?> entityInformation;
    private final EntityManager em;
    private final PersistenceProvider provider;
    private CrudMethodMetadata metadata;

Java JPA findAll 排除某些列 jpa findall sort_System_03

在看下UserDao的类型
类型是代理类对象,并且使用的还是java的动态代理类实现的
那么此时也就明了了,SpringData在进行持久化操作的时候,是通过动态代理将dao对象变成了SimpleJpaRepository对象

@Test
    public void test1(){
        //org.springframework.data.jpa.repository.support.SimpleJpaRepository@1dbaaf3
        System.out.println(this.userDao);
        System.out.println(this.userDao.getClass());
    }
}

其实我们也可以自己通过SpringData提供的方法创建jpa的代理对象
要求
必须继承Repository接口
实例演示
需要JpaRepositoryFactory 就是用于创建Jpa代理对象的工厂,它接收一个EntityManager 对象,通过通过该对象构件,并且需要一个继承了Repository接口的接口

@PersistenceContext(name = "entityManagerFactory")
private EntityManager entityManager;

@Test
public void test1() {
    //org.springframework.data.jpa.repository.support.SimpleJpaRepository@1dbaaf3
    // System.out.println(this.userDao);
    //System.out.println(this.userDao.getClass());

    JpaRepositoryFactory factory = new JpaRepositoryFactory(entityManager);
    UserDao repository = factory.getRepository(UserDao.class);
    System.out.println(repository.getClass());
    System.out.println(repository);
}

Java JPA findAll 排除某些列 jpa findall sort_Data_04

总结:
JPA实际根据Dao接口继承Repostory接口体系的接口,在进行配置的时候添加JPA扫描的dao包,在扫描的时候将继承了Repostory体系的接口通过动态代理创建Repostory体系的实现类SimpleJpaRepository的对象注入给Dao接口。