> 文章列表 > Spring Data快速入门

Spring Data快速入门

Spring Data快速入门

Spring Data快速入门

1 SpringData概念(统一了数据存储,xxxTemplate)

Spring Data 提供了一系列的目标数据库的存储解决方案,其中包括但不限于关系型数据库(如 Oracle、MySQL、PostgreSQL、SQL Server 等)、文档数据库(如 MongoDB)、图形数据(如 Neo4j)以及 Redis 等 NoSQL 数据库等,它为这些数据库的访问提供了一致的 API 接口,从而使开发人员能够以相同的方式管理和操作各种数据存储系统。

Spring Data快速入门

SpringData统一了不同的数据存储,提升了开发效率,降低了学习成本

SpringData致力为数据访问层(DAO)提供熟悉且一致的基于Spring的编程模板。目的就是统一和简化对不同类型持久性存储(关系型数据库系统和NoSQL数据存储)的访问。

SpringData的主要特性:

  • 模板制作

mongoTemplate、redisTemplate、jdbcTemplate…

  • 对象/数据存储映射

可以通过XML或注解进行对象关系映射

Spring Data快速入门

  • Repository支持

如:

  1. CrudRepository
  2. PagingAndSortingRepository
  3. JpaRepository等

2 SpringDataJPA(JDBC升级版)

Spring Data快速入门

2.1 什么是JPA,与JDBC有何区别?

相同处:

  1. 都跟操纵数据库有关,JPA是JDBC的升级版
  2. JDBC和JPA都是一组规范接口
  3. 都是sun公司出品的

不同处:

  1. JDBC是由各个关系型数据库实现的,JPA是由ORM框架实现的。
  2. JDBC使用SQL语句和数据库通信,JPA采用面向对象的方式,通过ORM框架来生成SQL,进行操作。
  3. JPA在JDBC之上,JPA也要依赖JDBC才能操作数据库。
    Spring Data快速入门

Sun在JDK1.5提出了JPA,JPA全称Java Persistence API( 2019年重新命名为 Jakarta Persistence API ), 是Sun官方提出的 一种ORM规范。
JPA规范为我们提供了:

  1. ORM映射元数据:通过XML、注解方式完成对象和表的映射(@Entity、@Table、@Id、@Column等)
  2. JPA的API:用来操作实体对象,执行CRUD操作
  3. JPQL查询语言

JPA仅仅是一种规范,也就是说JPA仅仅定义了一些接口。

2.2 Hibernate与JPA关系(Hibernate实现了JPA规范)

JPA是一种规范(接口),而接口是需要实现才能工作的。Hibernate就是实现了JPA规范的ORM框架。

Spring Data快速入门

MyBatis并没有实现JPA规范。

  • MyBatis:小巧、方便、高效、简单、半自动、就是对JDBC进行了简单的封装、国内更流行(业务复杂)
  • Hibernate:强大、方便、高效、全自动、根据ORM映射生成不同SQL、不方便处理业务复杂的场景、在业务相对简单的系统中进行使用、国外更流行。

3 Hibernate

官网地址:https://docs.jboss.org/hibernate/orm/5.5/userguide/html_single/Hibernate_User_Guide.html#hql

3.1 hibernate快速体验

  1. 导入依赖
<!--hibernate-->
<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-entitymanager</artifactId><version>5.4.32.Final</version>
</dependency>
<!--junit4-->
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope>
</dependency>
<!--mysql-->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version>
</dependency>
<!--lombok-->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version>
</dependency>
  1. 编写实体类

Consumer:

@Entity
@Table(name = "customer")
@Data
public class Consumer {/*@Id:声明主键@GeneratedValue:配置主键的生成策略- GenerationType.IDENTITY:自增(MySQL)- GenerationType.SEQUENCE:序列(Oracle)- GenerationType.TABLE:JPA提供的一种机制,通过一张数据库表的形式帮助我们完成主键自增- GenerationType.AUTO:由程序自动帮助我们选择主键生成策略@Column:配置属性和字段的映射关系name:数据库表中字段的名称*/@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id")//指定数据库对应列名private Long id;@Column(name = "name")private String name;@Column(name = "address")private String address;
}
  1. 编写hibernate.cfg.xml配置文件

