Grails資料來源配置,自動資料庫遷移,事物感知資料來源
你一定知道!由於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}" } }