Spring Data快速入门

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支持

如:

  1. CrudRepository
  2. PagingAndSortingRepository
  3. JpaRepository等

2 SpringDataJPA(JDBC升级版)

在这里插入图片描述

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才能操作数据库。
    在这里插入图片描述

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框架。

在这里插入图片描述

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.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>
  1. 编写测试类

项目结构:
在这里插入图片描述

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框架,可以通过如下方式切换:

  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.auto
                        create      : 程序运行时创建数据库表(如果有表,先删除表再创建)
                        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后实体的状态,因为事务已经提交了,此时实体的属性任你如何改变,也不会同步到数据库,因为游离是没人管的孩子,不在持久化上下文中。

在这里插入图片描述

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

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

在这里插入图片描述

  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/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
  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
            - 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 一对多(多对一)

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

  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 {

    @Autowired
    private UserRepository repository;

    @Test
    public void testC(){
        User user = new User();
        user.setUserAge(3);
        user.setUserName("Jackson");
        repository.save(user);
    }
}
  1. 效果
    在这里插入图片描述
    在这里插入图片描述

5.2 自动配置原理

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

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

就相当于 @EnableJpaRepositories

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值