只要我们在配置文件中配置, <property name="hbm2ddl.auto">update</property>,hibernate就会自动给我们创建表

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD//EN""http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration><session-factory><!--使用 Hibernate 自带的连接池配置--><property name="connection.url">jdbc:mysql://localhost:3306/springdata_jpa</property><property name="hibernate.connection.username">root</property><property name="hibernate.connection.password">200151</property><property name="connection.driver_class">com.mysql.jdbc.Driver</property><!--hibernate 方言--><property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property><!--打印sql语句--><property name="hibernate.show_sql">true</property><!--格式化sql--><property name="hibernate.format_sql">true</property><!--自动创建表--><!--        配置jpa实现方(hibernate)的配置信息显示sql:false|true自动创建数据库表:hibernate.hbm2ddl.autocreate:程序运行时创建数据库表(如果有表,先删除表再创建)update:程序运行时创建表(如果有表,不会创建表)none:不会创建表--><property name="hbm2ddl.auto">update</property><!-- 映射方式 --><mapping class="com.zi.entity.Consumer"></mapping><!-- 加载映射文件 --><!--<mapping resource="net/biancheng/www/mapping/User.hbm.xml"/>--></session-factory>
</hibernate-configuration>
  1. 编写测试类

项目结构:
Spring Data快速入门

TestHibernate.java:

public class TestHibernate {private SessionFactory sf;@Beforepublic void init(){//读取hibernate配置文件StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure("/hibernate.cfg.xml").build();//根据服务注册类创建一个元数据资源集,同时构建元数据并生成唯一的session工厂sf = new MetadataSources(registry).buildMetadata().buildSessionFactory();}@Testpublic void testCreate(){//1. 创建sessionSession session = sf.openSession();//2. 开始事务Transaction tx = session.beginTransaction();//3. 创建消息实例Consumer consumer = new Consumer();consumer.setName("张三");//4. 保存消息session.save(consumer);//5. 提交事务tx.commit();//6. 关闭sessionsession.close();sf.close();}
}

结果:

Spring Data快速入门

  • hibernate中也有延迟加载的方法(即:用到该对象才会去查询)
  • 同时hibernate也存在类似于Mybatis的两级缓存

拓展:如果单独使用hibernate的API来进行持久化操作,无法随意切换其他ORM框架,可以通过如下方式切换:

  1. 在resources目录下添加META-INF\\persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"><!--需要配置persistence-unit节点持久化单元:name:持久化单元名称transaction-type:事务管理的方式JTA:分布式事务管理RESOURCE_LOCAL:本地事务管理--><persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL"><!--jpa的实现方式 --><provider>org.hibernate.jpa.HibernatePersistenceProvider</provider><!--可选配置:配置jpa实现方的配置信息--><properties><!-- 数据库信息用户名,javax.persistence.jdbc.user密码,  javax.persistence.jdbc.password驱动,  javax.persistence.jdbc.driver数据库地址   javax.persistence.jdbc.url--><property name="javax.persistence.jdbc.user" value="root"/><property name="javax.persistence.jdbc.password" value="111111"/><property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/><property name="javax.persistence.jdbc.url" value="jdbc:mysql:///jpa"/><!--配置jpa实现方(hibernate)的配置信息显示sql           :   false|true自动创建数据库表    :  hibernate.hbm2ddl.autocreate      : 程序运行时创建数据库表(如果有表,先删除表再创建)update      :程序运行时创建表(如果有表,不会创建表)none        :不会创建表--><property name="hibernate.show_sql" value="true" /><property name="hibernate.hbm2ddl.auto" value="update" /></properties></persistence-unit>
</persistence>

JPA对象的四种状态:

  1. 临时状态:刚创建出来,∙没有与entityManager发生关系,没有被持久化,不处于entityManager中的对象
  2. 持久状态:与entityManager发生关系,已经被持久化,您可以把持久化状态当做实实在在的数据库记录。
  3. 删除状态:执行remove方法,事物提交之前
  4. 游离状态:游离状态就是提交到数据库后,事务commit后实体的状态,因为事务已经提交了,此时实体的属性任你如何改变,也不会同步到数据库,因为游离是没人管的孩子,不在持久化上下文中。

Spring Data快速入门

如果你操作的是数据库中存在的对象(持久状态),就算没有提交事务,执行更新等方法后也依然可以改变对应的属性值

4 SpringDataJPA使用(ORM框架默认使用Hibernate)

Spring Data快速入门

