你一定知道!由于Grails是基于Java技术构建的,因此设置数据源需要一些JDBC知识(代表Java数据库连接的技术)。
如果使用H2以外的数据库,则需要JDBC驱动程序。例如,对于MySQL中,你将需要连接器/ J。
驱动程序通常以JAR存档的形式出现。如果jar在Maven存储库中可用,最好使用依赖关系解析来解析jar,例如,您可以为MySQL驱动程序添加依赖关系,如下所示:
dependencies {
runtime 'mysql:mysql-connector-java:5.1.29'
}
解决JAR后,您需要熟悉Grails如何管理其数据库配置。配置可以在grails-app/conf/application.groovy
或中保持grails-app/conf/application.yml
。这些文件包含dataSource定义,其中包括以下设置:
-
driverClassName
- JDBC驱动程序的类名 -
username
- 用于建立JDBC连接的用户名 -
password
- 用于建立JDBC连接的密码 -
url
- 数据库的JDBC URL -
dbCreate
- 是否从域模型自动生成数据库 - “创建 - 删除”,“创建”,“更新”或“验证”之一 -
pooled
- 是否使用连接池(默认为true) -
logSql
- 启用SQL日志记录到stdout -
formatSql
- 格式化记录的SQL -
dialect
- 表示用于与数据库通信的Hibernate方言的String或Class。有关可用的方言,请参阅org.hibernate.dialect包。 -
readOnly
- 如果true
使DataSource为只读,则会导致连接池调用setReadOnly(true)
每个Connection
-
transactional
- 如果false
将DataSource的transactionManager bean留在链接的BE1PC事务管理器实现之外。这仅适用于其他数据源。 -
persistenceInterceptor
- 默认数据源自动连接到持久性拦截器,其他数据源不会自动连接,除非将其设置为true
-
properties
- 要在DataSource bean上设置的额外属性。请参阅Tomcat Pool文档。还有一个属性的Javadoc格式文档。 -
jmxExport
- 如果false
,将禁用所有DataSource的JMX MBean注册。默认情况下,jmxEnabled = true
为属性中的DataSource添加JMX MBean 。
MySQL的典型配置application.groovy
可能是这样的:
dataSource {
pooled = true
dbCreate = "update"
url = "jdbc:mysql://localhost:3306/my_database"
driverClassName = "com.mysql.jdbc.Driver"
dialect = org.hibernate.dialect.MySQL5InnoDBDialect
username = "username"
password = "password"
properties {
jmxEnabled = true
initialSize = 5
maxActive = 50
minIdle = 5
maxIdle = 25
maxWait = 10000
maxAge = 10 * 60000
timeBetweenEvictionRunsMillis = 5000
minEvictableIdleTimeMillis = 60000
validationQuery = "SELECT 1"
validationQueryTimeout = 3
validationInterval = 15000
testOnBorrow = true
testWhileIdle = true
testOnReturn = false
jdbcInterceptors = "ConnectionState;StatementCache(max=200)"
defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED
}
}
注意:配置DataSource时,在任何配置设置之前不要包含type或def关键字,因为Groovy会将这些视为局部变量定义,并且不会对它们进行处理。例如,以下内容无效:
dataSource {
boolean pooled = true // type declaration results in ignored local variable
...
}
有关dbCreate的更多信息
Hibernate可以自动创建域模型所需的数据库表。您可以通过dbCreate
属性控制何时以及如何执行此操作,该属性可以采用以下值:
-
create - 删除现有模式并在启动时创建模式,首先删除现有表,索引等。
-
create-drop - 与create相同,但在应用程序干净地关闭时也会删除表。
-
update - 创建缺少的表和索引,并在不删除任何表或数据的情况下更新当前架构。请注意,这无法正确处理许多架构更改,例如列重命名(您将使用包含现有数据的旧列)。
-
validate - 不对数据库进行任何更改。将配置与现有数据库架构进行比较并报告警告。
-
任何其他价值 - 什么都不做
dbCreate
一旦架构相对稳定,并且在应用程序和数据库部署到生产环境中时,建议将设置设置为“none”。然后数据库变更管理通过适当的迁移,无论是使用SQL脚本或类似迁移工具迁飞或Liquibase。该数据库迁移插件使用Liquibase。
数据源和环境
前面的示例配置假定您希望所有环境都具有相同的配置:生产,测试,开发等。
然而,Grails的DataSource定义是“环境感知的”,所以你可以这样做:
dataSource {
pooled = true
driverClassName = "com.mysql.jdbc.Driver"
dialect = org.hibernate.dialect.MySQL5InnoDBDialect
// other common settings here
}
environments {
production {
dataSource {
url = "jdbc:mysql://liveip.com/liveDb"
// other environment-specific settings here
}
}
}
自动数据库迁移
定义的dbCreate
属性DataSource
很重要,因为它规定了Grails在运行时应该如何从GORM类自动生成数据库表。DataSource部分中描述了这些选项:
-
create
-
create-drop
-
update
-
validate
-
没有价值
在开发模式下dbCreate
,默认情况下设置为“create-drop”,但在开发中的某个时刻(当然,一旦进入生产阶段),每次启动服务器时都需要停止删除并重新创建数据库。
很容易切换到update
保留现有数据,只在代码更改时更新架构,但Hibernate的更新支持非常保守。它不会进行任何可能导致数据丢失的更改,也不会检测重命名的列或表,因此您将留下旧的并且还将使用新的。
Grails通过插件支持Liquibase或Flyway的迁移。
事务感知数据源代理
实际的dataSource
bean包装在一个事务感知代理中,因此您将获得当前事务或Hibernate使用的连接(Session
如果一个处于活动状态)。
如果不是这种情况,那么从中检索连接dataSource
将是一个新连接,并且您将无法看到尚未提交的更改(假设您具有合理的事务隔离设置,例如READ_COMMITTED
或更好) 。
dataSource
如果您需要访问它,仍然可以使用“真正的”未经授权的; 它的豆名是dataSourceUnproxied
。
你可以像任何其他Spring bean一样访问这个bean,即使用依赖注入:
class MyService {
def dataSourceUnproxied
...
}
或者从以下方面拉出来ApplicationContext
:
def dataSourceUnproxied = ctx.dataSourceUnproxied
数据库控制台
该H2数据库控制台是H2提供了一个基于Web的界面,你有一个JDBC驱动程序的数据库的一个方便的功能,这是非常有用的,查看您所正在对开发数据库。在针对内存数据库运行时,它尤其有用。
您可以通过在浏览器中导航到http:// localhost:8080 / dbconsole来访问控制台。可以使用grails.dbconsole.urlRoot
属性in 配置URI application.groovy
,默认为'/dbconsole'
。
默认情况下,控制台在开发模式下处于启用状态,可以通过使用grails.dbconsole.enabled
属性在其他环境中禁用或启用控制台application.groovy
。例如,您可以在生产中启用控制台,如下所示:
environments {
production {
grails.serverURL = "http://www.changeme.com"
grails.dbconsole.enabled = true
grails.dbconsole.urlRoot = '/admin/dbconsole'
}
development {
grails.serverURL = "http://localhost:8080/${appName}"
}
test {
grails.serverURL = "http://localhost:8080/${appName}"
}
}