Comment accéder à deux bases de données dans Grails
-
09-06-2019 - |
Question
Grails facilite la configuration des sources de données pour différents environnements (développement, test, production) dans son fichier DataSources.groovy, mais il ne semble pas y avoir de possibilité de configurer plusieurs sources de données dans un seul environnement.Que faire si j'ai besoin d'accéder à plusieurs bases de données depuis la même application Grails ?
La solution 3
Il existe désormais un plugin Grails qui permet d'utiliser plusieurs sources de données directement avec la couche GORM de Grails :http://burtbeckwith.com/blog/?p=70
Autres conseils
La connexion de différentes bases de données dans différentes classes de domaine est très simple dans Grails 2.x.x.
Par exemple
development {
dataSource {//DEFAULT data source
.
.
}
dataSource_admin { //Convention is dataSource_name
url = "//db url"
driverClassName = "oracle.jdbc.driver.OracleDriver"
username = "test"
password = 'test123'
}
dataSource_users {
}
}
Vous pouvez utiliser n'importe quelle source de données dans vos classes de domaine en
class Role{
static mapping = {
datasource 'users'
}
}
class Product{
static mapping = {
datasource 'admin'
}
}
Si vous utilisez Grails 2.0 ou supérieur, le plugin n'est pas nécessaire, il est pris en charge nativement.
http://www.grails.org/doc/latest/guide/single.html#multipleDatasources
Grails 2.0 peut gérer plusieurs sources de données sans plugin :
Exemple avec une source de données différente pour les environnements dev(h2 dataSource) et test(mysql dataSource_mysql) :
DataSource.groovy :
dataSource {
pooled = true
driverClassName = "org.h2.Driver"
username = "sa"
password = ""
}
dataSource_mysql {
dialect = org.hibernate.dialect.MySQLInnoDBDialect
driverClassName = 'com.mysql.jdbc.Driver'
username = "user"
password = "pass"
url = "jdbc:mysql://mysqldb.com/DBNAME"
}
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = false
cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
}
// environment specific settings
environments {
development {
dataSource {
configClass = HibernateFilterDomainConfiguration.class
dbCreate = "update" // one of 'create', 'create-drop', 'update', 'validate', ''
url = "jdbc:h2:file:../devDb;MVCC=TRUE"
sqlLogging = true
}
}
test {
dataSource_mysql {
configClass = HibernateFilterDomainConfiguration.class
dbCreate = "create" // one of 'create', 'create-drop', 'update', 'validate', ''
sqlLogging = true
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
pooled = true
properties {
maxActive = -1
minEvictableIdleTimeMillis=1800000
timeBetweenEvictionRunsMillis=1800000
numTestsPerEvictionRun=3
testOnBorrow=true
testWhileIdle=true
testOnReturn=true
validationQuery="SELECT 1"
}
}
}
}
Veux-tu vraiment faire ça ?D'après mon expérience, le scénario habituel ici est le suivant :
- Une application gère ses propres données dans son propre schéma de base de données
- Souvent, l'application nécessitera des données provenant d'autres sources (par exemple, pour que les données de référence ne soient pas copiées et collées)
J'ai normalement toujours eu le luxe de disposer de tous les schémas résidant sur une seule instance de base de données.Donc ma candidature :
- n'a qu'une seule connexion à la base de données - qui concerne le schéma qu'il possède et dispose d'un accès en lecture/écriture
- les autres applications "exportent" leurs données via des vues
- mon application a un accès en lecture à ces vues et possède un synonyme pour cette vue, la faisant apparaître locale
La raison derrière l'utilisation des vues est que l'application qui expose les données
- sait explicitement qu'il est exporté et ce qui est exporté
- n'expose pas la structure interne du schéma (donc si la structure interne change, tant que la vue est correcte, les applications consommatrices ne le savent pas)
Je n'ai pas eu à faire cela avec une application Grails, mais l'approche devrait fonctionner.
Une autre approche du partage de données entre applications consiste à créer un service Web pour exposer les données.Grails rend cela facile.
J'espère que cela aide, mais cette approche peut ne pas être applicable à toutes les situations.
Le post suivant semble être la meilleure source d'informations sur le sujet :
Comment obtenir multi-dataSource dans Grails
Cela se résume à :
- Définir datasource1 dans DevelopmentDataSource
- Définir datasource2 dans resources.xml
- Écrivez un DAO pour CRUD des objets de domaine à l'aide de datasource2
- Dans hibernate.cfg.xml, répertoriez tous les objets de domaine.
Seule la première source de données disposera de méthodes de recherche dynamique.
Si vous recherchez une requête très simple et que cela ne vous dérange pas de ne pas avoir les fonctionnalités ORM, vous pouvez utiliser Groovy SQL ou les fonctionnalités SQL natives d'Hibernate.