资讯详情

Spring Boot 3.0.0-M1 Reference Documentation(Spring Boot中文参考文档) 9-16

9. 数据

Spring Boot与多个数据技术集成,包括SQL和NoSQL。

9.1. SQL数据库

Spring Framework为和谐提供扩展支持SQL数据工作,从使用JdbcTemplate直接JDBC访问完整的对象关系映射技术,如Hibernate。Spring Data提供额外的功能级别:直接从接口创建Repository实现并使用协议从方法名称生成查询。

9.1.1. 配置数据源

Java的javax.sql.DataSource接口提供与数据库链接的标准方法。传统上,‘DataSource’使用URL与证书一起建立数据库链接。

查看"How-to"了解更多高级示例,通常是为了完全控制数据源的配置。

嵌入式数据库支持

基于内存的嵌入式数据库开发应用程序通常非常方便。显然,内存数据库不提供持久存储。您需要在应用程序开始时填写数据,并在应用程序结束时丢弃数据。

"How-to"章节包括如何初始化数据库的一部分。

Spring Boot内嵌可自动配置H2,HSQL和Derby数据库。您不需要提供任何连接URL。你只需要包含你想要使用的内嵌数据库的构建依赖。如果在类路径有多个内嵌数据库,设置spring.datasource.embedded-database-connection配置属性控制您使用的属性。设置属性值为none禁止自动配置嵌入式数据。

如果您在测试中使用此功能,您可能会注意到,无论您使用多少在线应用程序,您的所有测试套件都重用了相同的数据库。如果您想确保每个上下文都有一个单独的嵌入式数据库,您应该设置它spring;datasource.generate-unique-nametrue

例如,典型的POM依赖如下:

<dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency>     <groupId>org.hsqldb</groupId>     <artifactId>hsqldb</artifactId>     <scope>runtime</scope> </dependency> 

你需要在spring-jdbc上一个依赖项用于自动配置嵌入式数据库。在这个例子中,它通过spring-boot-starter-data-jpa传递拉入。

如果,无论什么原因,你所做的配置链接URL对于嵌入式数据库,请确保禁止自动停止数据库。如果您使用它H2.你应该为此使用它DB_CLOSE_ON_EXIST=FALSE。如果你使用HSQLDB,确保不使用shutdown=true。当数据库关闭时,禁用数据库可以自动停止Spring Boot控制,确保不需要访问数据库自动关闭。

连接生产数据库

也可以使用生产数据库链接DataSource自动配置连接池。

DataSource配置

spring.datasource.*外部配置属性控制DataSource配置。例如,你可以application.properties声明如下:

spring:   datasource:     url: "jdbc:mysql://localhost/test"/span> username: "dbuser" password: "dbpass" 

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

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

为创建DataSource池,我们需要可以校验一个有效的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
      max-active: 50
      test-on-borrow: true

如果没有链接可用,这个将设置抛出异常之前链接池等待10000ms,限制最大的链接数是50并且在池中借出它之前校验链接。

支持的链接池

Spring Boot使用以下算法用于选择特定实现:

  1. 我们更喜欢HikariCP它的性能和并发性。如果HikariCP可用,我们总是选择它。
  2. 否则,如果Tomcat DataSource池可用,我们使用它。
  3. 否则,如果通用的DBCP2可用,我们使用它。
  4. 如果没有HikariCP,Tomcat和DBCP2可用,如果Oracle UCP可用,我们使用它。

如果你使用spring-boot-starter-jdbc或者spring-boot-starter-data-jap启动器,你自动得到HikariCP依赖项。

你可以完全绕过该算法并通过设置spring.datasource.type属性指定链接池来使用。如果在tomcat容器运行应用程序这点非常重要,因为默认提供tomcat-jdbc

使用DataSourceBuilder可以手工配置额外的链接池。如果你定义你自己的DataSourcebean,自动配置不会发生。下面的链接池通过DataSourceBuilder支持。

  • HikariCP
  • Tomcat DataSource
  • 通用的DBCP2
  • Oracel UCP&OracelDataSource
  • Spring Framework的SimpleDriverDataSource
  • H2 JdbcDataSource
  • PostgreSQL PGSimpleDataSource
链接到JNDI数据源

如果你部署你的Spring Boot应用程序到Application Server,你可能想要通过使用你的Application Server内建特性配置和管理你的DataSource并通过使用JNDI访问它。

spring.datasource.jndi-name属性可以用来当做spring.datasource.url的替代方案,spring.datasource.usernamespring.datasource.password属性可以从特定的JNDI位置访问DataSource。例如,下面的application.properties中部分展示根据定义的DataSource如何访问JBoss:

spring:
  datasource:
    jndi-name: "java:jboss/datasources/customers"

9.1.2. 使用JdbcTemplate