  1. 导入pom依赖
<dependencies><!--JPA依赖--><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-jpa</artifactId></dependency><!-- junit4 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency><!-- hibernate对jpa的支持包 --><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-entitymanager</artifactId><version>5.4.32.Final</version></dependency><!-- Mysql and MariaDB --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.29</version></dependency><!--连接池--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version></dependency><!--spring-test --><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.3.10</version><scope>test</scope></dependency></dependencies>
  1. 接口
//CrudRepository<T, ID> : T指定操作的实体对象 ID:指定主键类型
//PagingAndSortingRepository自带分页和排序的Repository
public interface ConsumerRepository extends CrudRepository<Consumer, Long> {
}
  1. 实体类
@Entity
@Table(name = "customer")
@Data
public class Consumer {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id")//指定数据库对应列名private Long id;@Column(name = "name")private String name;@Column(name = "address")private String address;
}

4.1 基于XML使用SpringDataJPA

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/data/jpahttps://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"><!--用于整合jpa  @EnableJpaRepositories --><jpa:repositories base-package="com.zi.repositories"entity-manager-factory-ref="entityManagerFactory"transaction-manager-ref="transactionManager"/><!--EntityManagerFactory--><bean name="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"><property name="jpaVendorAdapter"><!--Hibernate实现--><bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"><!--生成数据库表--><property name="generateDdl" value="true"></property><property name="showSql" value="true"></property></bean></property><!--设置实体类的包--><property name="packagesToScan" value="com.zi.entity"></property><property name="dataSource" ref="dataSource" ></property></bean><!--数据源--><bean class="com.alibaba.druid.pool.DruidDataSource" name="dataSource"><property name="username" value="root"/><property name="password" value="123456"/><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/springdata_jpa?characterEncoding=UTF-8"/></bean><!--声明式事务--><bean class="org.springframework.orm.jpa.JpaTransactionManager" name="transactionManager"><property name="entityManagerFactory" ref="entityManagerFactory"></property></bean><!--启动注解方式的声明式事务--><tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven></beans>

测试类中引用配置文件@ContextConfiguration("/spring.xml")

4.2 基于JavaConfig(注解)

@Configuration          // 标记当前类为配置类   =xml配文件
@EnableJpaRepositories(basePackages="com.zi.repositories")  // 启动jpa    <jpa:repositories
@EnableTransactionManagement    // 开启事务
public class SpringDataJPAConfig {@Beanpublic DataSource dataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setUsername("root");dataSource.setPassword("123456");dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql://localhost:3306/springdata_jpa?characterEncoding=UTF-8");return  dataSource;}@Beanpublic LocalContainerEntityManagerFactoryBean entityManagerFactory() {HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();vendorAdapter.setGenerateDdl(true);vendorAdapter.setShowSql(true);LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();factory.setJpaVendorAdapter(vendorAdapter);factory.setPackagesToScan("com.zi.entity");factory.setDataSource(dataSource());return factory;}/** <bean class="org.springframework.orm.jpa.JpaTransactionManager" name="transactionManager"><property name="entityManagerFactory" ref="entityManagerFactory"></property></bean>* */@Beanpublic PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {JpaTransactionManager txManager = new JpaTransactionManager();txManager.setEntityManagerFactory(entityManagerFactory);return txManager;}}

测试类中引用配置类@ContextConfiguration(classes = SpringDataJPAConfig.class)

测试类:

//@ContextConfiguration("/spring.xml")
@ContextConfiguration(classes = SpringDataJPAConfig.class)
@RunWith(SpringRunner.class)
public class SpringDataJPATest {@Autowiredprivate ConsumerRepository repository;@Testpublic void testR(){Optional<Consumer> res = repository.findById(1L);System.out.println(res);//repository.delete(customer);// CrudRepository ,有一个 PagingAndSortingRepository 抽象,它添加了额外的方法来简化对实体的分页访问}//测试排序@Testpublic void testSort(){Sort.TypedSort<Consumer> sortType = Sort.sort(Consumer.class);//根据id降序排列,如果有多个条件,可以直接在sortType后面.andSort sort = sortType.by(Consumer::getId).descending();Iterable<Consumer> all = repository.findAll(sort);System.out.println(all);}//测试分页@Testpublic void testPage(){//PageRequest.of(page, size, sort) 起始页,每页大小,排序Page<Consumer> all = repository.findAll(PageRequest.of(0, 2));System.out.println(all.getTotalElements());System.out.println(all.getTotalPages());System.out.println(all.getContent());}
}

4.3 JPQL与原生SQL(ORM使用hibernate)

①JPQL(原生SQL)

@Query- 查询如果返回单个实体就用pojo接收,如果是多个需要使用集合- 参数设置方式1. 索引:	?数字2. 具名:	:参数名 结合@Param注解指定参数名字- 增删改1. 要加上事务的支持2. 如果是插入方法,一定只有才hibernate下才支持(伪插入:insert into ...select)@Transactional //通常会放在逻辑层上声明
@Modifying //通知SpringDataJPA是增删改操作

②规定方法名(例:findByCustomName)

(通过一定的方法名命名规则自动生成)
推荐安装:JPABuddy插件,它能够帮我们提示

