Spring Data快速入门
1 SpringData概念(统一了数据存储,xxxTemplate)
Spring Data 提供了一系列的目标数据库的存储解决方案,其中包括但不限于关系型数据库(如 Oracle、MySQL、PostgreSQL、SQL Server 等)、文档数据库(如 MongoDB)、图形数据(如 Neo4j)以及 Redis 等 NoSQL 数据库等,它为这些数据库的访问提供了一致的 API 接口,从而使开发人员能够以相同的方式管理和操作各种数据存储系统。
SpringData统一了不同的数据存储,提升了开发效率,降低了学习成本
SpringData致力为数据访问层(DAO)提供熟悉且一致的基于Spring的编程模板。目的就是统一和简化对不同类型持久性存储(关系型数据库系统和NoSQL数据存储)的访问。
SpringData的主要特性:
- 模板制作
mongoTemplate、redisTemplate、jdbcTemplate…
- 对象/数据存储映射
可以通过XML或注解进行对象关系映射
- Repository支持
如:
- CrudRepository
- PagingAndSortingRepository
- JpaRepository等
2 SpringDataJPA(JDBC升级版)
2.1 什么是JPA,与JDBC有何区别?
相同处:
- 都跟操纵数据库有关,JPA是JDBC的升级版
- JDBC和JPA都是一组规范接口
- 都是sun公司出品的
不同处:
- JDBC是由各个关系型数据库实现的,JPA是由ORM框架实现的。
- JDBC使用SQL语句和数据库通信,JPA采用面向对象的方式,通过ORM框架来生成SQL,进行操作。
- JPA在JDBC之上,JPA也要依赖JDBC才能操作数据库。
Sun在JDK1.5提出了JPA,JPA全称Java Persistence API( 2019年重新命名为 Jakarta Persistence API ), 是Sun官方提出的 一种ORM规范。
JPA规范为我们提供了:
- ORM映射元数据:通过XML、注解方式完成对象和表的映射(@Entity、@Table、@Id、@Column等)
- JPA的API:用来操作实体对象,执行CRUD操作
- JPQL查询语言
JPA仅仅是一种规范,也就是说JPA仅仅定义了一些接口。
2.2 Hibernate与JPA关系(Hibernate实现了JPA规范)
JPA是一种规范(接口),而接口是需要实现才能工作的。Hibernate就是实现了JPA规范的ORM框架。
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快速体验
- 导入依赖
<!--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>
- 编写实体类
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;
}
- 编写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.auto
create:程序运行时创建数据库表(如果有表,先删除表再创建)
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>
- 编写测试类
项目结构:
TestHibernate.java:
public class TestHibernate {
private SessionFactory sf;
@Before
public void init(){
//读取hibernate配置文件
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure("/hibernate.cfg.xml").build();
//根据服务注册类创建一个元数据资源集,同时构建元数据并生成唯一的session工厂
sf = new MetadataSources(registry).buildMetadata().buildSessionFactory();
}
@Test
public void testCreate(){
//1. 创建session
Session session = sf.openSession();
//2. 开始事务
Transaction tx = session.beginTransaction();
//3. 创建消息实例
Consumer consumer = new Consumer();
consumer.setName("张三");
//4. 保存消息
session.save(consumer);
//5. 提交事务
tx.commit();
//6. 关闭session
session.close();
sf.close();
}
}
结果:
- hibernate中也有延迟加载的方法(即:用到该对象才会去查询)
- 同时hibernate也存在类似于Mybatis的两级缓存
拓展:
如果单独使用hibernate的API来进行持久化操作,无法随意切换其他ORM框架,可以通过如下方式切换:
- 在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.auto
create : 程序运行时创建数据库表(如果有表,先删除表再创建)
update :程序运行时创建表(如果有表,不会创建表)
none :不会创建表
-->
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
JPA对象的四种状态:
- 临时状态:刚创建出来,∙没有与entityManager发生关系,没有被持久化,不处于entityManager中的对象
- 持久状态:与entityManager发生关系,已经被持久化,您可以把持久化状态当做实实在在的数据库记录。
- 删除状态:执行remove方法,事物提交之前
- 游离状态:游离状态就是提交到数据库后,事务commit后实体的状态,因为事务已经提交了,此时实体的属性任你如何改变,也不会同步到数据库,因为游离是没人管的孩子,不在持久化上下文中。
如果你操作的是数据库中存在的对象(持久状态),就算没有提交事务,执行更新等方法后也依然可以改变对应的属性值
4 SpringDataJPA使用(ORM框架默认使用Hibernate)
- 导入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>
- 接口
//CrudRepository<T, ID> : T指定操作的实体对象 ID:指定主键类型
//PagingAndSortingRepository自带分页和排序的Repository
public interface ConsumerRepository extends CrudRepository<Consumer, Long> {
}
- 实体类
@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/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
https://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 {
@Bean
public 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;
}
@Bean
public 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>
* */
@Bean
public 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 {
@Autowired
private ConsumerRepository repository;
@Test
public void testR(){
Optional<Consumer> res = repository.findById(1L);
System.out.println(res);
//repository.delete(customer);
// CrudRepository ,有一个 PagingAndSortingRepository 抽象,它添加了额外的方法来简化对实体的分页访问
}
//测试排序
@Test
public void testSort(){
Sort.TypedSort<Consumer> sortType = Sort.sort(Consumer.class);
//根据id降序排列,如果有多个条件,可以直接在sortType后面.and
Sort sort = sortType.by(Consumer::getId).descending();
Iterable<Consumer> all = repository.findAll(sort);
System.out.println(all);
}
//测试分页
@Test
public 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等)
- 只支持查询和删除
- 支持的查询方法
谓词关键字和修饰符
- 决定查询条件
③ Query by Example
- 只支持查询
- 不支持嵌套或分组的属性约束,如:firstname = ? or (firstname = ?1 and lastname = ?2)
- 只支持字符串,start/contains/ends/regex匹配和其他属性类型的精确匹配
- 实现
将Repository继承QueryByExampleExecutor
④Specifications
在之前使用Query by Example只能针对字符串进行条件设置,那如果希望对所有类型支持,可以使用Specifications
- Query By Example只对字符串有效,Specifications对所有类型都支持
- 实现
继承接口JpaSpecificationExecutor
- 限制
不能分组、聚合函数, 需要自己通过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
- false
mappedBy
- 将外键约束交给另一方维护(通常在双向关联关系中,会放弃一方的外键约束)
值 = 另一方关联属性名
*/
@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 {
@Autowired
private CustomerRepository repository;
@Test
public 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);
}
}
结果:
4.4.2 一对多(多对一)
一对多与多对一其实是类似的,只不过站的角度不同
- 一对多
一个客户有收到多条信息
①配置管理关系
public class Customer{
...
// 一对多
// fetch 默认是懒加载 懒加载的优点( 提高查询性能)
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
@JoinColumn(name="customer_id")
private List<Message> messages;
}
②配置关联操作
- 多对一
一条消息可以发给多个用户
①配置管理关系
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 演示
- 导入依赖
<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>
- 编写配置文件
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
- 编写用例测试
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 {
@Autowired
private UserRepository repository;
@Test
public void testC(){
User user = new User();
user.setUserAge(3);
user.setUserName("Jackson");
repository.save(user);
}
}
- 效果
5.2 自动配置原理
- 通过 JpaBaseConfiguration 去配置我们以前集成spring data jpa的基本@Bean
- JpaRepositoriesAutoConfiguration
@Import(JpaRepositoriesImportSelector.class)
JpaRepositoriesImportSelector又会注册一个ImportBeanDefinitionRegistrar 其实就是JpaRepositoriesRegistrar
‐‐‐‐JpaRepositoriesRegistrar 跟通过@EnableJpaRepositories 导入进来的组件是同一个
就相当于 @EnableJpaRepositories