Spring的JdbcTempalteNamedParameterJdbcTemplate类是自动配置的,你可以直接@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被定义并没有主要的候选者存在,NamedParameterJdbcTempalte不会自动配置。

9.1.3. JPA和Spring Data JPA

Java Persistence API(Java持久化API)是标准的技术,让你“映射”对象到相关的数据库。spring-boot-starter-data-jpaPOM提供一个快速的方式开始。它提供以下关键依赖:

  • Hibernate:最受欢迎之一的JPA实现。
  • Spring Data JPA:帮助你实现基于JAP仓库。
  • Spring ORM:来自Spring Framework核心ORM支持。

这里我们不深入了解JPA和Spring Data的更多细节。你可以遵循来自spring.io的“使用JPA访问数据”指南并阅读Spring Data JPA和Hibernate参考文档。

实体类

传统上,在persistence.xml文件中指定JPA“实体”类。使用Spring Boot,这个文件不必须的并使用“Entity Scanning”代替。默认情况下,在你的主配置类(使用@EnableAutoConfiguration或者@SpringBootApplication注解的一个)下的所有包都会被搜索。

使用@Entity@Embeddable或者@MappedSuperclass注解的所有类都会考虑。一个典型的实体类类似于下面的示例:

import java.io.Serializable;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.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注解你可以定制实体扫描位置。请查看“将@Entity 定义与Spring Configuration分隔”如果做。

Spring Data JPA仓库

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

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

Spring Data仓库通常集成自Repository或者CrudRepository接口。如果你使用自动配置,将从你的主配置类(使用@EnableAutoConfiguration或者@SpringBootApplication注解的一个)搜索仓库。

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

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<City, Long> { 
        

    Page<City> findAll(Pageable pageable);

    City findByNameAndStateAllIgnoringCase(String name, String state);

}

Spring Data JPA仓库支持不同的引导指令模式:defalut,defered和lazy。为启用延迟的或者懒惰的引导指令,分别设置spring.data.jpa.repositories.bootstrap-mode属性为deferred或者lazy。当使用defered或者lazy引导指令,自动配置EntityManagerFactoryBuilder将使用上下文的AsyncTaskExecutor,若有的话,作为引导执行器。如果存在多余一个,名称为applicationTaskExecutor的那个将被使用。

当使用deferred或者lazy引导指令,确保在应用程序上下文引导阶段之后延迟对JPA基础设施的任何访问。你可以使用SmartInitializingSingleton以调用任何需要JPA基础设施的初始化。对于JPA组件(例如converters)被创建为Spring bean,如果有依赖项,请使用ObjectProvider来延迟解析。

我们只触碰到Spring Data JPA的皮毛。要了解完整的详情,请查阅Spring Data JPA参考文档。

Spring Data Envers仓库

如果Sprig Data Enver可用,JPA仓库自动配置以支持典型的Enver需求。

为使用Spring Data Enver,确保你的仓库继承于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<Country, Long, Integer>, Repository<Country, Long> { 
        

    Page<Country> findAll(Pageable pageable);

}

为了解更多详情,请查看Spring Data Enver参考文档。

创建和移除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.globally_quoted_identifiers属性true值到Hibernate实体管理。

默认情况下,DDL执行器(或者校验器)是延迟的直到ApplicationContext已经开始。也存在spring.jpa.generate-ddl标志,但是如果Hibernate自动配置是活跃的,它不会被使用,因为ddl-auto设置是更细粒度的。

视图中打开EntityManager

如果你正在运行一个web应用程序,默认情况下,Spring Boot注册OpenEntityManagerInViewInterceptor以应用“Open EntityManager In View”格式,允许在web视图中用于懒加载。如果你不希望这样的行为,你应该在application.properties中的spring.jpa.open-in-view设置为false

9.1.4. Spring Data JDBC

Spring Boot包含对JDBC支持的仓库并将对在CrudRepository上的方法自动生成SQL。对于更高级的查询,提供@Query注解。

当必须的依赖在类路径中时,Spring Boot将自动配置Spring Data的JDBC仓库。使用在spring-boot-starter-data-jdbc上的单个依赖将他们加入的项目。如果必须,你可以通过添加@EnableJdbcRepositories注解或者JdbcConfiguration子类到你的应用程序以控制Spring Data JDBC的配置。

为了解Spring Data JDBC完整详情,请查看参考文档。

9.1.5.使用H2web 控制台

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

  • 你正在开发一个基于Servlet的web应用程序。
  • com.h2database:h2在类路径中。
  • 你正在使用Spring Boot开发者工具。

如果你没有使用开发者工具但是仍想使用H2控制台, 你可以使用true值配置spring.h2.console.enabled属性。

H2控制台只打算用于开发期间使用,所以你应该小心,以确保生产环境spring.h2.console.enabled没有设置为true

更改H2控制台路径

默认情况下,控制台是使用在/h2-console。你可以通过使用spring.h2.console.path属性定制控制台路径。

