SpringBoot学习笔记12-Data(SQL)

SpringBoot学习笔记12-Data(SQL),第1张

SpringBoot学习笔记12-Data(SQL)

以spring官方文档为基础,官方地址:Spring Boot_Data

Spring Boot集成了许多数据技术,无论是SQL还是NoSQL。本篇内容为:SQL

Spring框架为使用SQL数据库提供了广泛的支持,从使用JdbcTemplate直接访问JDBC到完成Hibernate等“对象关系映射”技术。Spring Data提供了一种额外的功能:直接从接口创建Repository实现,并使用“从方法名生成查询”的约定。

1. 配置数据源_DataSource

Java的javax.sql.DataSource接口提供了处理数据库连接的标准方法。通常,“DataSource”使用URL和一些凭据来建立数据库连接。

1.1 嵌入式数据库

使用内存中的嵌入式数据库开发应用程序通常很方便。显然,内存中的数据库不提供持久存储。需要在应用程序启动时填充数据库,并准备在应用程序结束时丢弃数据。

Spring Boot可以自动配置嵌入式H2、HSQL和Derby数据库。不需要提供任何连接url。只需要包含对要使用的嵌入式数据库的构建依赖项。如果类路径上有多个嵌入式数据库,则设置spring.datasource.embedded-database-connection属性来控制使用哪一个。将该属性设置为none将禁用嵌入式数据库的自动配置。

如果在测试中使用此特性,可能会注意到,无论使用的应用程序上下文的数量如何,整个测试套件都重用了相同的数据库。如果想确保每个上下文都有一个独立的嵌入式数据库,可设置spring.datasource.generate-unique-name为true。

使用嵌入式数据库的的一个POM依赖例子为:


    org.springframework.boot
    spring-boot-starter-data-jpa


    org.hsqldb
    hsqldb
    runtime

嵌入式数据库需要依赖spring-jdbc才能自动配置。在本例中,它通过spring-boot-starter-data-jpa传递地被拉入。

无论出于什么原因,如果确实为嵌入式数据库配置了连接URL,请确保禁用了数据库的自动关闭功能。如果使用H2,应该使用DB_CLOSE_ON_EXIT=FALSE。如果使用HSQLDB,应该确保不使用shutdown=true。禁用数据库的自动关闭功能可以让Spring Boot控制何时关闭数据库,从而确保一旦不再需要访问数据库,Spring Boot就会关闭数据库。

1.2 连接到生产数据库

生产数据库连接也可以通过使用池数据源自动配置。

1.3 数据源配置

数据源配置由spring.datasource.*中的外部配置属性控制。例如,可以在application.properties中声明以下部分:

spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass

至少应该通过设置spring.datasource.url属性来指定URL。否则,Spring Boot会尝试自动配置嵌入式数据库。

Spring Boot可以从URL推断出大多数数据库的JDBC驱动程序类。如果需要指定一个特定的类,可以使用spring.datasource.driver-class-name属性。

创建池数据源时,需要先验证Driver类是否可用,所以需要进行检查。换句话说,如果设置了spring.datasource.driver-class-name=com.mysql.jdbc.Driver,那么该类必须是可加载的。

更多支持的选项请参见DataSourceProperties。这些是标准选项,不管实际实现如何,它们都可以工作。也可以通过使用它们各自的前缀来调整特定于实现的设置(比如spring.datasource.hikari., spring.datasource.tomcat., spring.datasource.dbcp2., spring.datasource.oracleucp.)。有关详细信息,请参阅你正在使用的连接池实现的文档。

例如,如果使用的是Tomcat连接池,则可以自定义许多额外的设置,如下所示:

spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.max-active=50
spring.datasource.tomcat.test-on-borrow=true

上述设置表明:如果没可用的连接,在抛出异常之前pool至多等待10000ms,且将最大连接数限制为50,并在从池使用连接之前验证连接。

1.4 支持的连接池