  • 支持的查询方法主题关键字(前缀)
    • 决定当前方法作用(如:find、delete等)
    • 只支持查询和删除
      Spring Data快速入门
  • 支持的查询方法谓词关键字和修饰符
    • 决定查询条件

Spring Data快速入门

③ Query by Example

  1. 只支持查询
    • 不支持嵌套或分组的属性约束,如:firstname = ? or (firstname = ?1 and lastname = ?2)
    • 只支持字符串,start/contains/ends/regex匹配和其他属性类型的精确匹配
  2. 实现

将Repository继承QueryByExampleExecutor

④Specifications

在之前使用Query by Example只能针对字符串进行条件设置,那如果希望对所有类型支持,可以使用Specifications

  1. Query By Example只对字符串有效,Specifications对所有类型都支持
  2. 实现

继承接口JpaSpecificationExecutor

  1. 限制

不能分组、聚合函数, 需要自己通过entityManager玩

⑤QueryDSL(通用查询框架,非Spring体系)

官网:https://querydsl.com/

  • QueryDSL是基于ORM框架或SQL平台上的一个通用查询框架。借助QueryDSL可以在任何支持的ORM框架或SQL平台上以通用API方式构建查询。
  • JPA是QueryDSL的主要集成技术,是JPQL和Criteria查询的代替方法。目前QueryDSL支持的平台包括JPA,JDO,SQL,Mongodb 等等。。。
  • Querydsl扩展能让我们以链式方式代码编写查询方法。该扩展需要一个接口QueryDslPredicateExecutor,它定义了很多查询方法。

使用过程中需要引入querydsl-jpa依赖,同时配置插件,让maven构建出对应实体类的Q对象

4.4 多表关联(hibernate实现)

SpringDataJPA的多表关联使用的是hibernate实现,它并没有提供额外的封装等

4.4.1 一对一

用户和实体是一对一的关系,一个账户对应一个用户,一个用户只能有一个账户

Account:

声明为entity,指明和Customer为一对一关系,并且指明外键是和customer_id

@Entity
@Table(name = "tb_account")
@Data
public class Account {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String username;private String password;@OneToOne@JoinColumn(name = "customer_id")private Customer customer;
}

Customer:

标明为entity,OneToOne声明customer和account是一对一关系,mappedBy将外键交给customer维护

@Entity
@Table(name = "tb_customer")
@Data
public class Customer {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id")private Long id;@Column(name = "cust_name")private String custName;@Column(name = "cust_address")private String custAddress;/*单向关联:一对一cascade 设置关联操作- ALL 所有持久化操作- PERSIST 只有插入时才会执行关联操作- MERGE 只有修改时才会执行- REMOVE 只有执行时fetch 设置是否懒加载- EAGER 立即加载(默认)- LAZY 懒加载(直到用到对象才会进行查询,因为不是所有的关联对象都需要用到)orphanRemoval 关联移除(通常在修改的时候会用到)- true:当关联的数据设置为null,或者修改其他的关联数据,就会删除关联数据optional- true(默认) 限制关联对象可以为null- falsemappedBy- 将外键约束交给另一方维护(通常在双向关联关系中,会放弃一方的外键约束)值 = 另一方关联属性名*/@OneToOne(mappedBy = "customer",cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)//设置外键的字段名@JoinColumn(name = "account_id")private Account account;
}

DAO:

public interface CustomerRepository extends PagingAndSortingRepository<Customer,Long>{
}

测试:

@ContextConfiguration(classes = SpringDataJPAConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class OneToOneTest {@Autowiredprivate CustomerRepository repository;@Testpublic void testC(){Account account = new Account();account.setUsername("jack");Customer customer = new Customer();customer.setCustName("jackAccountName");customer.setAccount(account);account.setCustomer(customer);repository.save(customer);}
}

结果:
Spring Data快速入门
Spring Data快速入门
Spring Data快速入门

4.4.2 一对多(多对一)

一对多与多对一其实是类似的,只不过站的角度不同

  1. 一对多

一个客户有收到多条信息

①配置管理关系

public class Customer{...// 一对多// fetch 默认是懒加载   懒加载的优点( 提高查询性能)@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY)@JoinColumn(name="customer_id")private List<Message> messages;
}

②配置关联操作

  1. 多对一

一条消息可以发给多个用户

①配置管理关系

public class Customer{...@ManyToOne@JoinColumn(name="customer_id")private List<Message> message;
}

②配置关联操作

public class Message{//多对一@ManyToOne(cascade = CascadeType.PERSIST)private Customer customer;
}

4.4.3 多对多

客户与角色,多对多

此处以单向多对多为例:
①配置管理关系

public class Customer{/*中间表需要设置@JoinTable来维护外键(不设置也会自动生成)name:指定中间表名称joinColumns 设置本表的外键名称inverseJoinColumns 设置关联表的外键名称*/@ManyToMany@JoinTable(name = "tb_customer_role",joinColumns={@JoinColumn(name="c_id")},inverseJoinColumns={@JoinColumn(name="r_id")})private List<Role> roles;
}

②配置关联操作

③测试

// 保存
/*
如果保存的关联数据 希望使用已有的 ,就需要从数据库中查出来(持久状态)。否则 提示 游离状态不能持久化
如果一个业务方法有多个持久化操作, 记得加上@Transactional ,否则不能共用一个session
在单元测试中用到了@Transactional , 如果有增删改的操作一定要加@Commit
单元测试会认为你的事务方法@Transactional, 只是测试而已, 它不会为你提交事务, 需要单独加上 @Commit
*/
@Test
@Transactional
@Commit
public void testC() {List<Role> roles=new ArrayList<>();roles.add(roleRepository.findById(9L).get());roles.add(roleRepository.findById(10L).get());Customer customer = new Customer();customer.setCustName("Jim");customer.setRoles(roles);repository.save(customer);
}

5 SpringBoot整合SpringDataJPA

5.1 演示

  1. 导入依赖
<properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.6.13</spring-boot.version></properties><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>
  1. 编写配置文件
    application.properties:
# 应用服务 WEB 访问端口
server.port=8080
#没有表的时候创建
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/springdata_jpa?serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456
# 打印SQL
spring.jpa.show-sql=true
# 格式化SQL
spring.jpa.properties.hibernate.format_sql = true
  1. 编写用例测试

User实体类:

@Table(schema = "tb_user")
@Entity
@Data
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;@Column(name = "name")private String userName;@Column(name = "age")private Integer userAge;
}

UserRepository:

//Integer对应的是User的Id类型
public interface UserRepository extends CrudRepository<User, Integer> {
}

测试类:

@SpringBootTest
public class Test01 {@Autowiredprivate UserRepository repository;@Testpublic void testC(){User user = new User();user.setUserAge(3);user.setUserName("Jackson");repository.save(user);}
}
  1. 效果
    Spring Data快速入门
    Spring Data快速入门

5.2 自动配置原理

  1. 通过 JpaBaseConfiguration 去配置我们以前集成spring data jpa的基本@Bean
  2. JpaRepositoriesAutoConfiguration

@Import(JpaRepositoriesImportSelector.class)
JpaRepositoriesImportSelector又会注册一个ImportBeanDefinitionRegistrar 其实就是JpaRepositoriesRegistrar
‐‐‐‐JpaRepositoriesRegistrar 跟通过@EnableJpaRepositories 导入进来的组件是同一个

就相当于 @EnableJpaRepositories