在保障安全的应用程序中访问H2控制台

H2控制台使用框架并只打算用于开发环境,不支持CSRF保护措施。如果你的应用程序使用Spring Security,你需要配置它为:

  • 针对控制台请求禁用CSRF保护。
  • 在来自控制台的响应上设置头X-Frame-OptionsSAMEORIGIN。 在CSRF和头X-Frame-Options更多信息可以在Spring Security参考指南中发现。

在简单的设置中,像以下的SecurityFilterChain可以使用:

import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Profile("dev")
@Configuration(proxyBeanMethods = false)
public class DevProfileSecurityConfiguration { 
        

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    SecurityFilterChain h2ConsoleSecurityFilterChain(HttpSecurity http) throws Exception { 
        
        http.requestMatcher(PathRequest.toH2Console());
        http.authorizeRequests(yourCustomAuthorization());
        http.csrf((csrf) -> csrf.disable());
        http.headers((headers) -> headers.frameOptions().sameOrigin());
        return http.build();
    }


}

H2控制台只打算在开发期间使用。在生产环境,对站点禁用CSRF保护或者允许框架可能创建严重安全风险。

当控制台路径已经被定制,PathRequest.toH2Console()也可以返回正确的请求匹配器。

9.1.6. 使用jOOQ

jOOQ Object Oriented Querying(jOOQ)是来自Data Geekery非常受欢迎的产品,它根据你的数据库生成Java代码并允许你通过它的流式API构建类型安全的SQL查询。商业和开源版本都可以被Spring Boot使用。

代码生成

为了使用jOOQ类型安全查询,你需要从你的数据库模式生成Java类。你可以遵循jOOQ用户手册说明。如果你使用jooq-codegen-maven插件并且你也可以spring-boot-start-parent父POM,你可以安全地省去插件的<version>标签。你也可以使用预定义的Spring Boot版本变量(比如h2.version)以声明插件的数据库依赖。以下列表展示了一个示例:

<plugin>
    <groupId>org.jooq</groupId>
    <artifactId>jooq-codegen-maven</artifactId>
    <executions>
        ...
    </executions>
    <dependencies>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>${h2.version}</version>
        </dependency>
    </dependencies>
    <configuration>
        <jdbc>
            <driver>org.h2.Driver</driver>
            <url>jdbc:h2:~/yourdatabase</url>
        </jdbc>
        <generator>
            ...
        </generator>
    </configuration>
</plugin>
使用DSLContext

jOOQ提供的流式API通过org.jooq.DSLContext接口发起的。Spring Boot自动配置DSLContext作为Spring bean并将它与应用程序DataSource连接。为使用DSLContext,你可以注入它,如下示例所示:

import java.util.GregorianCalendar;
import java.util.List;

import org.jooq.DSLContext;

import org.springframework.stereotype.Component;

import static org.springframework.boot.docs.data.sql.jooq.dslcontext.Tables.AUTHOR;

@Component
public class MyBean { 
        

    private final DSLContext create;

    public MyBean(DSLContext dslContext) { 
        
        this.create = dslContext;
    }


}

jOOQ手册倾向于使用名为create变量名称来保存DSLContext

你仍可以使用DSLContext来构造你的查询,如下示例所示:

public List<GregorianCalendar> authorsBornAfter1980() { 
        
    return this.create.selectFrom(AUTHOR)
            .where(AUTHOR.DATE_OF_BIRTH.greaterThan(new GregorianCalendar(1980, 0, 1)))
            .fetch(AUTHOR.DATE_OF_BIRTH);

jOOQ SQL Dialect

除了spring.jooq.sql-dialect属性已经配置,Spring Boot决定SQL方言来用于数据源的使用。如果Spring Boot无法检测方言,他使用DEFAULT

Spring Boot只能通过开源的jOOQ版本自动配置支持的方言。

定制jOOQ

通过定义自己的DefaultConfigurationCustomizerbean可以实现更高级的定制,该bean将在创建org.jooq.Configuration``@Bean之前被调用。

9.1.7. 使用R2DBC

Reactive Relational Database Connectivity(R2DBC)项目采用响应式程序API关系型数据库。R2DBC的io.r2dbc.spi.Connection提供标准的工作于非阻塞数据库链接的方法。通过使用ConnectionFactory提供链接,类似于使用jdbc的DataSource

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

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

你不需要指定驱动类名称,因为Spring Boot从R2DBC的链接工厂发现获得。

至少应该提供url,URL中特定的信息优先级高于个别属性,那是name,username,password和池化选项。

“如何做”章节包含在如何初始化数据库部分。

为了通过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<String, String> options = new HashMap<>();
        options.put("lock_timeout", "30s");
        options.put("statement_timeout", "60s");
        return (builder) -> builder.option 

标签: 隔离变送器ws1521interface传感器mb

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台