Spring Boot使用以下算法来选择一个特定的实现:

  • 更偏向使用HikariCP,因为它的性能和并发性。如果HikariCP可用,Spring Boot总是选择它。

  • 否则,如果Tomcat池数据源可用,就使用它。

  • 否则,如果Commons DBCP2可用,就使用它。

  • 如果HikariCP、Tomcat和DBCP2都不可用,并且Oracle UCP可用,就使用它。

如果使用的是spring-boot-starter-jdbc或spring-boot-starter-data-jpa“启动器”,那么将会自动获得对HikariCP的依赖。

也可以完全绕过该算法,并通过设置spring.datasource.type属性指定要使用的连接池。有一个点需要注意:如果在Tomcat容器中运行应用程序,Tomcat -jdbc是默认提供的。

额外的连接池总是可以使用DataSourceBuilder手动配置。DataSourceBuilder支持以下连接池:

  • HikariCP
  • Tomcat pooling Datasource
  • Commons DBCP2
  • Oracle UCP和OracleDataSource
  • Spring框架的SimpleDriverDataSource
  • H2 JdbcDataSource
  • PostgreSQL PGSimpleDataSource
1.5 连接到JNDI数据源

如果将Spring Boot应用程序部署到application Server,你可能希望通过使用application Server的内置特性来配置和管理数据源,并通过使用JNDI来访问它。

spring.datasource.jndi-name属性可作为spring.datasource.url, spring.datasource.username, 和spring.datasource.password的一个代替,它可以实现从特定的JNDI位置访问DataSource。例如,以下例子展示了如何访问JBoss 数据源:

spring.datasource.jndi-name=java:jboss/datasources/customers
2. 使用JdbcTemplate

Spring的JdbcTemplate和NamedParameterJdbcTemplate类是自动配置的,可以直接@Autowire它们到自己的bean中,如下面的例子所示:

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final JdbcTemplate jdbcTemplate;

    public MyBean(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public void doSomething() {
        this.jdbcTemplate ...
    }

}

也可以使用spring.jdbc.template.*属性自定义模板的一些属性,示例如下:

spring.jdbc.template.max-rows=500

NamedParameterJdbcTemplate在后台重用相同的JdbcTemplate实例。如果定义了多个JdbcTemplate,并且不存在主候选,则NamedParameterJdbcTemplate不会自动配置。

3. JPA 和 Spring Data JPA

Java Persistence API是一种标准技术,它允许我们将对象“映射”到关系数据库。spring-boot-starter-data-jpa POM提供了一种快速启动的方法。它提供以下关键依赖项:

  • Hibernate:最流行的JPA实现之一
  • Spring Data JPA:帮助我们实现基于JPA的存储库
  • Spring ORM:来自Spring框架的核心ORM支持
3.1 实体类

传统上,JPA“实体”类在persistence.xml文件中指定。但在Spring Boot中,这个文件不是必需的,而是使用“实体扫描”。默认情况下,搜索主配置类下面的所有包(带有@EnableAutoConfiguration或@SpringBootApplication注释的包)。

任何带有@Entity、@Embeddable或@MappedSuperclass注解的类都会被扫描进来。一个典型的实体类例子如下:

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class City implements Serializable {

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String state;

    // ... additional members, often include @oneToMany mappings

    protected City() {
        // no-args constructor required by JPA spec
        // this one is protected since it should not be used directly
    }

    public City(String name, String state) {
        this.name = name;
        this.state = state;
    }

    public String getName() {
        return this.name;
    }

    public String getState() {
        return this.state;
    }

    // ... etc

}

也可以使用@EntityScan注释自定义实体扫描位置。

3.2 Spring Data JPA Repositories

Spring Data JPA存储库是可以定义来访问数据的接口。JPA查询是根据方法名自动创建的。例如,CityRepository接口可能声明一个findAllByState(String state)方法来查找处于给定状态的所有城市。

对于更复杂的查询,可以使用Spring Data的Query注释来注释方法。

Spring数据存储库通常是从Repository或CrudRepository接口扩展而来。如果使用自动配置,存储库将从包含主配置类(带有@EnableAutoConfiguration或@SpringBootApplication注释的类)的包中搜索下来。

下面的例子展示了一个典型的Spring Data repository接口定义:

