Spring框架为使用SQL数据库提供了广泛支持,从使用 JdbcTemplate 直接访问JDBC到完全的对象关系映射(ORM)
技术,比如Hibernate。Spring Data提供了更高级的功能,直接从接口创建 Repository 实现,并根据约定从方法名生成查询。
配置DataSource
Java的 javax.sql.DataSource 接口提供了一个标准的使用数据库连接的方法。通常,DataSource使用 URL 和相应的凭证去初始化数据库连接。
对内嵌数据库的支持
开发应用时使用内存数据库是很方便的。显然,内存数据库不提供持久化存储;只需要在应用启动时填充数据库,在应用结束前预先清除数据。Spring Boot可以自动配置的内嵌数据库包括H2, HSQL和Derby。不需要提供任何连接URLs,只需要添加想使用的内嵌数据库依赖。
示例:典型的POM依赖如下:
注 对于自动配置的内嵌数据库,需要添加 spring-jdbc
依赖,在本示例中, spring-boot-starter-data-jpa
已包含该依赖了。
无论出于什么原因,需要配置内嵌数据库的连接URL,一定要确保数据库的自动关闭是禁用的。如果使用H2,需要设置 DB_CLOSE_ON_EXIT=FALSE
。如果使用HSQLDB,需要确保没使用 shutdown=true
。禁用数据库的自动关闭可以让Spring Boot控制何时关闭数据库,因此在数据库不需要时可以确保关闭只发生一次。
连接生产环境数据库
生产环境的数据库连接可以通过池化的 DataSource 进行自动配置,下面是选取特定实现的算法:
- 出于tomcat数据源连接池的优秀性能和并发,如果可用总会优先使用它。
- 如果HikariCP可用,我们将使用它。
- 如果Commons DBCP可用,我们将使用它,但生产环境不推荐。
- 最后,如果Commons DBCP2可用,我们将使用它。
如果使用 spring-boot-starter-jdbc
或 spring-boot-starter-data-jpa
‘starters’,会自动添加 tomcat-jdbc
依赖。
注 通过指定 spring.datasource.type
属性,可以完全抛弃该算法,然后指定数据库连接池。如果在tomcat容器中运行应用,由于默认提供 tomcat-jdbc ,这就很重要了。
注 其他的连接池可以手动配置,如果定义自己的 DataSource
bean,自动配置是不会发生的。
DataSource配置被外部的 spring.datasource.*
属性控制,例如,可能会在 application.properties
中声明以下片段:
注 应该至少使用 spring.datasource.url
属性指定url,或Spring Boot尝试自动配置内嵌数据库。
注 通常不需要指定 driver-class-name
,因为Spring boot可以从 url
推断大部分数据库。
注 对于将要创建的池化 DataSource
,我们需要验证是否有一个可用的 Driver
,所以在做其他事前会校验它。比如,如果设置 spring.datasource.driver-class-name=com.mysql.jdbc.Driver
,然后该class加载出来,否则就会出错。
其他可选配置可以查看DataSourceProperties,有些标准配置是跟实现无关的,对于实现相关的配置可以通过相应前缀进行设置( spring.datasource.tomcat.*
, spring.datasource.hikari.*
, spring.datasource.dbcp.*
和 spring.datasource.dbcp2.*
),具体参考使用的连接池文档。
举例来说,如果正在使用Tomcat连接池,可以自定义很多其他设置:
连接JNDI数据库
如果正在将Spring Boot应用部署到一个应用服务器,我们可能想要用应用服务器内建的特性来配置和管理DataSource,并使用JNDI访问它。spring.datasource.jndi-name
属性可用来替代 spring.datasource.url
, spring.datasource.username
和 spring.datasource.password
去从一个特定的JNDI路径获取 DataSource
,比如,以下 application.properties
中的片段展示了如何获取JBoss AS定义的 DataSource
:
使用JdbcTemplate
Spring的 JdbcTemplate
和 NamedParameterJdbcTemplate
类会被自动配置,可以将它们直接 @Autowire
到自己的beans:
JPA和Spring Data
Java持久化API是一个允许将对象映射为关系数据库的标准技术, springboot-starter-data-jpa
POM提供了一种快速上手的方式,它提供以下关键依赖:
- Hibernate - 一个非常流行的JPA实现。
- Spring Data JPA - 让实现基于JPA的repositories更容易。
- Spring ORMs - Spring框架支持的核心ORM。
注 更多关于JPA或Spring Data的细节。可以参考来自spring.io的指南使用JPA获取数据,并阅读Spring Data JPA和Hibernate的参考文档。
注 Spring Boot默认使用Hibernate 5.0.x,如果希望的话也可以使用4.3.x或5.2.x,具体参考Hibernate 4和Hibernate 5.2示例。
实体类
通常,JPA实体类被定义到一个 persistence.xml
文件,在Spring Boot中,这个文件被实体扫描
取代。默认情况,Spring Boot会查找主配置类(被 @EnableAutoConfiguration 或 @SpringBootApplication 注解的类)下的所有包。
任何被 @Entity
, @Embeddable
或 @MappedSuperclass
注解的类都将被考虑,一个普通的实体类看起来像这样:
注 可以使用 @EntityScan
注解自定义实体扫描路径,具体参考Section 74.4,“Separate @Entity definitions from Spring configuration”。
Spring Data JPA仓库
Spring Data JPA仓库(repositories)是用来定义访问数据的接口。根据方法名,JPA查询会被自动创建,比如,一个 CityRepository
接口可能声明一个 findAllByState(String state)
方法,用来查找给定状态的所有城市。
对于比较复杂的查询,可以使用Spring Data的 Query 注解方法。
Spring Data仓库通常继承自 Repository 或 CrudRepository 接口。如果使用
自动配置,Spring Boot会搜索主配置类(注
解 @EnableAutoConfiguration 或 @SpringBootApplication 的类)所在包下
的仓库。
下面是典型的Spring Data仓库:
注:更多详细细节参考Spring Data JPA的参考指南。
创建和删除JPA数据库
默认情况下,只有在使用内嵌数据库(H2, HSQL或Derby)时,JPA数据库才会被自动创建。可以使用 spring.jpa.*
属性显式的设置JPA,比如,将以下配置添加到 application.properties
中可以创建和删除表:
注 Hibernate自己内部对创建,删除表支持的属性是 hibernate.hbm2ddl.auto
。可以使用 spring.jpa.properties.*
(前缀在被添加到实体管理器之前会被去掉)设置Hibernate其他的native属性,比如:
将传递 hibernate.globally_quoted_identifiers
到Hibernate实体管理器。
通常,DDL执行(或验证)被延迟到 ApplicationContext
启动后,这可以通过 spring.jpa.generate-ddl
标签控制,如果Hibernate自动配置被激活,那该标识就不会被使用,因为 ddl-auto
设置粒度更细。
使用H2的web控制台
H2数据库提供一个基于浏览器的控制台,Spring Boot可以自动配置。如果以下条件满足,则控制台会被自动配置:
注 如果没有使用Spring Boot的开发者工具,仍想利用H2的控制台,可以设置 spring.h2.console.enabled
属性值为 true
。H2控制台应该只用于开发期间,所以确保生产环境没有设置 spring.h2.console.enabled
。
改变H2控制台路径
H2控制台路径默认为 /h2-console
,可以通过设置 spring.h2.console.path
属性自定义该路径。
保护H2控制台
当添加Spring Security依赖,并且启用基本认证时,Spring Boot自动使用基本认证保护H2控制台。以下属性可用于自定义安全配置:
security.user.role
security.basic.authorize-mode
security.basic.enabled
使用jOOQ
Java面向对象查询(jOOQ)是Data Geekery的一个明星产品,可以从数据库生成Java代码,通过它的流式API构建类型安全的SQL查询。不管是商业版,还是
开源版本都能跟Spring Boot一块使用。
代码生成
为了使用jOOQ的类型安全查询,需要从数据库Schema中生成Java类。具体可以参照jOOQ的用户手册的操作指南。如果正在使用jooq-codegen-maven
插件(并且使用spring-boot-starter-parent
parent pom), 那么可以安全地省略插件的<version>
标签。当然也可以使用Spring Boot来定义版本变量 (例如. h2.version
)来声明插件的数据库依赖。
使用 DSLContext
jOOQ提供的fluent API是通过 org.jooq.DSLContext
接口初始化的。Spring Boot会自动配置一个作为Spring Bean的DSLContext
,并且连接到应用程序DataSource
,想要使用DSLContext
就只需要@Autowire
就可以了。
jOOQ 指南中使用了一个名为create
的变量来存储DSLContext, 以上例子是相同的。
接下来就可以通过DSLContext
来构建相关查询了:
Customizing jOOQ
jOOQ可以通过在application.properties
中设置spring.jooq.sql-dialect
来定制化SQL dialect。例如,想要指定为Postgres
可以添加:
在jOOQ在创建的时候,可以通过定义自己的@Bean
定义来实现更多高级的定制化操作。可以为如下的jOOQ类型定义beans:
- ConnectionProvider
- TransactionProvider
- RecordMapperProvider
- RecordListenerProvider
- ExecuteListenerProvider
- VisitListenerProvider
可以通过创建自己的org.jooq.Configuration
@Bean
来获取完整的jOOQ配置控制权。
实验
本实验基于内嵌H2数据库进行。
创建一个Maven项目
pom.xml
application.yml
User.java
UserController.java
UserRepository.java
App.java
项目结构
运行结果
访问http://localhost:9090/users/all
,查看所有的用户列表:
通过浏览器的GET请求添加一个ID为1的用户http://localhost:9090/users/save?id=1&name=freud&age=29
和一个ID为2的用户http://localhost:9090/users/save?id=2&name=kang&age=30
:
访问http://localhost:9090/users/all
,查看所有的用户列表:
通过ID查看用户信息http://localhost:9090/users/find?id=1
:
通过ID删除用户信息http://localhost:9090/users/delete?id=1
:
访问http://localhost:9090/users/all
,查看所有的用户列表:
参考资料
Spring Boot Reference Guide : http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/