8.2.2 创建生产 Profile
多亏了自动配置,我们有了一个指向嵌入式 H2 数据库的 DataSource
Bean。更确切地说, DataSource
Bean 是一个数据库连接池,通常是 org.apache.tomcat.jdbc.pool.DataSource
。因此,很明显,要使用嵌入式 H2 之外的数据库,我们只需声明自己的 DataSource
Bean,指向我们选择的生产数据库,用它覆盖自动配置的 DataSource
Bean。
例如,假设我们想使用运行 localhost 上的 PostgreSQL 数据库,数据库名字是 readingList。下面的 @Bean
方法就能声明我们的 DataSource
Bean:
@Bean
@Profile("production")
public DataSource dataSource() {
DataSource ds = new DataSource();
ds.setDriverClassName("org.postgresql.Driver");
ds.setUrl("jdbc:postgresql://localhost:5432/readinglist");
ds.setUsername("habuma");
ds.setPassword("password");
return ds;
}
这里 DataSource
的类型是 Tomcat 的 org.apache.tomcat.jdbc.pool.DataSource
,不要和 javax.sql.DataSource
搞混了。前者是后者的实现。连接数据库所需的细节(包括 JDBC 驱动类名、数据库 URL、用户名和密码)提供给了 DataSourse
实例。声明了这个 Bean 之后,默认自动配置的 DataSource
Bean 就会忽略。
这个 @Bean
方法最关键的一点是,它还添加了 @Profile
注解,说明只有在 production
Profile 被激活时才会创建该 Bean。所以,在开发时我们还能继续使用嵌入式的 H2 数据库。激活 production
Profile 后就能使用 PostgreSQL 数据库了。
虽然这么做能达到目的,但是配置数据库细节的时候,最好还是不要显式地声明自己的 DataSource
Bean。在不替换自动配置的 Datasource
Bean 的情况下,我们还能通过 application.yml 或 application.properties 来配置数据库的细节。表 8-2 列出了在配置 DataSource
Bean 时用到的全部属性。
表 8-2 DataSource
配置属性
属性(带有 spring.datasource.前缀) | 描述 |
---|---|
| 数据源的名称 |
| 是否执行 data.sql(默认: |
| Schema(DDL)脚本资源的名称 |
| 数据(DML)脚本资源的名称 |
| 读入 SQL 脚本的字符集 |
| 读入 Schema 资源时所使用的平台(例如:schema-{platform}.sql) |
| 如果初始化失败是否还要继续(默认: |
| SQL 脚本的分隔符(默认: |
| JDBC 驱动的全限定类名(通常能通过 URL 自动推断出来) |
| 数据库 URL |
| 数据库的用户名 |
| 数据库的密码 |
| 通过 JNDI 查找数据源的 JNDI 名称 |
| 最大的活跃连接数(默认: |
| 最大的闲置连接数(默认: |
| 最小的闲置连接数(默认: |
| 连接池的初始大小(默认: |
| 用来验证连接的查询语句 |
| 从连接池借用连接时是否检查连接(默认: |
| 向连接池归还连接时是否检查连接(默认: |
| 连接空闲时是否测试连接(默认: |
| 多久(单位为毫秒)清理一次连接(默认: |
| 在被测试是否要清理前,连接最少可以空闲多久(单位为毫秒,默认: |
| 当没有可用连接时,连接池在返回失败前最多等多久(单位为毫秒,默认: |
| 数据源是否可以通过 JMX 进行管理(默认: |
表 8-2 里的大部分属性都是用来微调连接池的。怎么设置这些属性以适应你的需要,这就交给你来解决了。我们现在要设置属性,让 DataSource
Bean 指向 PostgreSQL 而非内嵌的 H2 数据库。具体来说,我们要设置的是 spring.datasource.url
、 spring.datasource.username
以及 spring.datasource.password
属性。
在设置这些内容时,我在本地运行了一个 PostgreSQL 数据库,监听 5432 端口。用户名和密码分别是 habuma 和 password。因此,application.yml 的 production
Profile 里需要如下内容:
---
spring:
profiles: production
datasource:
url: jdbc:postgresql://localhost:5432/readinglist
username: habuma
password: password
jpa:
database-platform: org.hibernate.dialect.PostgreSQLDialect
请注意,这个代码片段以 ---
开头,设置的第一个属性是 spring.profiles
。这说明随后的属性都只在 production
Profile 激活时才会生效。
随后设置的是 spring.datasource.url
、 spring.datasource.username
和 spring.datasource.password
属性。注意, spring.datasource.driver-class-name
属性一般无需设置。Spring Boot 可以根据 spring.datasource.url
属性的值做出相应推断。我还设置了一些 JPA 的属性。 spring.jpa.database-platform
属性将底层的 JPA 引擎设置为 Hibernate 的 PostgreSQL 方言。
要开启这个 Profile,我们需要把 spring.profiles.active
属性设置为 production
。实现方式有很多,但最方便的还是在运行应用服务器的机器上设置一个系统环境变量。在启动 Tomcat 前开启 production
Profile,我需要像这样设置 SPRING_PROFILES_ACTIVE
环境变量:
$ export SPRING_PROFILES_ACTIVE=production
你也许已经注意到了, SPRING_PROFILES_ACTIVE
不同于 spring.profiles.active
。因为无法在环境变量名里使用句点,所以变量名需要稍作修改。站在 Spring 的角度看,这两个名字是等价的。
我们基本已经可以在应用服务器上部署并运行应用程序了。实际上,如果你喜欢冒险,也可以直接尝试一下。不过你会遇到一点小问题。
默认情况下,在使用内嵌的 H2 数据库时,Spring Boot 会配置 Hibernate 来自动创建 Schema。更确切地说,这是将 Hibernate 的 hibernate.hbm2ddl.auto
设置为 create-drop
,说明在 Hibernate 的 SessionFactory
创建时会创建 Schema, SessionFactory
关闭时删除 Schema。
但如果没使用内嵌的 H2 数据库,那么它什么都不会做。也就是,说应用程序的数据表尚不存在,在查询那些不存在的表时会报错。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论