import org.springframework.boot.docs.data.sql.jpaandspringdata.entityclasses.City;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.Repository;

public interface CityRepository extends Repository {

    Page findAll(Pageable pageable);

    City findByNameAndStateAllIgnoringCase(String name, String state);

}

Spring Data JPA存储库支持三种不同的引导模式:default, deferred, 和lazy。要deferred或lazy延迟启动,须将spring.data.jpa.repositories.bootstrap-mode属性分别设置为deferred或lazy。当使用延迟或惰性引导时,自动配置的EntityManagerFactoryBuilder将使用上下文的AsyncTaskExecutor(如果有的话)作为引导执行器。如果存在多个,则将使用名为applicationTaskExecutor的对象。

以上仅触及了Spring Data JPA的皮毛。有关完整的详细信息,请参阅Spring Data JPA参考文档。

3.3 Spring Data Envers Repositories

如果Spring Data Envers可用,JPA存储库将自动配置为支持典型的Envers查询。

要使用Spring Data Envers,请确保存储库是从RevisionRepository扩展而来,如下所示:

import org.springframework.boot.docs.data.sql.jpaandspringdata.entityclasses.Country;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.history.RevisionRepository;

public interface CountryRepository extends RevisionRepository, Repository {

    Page findAll(Pageable pageable);

}

更多信息,可查阅Spring Data Envers篇。

3.4 创建和删除JPA数据库

默认情况下,只有在使用嵌入式数据库(H2、HSQL或Derby)时,才会自动创建JPA数据库。不过可以通过使用spring.jpa.*属性显式地配置JPA设置。例如,要创建和删除表,你可以在你的application.properties中添加以下行:

spring.jpa.hibernate.ddl-auto=create-drop

Hibernate自己的内部属性名是Hibernate .hbm2ddl.auto。可以通过使用spring.jpa.properties.*来设置它,以及其他Hibernate原生属性(在将它们添加到实体管理器之前,前缀被删除了)。下面这行展示了一个为Hibernate设置JPA属性的例子:

spring.jpa.properties.hibernate[globally_quoted_identifiers]=true

以上例子中,实现了向Hibernate实体管理器中hibernate.globally_quoted_identifiers属性传递了一个true值。

默认情况下,DDL执行(或验证)被推迟到ApplicationContext启动之后。还有一个spring.jpa.generate-ddl标志,但是如果Hibernate的自动配置是active的,就不会使用它,因为ddl-auto设置的颗粒度更细。

3.5 打开EntityManager视图

如果正在运行一个web应用程序,Spring Boot默认注册OpenEntityManagerInViewInterceptor来应用“Open EntityManager in View”模式,以允许在web视图中延迟加载。如果不想要这种行为,可以在application.properties中将spring.jpa.open-in-view设置为false。

4. Spring Data JDBC

Spring Data包含了对JDBC的存储库支持,并将自动为CrudRepository上的方法生成SQL。对于更高级的查询,提供了@Query注释。

当类路径上有必要的依赖项时,Spring Boot将自动配置Spring Data的JDBC存储库。通过对spring-boot- startup -data-jdbc的单一依赖,可以将它们添加到项目中。如果需要,可以通过向应用程序添加@EnableJdbcRepositories注释或JdbcConfiguration子类来控制Spring Data JDBC的配置。

更多信息,可参看Spring Data JDBC篇。

5. 使用H2的Web控制台

H2数据库提供了一个基于浏览器的控制台,Spring Boot可以自动配置它。当满足以下条件时,控制台会自动配置:

  • 正在开发的是一个基于servlet的web应用程序。
  • com.h2database:h2位于类路径上。
  • 使用了Spring Boot开发工具。

如果没有使用Spring Boot开发工具,但是仍然想使用H2的控制台,也可以启用配置spring.h2.console.enabled的值为true。

关于更改H2控制台的路径:
默认情况下,控制台在/h2-console路径下可用。但可以使用spring.h2.console.path属性自定义控制台路径。

6. 使用R2DBC

响应式关系数据库连接(R2DBC)项目将响应式编程api引入关系数据库。R2DBC 的io.r2dbc.spi.Connection提供了处理非阻塞数据库连接的标准方法。其连接是通过使用ConnectionFactory提供的,类似于带有jdbc的DataSource。

ConnectionFactory配置由spring.r2dbc.*中的外部配置属性控制。例如,可以在application.properties中声明以下部分:

spring.r2dbc.url=r2dbc:postgresql://localhost/test
spring.r2dbc.username=dbuser
spring.r2dbc.password=dbpass

不需要指定驱动程序类名,因为Spring Boot从R2DBC的Connection Factory发现中获得驱动程序。

如果要定制ConnectionFactory创建的连接,也就是说,设置你不希望(或不能)在中央数据库配置中配置的特定参数,可以使用ConnectionFactoryOptionsBuilderCustomizer @Bean。下面的例子展示了如何手动覆盖数据库端口,而其余的选项来自应用程序配置:

import io.r2dbc.spi.ConnectionFactoryOptions;

import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyR2dbcConfiguration {

    @Bean
    public ConnectionFactoryOptionsBuilderCustomizer connectionFactoryPortCustomizer() {
        return (builder) -> builder.option(ConnectionFactoryOptions.PORT, 5432);
    }

}

下面的例子展示了如何设置一些PostgreSQL连接选项:

import java.util.HashMap;
import java.util.Map;

import io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider;

import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyPostgresR2dbcConfiguration {

    @Bean
    public ConnectionFactoryOptionsBuilderCustomizer postgresCustomizer() {
        Map options = new HashMap<>();
        options.put("lock_timeout", "30s");
        options.put("statement_timeout", "60s");
        return (builder) -> builder.option(PostgresqlConnectionFactoryProvider.OPTIONS, options);
    }

}

当ConnectionFactory bean可用时,常规JDBC DataSource自动配置将退出。如果希望保留JDBC DataSource自动配置,并且愿意承担在响应式应用程序中使用阻塞JDBC API的风险,请在应用程序中的@Configuration类上添加@import(DataSourceAutoConfiguration.class)来重新启用它。

6.1 嵌入式数据库支持

与JDBC支持类似,Spring Boot可以自动为响应式使用配置嵌入式数据库。并且也不需要提供任何连接url。只需要包含一个你想要使用的嵌入式数据库的构建依赖,如下所示:


    io.r2dbc
    r2dbc-h2
    runtime

如果在测试中使用,可能会注意到,无论使用的应用程序上下文的数量如何,整个测试套件都重用了相同的数据库。如果想确保每个上下文都有一个单独的嵌入式数据库,应该设置spring.r2dbc.generate-unique-name为true。

6.2 使用DatabaseClient

DatabaseClient bean是自动配置的,可以用@Autowire它直接到你自己的bean中,如下面的例子所示:

import java.util.Map;

import reactor.core.publisher.Flux;

import org.springframework.r2dbc.core.DatabaseClient;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final DatabaseClient databaseClient;

    public MyBean(DatabaseClient databaseClient) {
        this.databaseClient = databaseClient;
    }

    public Flux> someMethod() {
        return this.databaseClient.sql("select * from user").fetch().all();
    }

}

6.3 Spring Data R2DBC Repositories

Spring Data R2DBC存储库可以用来定义访问数据的接口。Queries查询会根据方法名自动创建。例如,CityRepository接口可能声明一个findAllByState(String state)方法来查找处于给定状态的所有城市。

对于更复杂的查询,可以使用Spring Data的Query注释来注释方法。

Spring数据存储库通常是从Repository或CrudRepository接口扩展而来。如果使用自动配置,存储库将从包含主配置类(带有@EnableAutoConfiguration或@SpringBootApplication注释的类)的包中搜索下来。

下面的例子展示了一个典型的Spring Data repository接口定义:

import reactor.core.publisher.Mono;

import org.springframework.data.repository.Repository;

public interface CityRepository extends Repository {

    Mono findByNameAndStateAllIgnoringCase(String name, String state);

}

更多信息,可参看Spring Data R2DBC篇。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5687357.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存