2010-11-11 10 views
6

Sto creando un'applicazione in Grails che dovrebbe leggere da un database e scrivere in un altro database. Ho creato datasources.groovy per questo requisito e ho installato il plugin datasources. Tuttavia, sono bloccato su come utilizzare questa origine dati quando si esegue una query sql (selezionare * da ........ ecc. Ecc.).Utilizzo di due database per un'applicazione in grails

Ad es. Di seguito è riportato come eseguo una query nella mia azione. Sto usando query personalizzate e non gorm.

MODIFICATI:

class TuneController { 

    def dataSource_ds2 

    def list = { 

     String nameSql = "select name from emp where id=3345" 
     Sql sql = new Sql(dataSource_ds2) 
     String name = sql.rows(nameSql) 
     println(name) 
    } 
} 

Nel caso di cui sopra, le origini dati non viene letto e ha un valore nullo. Esiste un codice di esempio disponibile per questo requisito.

mi manca qualcosa qui?

EDIT:

entrata mio Datasources.groovy è come sotto.

datasources = { 

    datasource(name:'ds2') { 
     domainClasses([com.Tune]) 
     readOnly(true) 
     driverClassName('oracle.jdbc.driver.OracleDriver') 
     url('jdbc:oracle:thin:@test-ofr.wellmanage.com:1521:OFRS1')   
     username('test') 
     password('test') 
     environments(['development']) 
     dbCreate('do-not-bother') 
     logSql(true) 
     dialect(org.hibernate.dialect.Oracle10gDialect) 
     hibernate { 
      cache { 
       use_second_level_cache(false) 
       use_query_cache(false) 
      } 
     } 
    } 
} 

risposta

5

Le origini dati secondari sono disponibili con l'iniezione di dipendenza, ma i loro nomi si basano sui nomi in Datasources.groovy. Per esempio, se avete definito un DataSource chiamato 'pippo', allora si dovrebbe iniettare che con def dataSource_foo:

class MyController { 

    def dataSource_foo 

    def list = { 
     String nameSql = "select name from emp where id=3345" 
     Sql sql = new Sql(dataSource_foo) 
     def rows = sql.rows(nameSql) 
     ... 
    } 
} 

Si noti che è necessario mettere def dataSource_foo come un campo di classe-scope e non all'interno della vostra azione (o metodo) . Questo è vero per ogni iniezione di dipendenza: se si trova all'interno di un metodo o di una chiusura, è solo una variabile del metodo scope.

+0

Hai ottenuto il tuo punto. Ho modificato il mio codice secondo il tuo suggerimento. Controlla il mio codice modificato. Il mio nome di origine è ds2. Così ora ho definito la mia origine dati come def dataSource_ds2. altre opzioni def ds2 Sempre ottenendo lo stesso errore "Devi specificare una connessione non nulla." Mi manca qualcosa? – MAlex

+0

Pensi che ci sia qualche problema con il modo in cui ho scritto i miei dati Source – MAlex

+0

@ Burt: Grazie per il tuo aiuto. Questa risposta e il tuo fantastico plugin meritano sicuramente un voto – MAlex

0

Ho fatto questo nel BootStrap dell'ultimo progetto su cui ho lavorato. Basta ricordare, il codice Java valido è anche Groovy valido (soprattutto), e non devi fare tutto il "Grails Way". Basta connettersi al database "da" in un modo che si sente a proprio agio e archiviare materiale nell'origine dati Grails tramite la manipolazione degli oggetti del dominio Grails. Esempio di codice:

try { 
    Connection con = DriverManager.getConnection ("jdbc:xxxx", "username", "password") 
    ResultSet resultSet = con.createStatement().executeQuery("SELECT * FROM the_table") 
    while(resultSet.next()) { 
     DomainObject domainObjectInstance = new DomainObject(attributeA: resultSet.getString('attributeA'), attributeB: resultSet.getString('attributeB')) 
     if (!domainObjectInstance.save(flush: true)) { 
      println "Unable to save DomainObject: ${domainObjectInstance.errors}" 
     } 
    } 
} catch (SQLException e) { 
    e.printStackTrace(); 
} 
+0

Grazie Eric. capisco il tuo punto. Ma il requisito dice rigorosamente "Fallo nei GRAIL" :( – MAlex

0

Ho aggiornato la mia origine dati al seguente e ha funzionato. Non sono sicuro di quale sia il ragionamento che sta dietro.

datasources = { 

    datasource(name:'ds2') { 
     domainClasses([com.Tune]) 
     readOnly(true) 
     driverClassName('oracle.jdbc.driver.OracleDriver') 
     url('jdbc:oracle:thin:@test-ofr.tnic.com:1521:OFRS1')   
     username('test') 
     password('test') 
     environments(['development']) 
     dbCreate('do-not-bother') 
     logSql(true) 
     dialect(org.hibernate.dialect.Oracle10gDialect) 
     hibernate { 
      cache { 
       provider_class('net.sf.ehcache.hibernate.EhCacheProvider') 
       use_second_level_cache(true) 
       use_query_cache(true) 
      } 
     } 
    } 
} 
2

solo per aggiornare la risposta per questa domanda (Ho appena ricevuto un nuovo progetto che richiede l'utilizzo di due differenti mysql DB). Ho dovuto eseguire l'aggiornamento a Grails 2.0 (sì, sono stato troppo pigro per l'aggiornamento da 1.3.7) poiché ha integrato il supporto per più origini dati (non è necessario utilizzare il plugin).

Grails 2.0 - multiple datasources

Dal esempio, è sufficiente impostare il DB nel DataSource.groovy presentare

environments { 
development { 
    dataSource { 
     dbCreate = "create-drop" 
     url = "jdbc:h2:mem:devDb" 
    } 
    dataSource_lookup { 
     dialect = org.hibernate.dialect.MySQLInnoDBDialect 
     driverClassName = 'com.mysql.jdbc.Driver' 
     username = 'lookup' 
     password = 'secret' 
     url = 'jdbc:mysql://localhost/lookup' 
     dbCreate = 'update' 
    } 
} 

Poi nella classe di dominio, specificare quale origine dati:

class ZipCode { 

    String code 

    static mapping = { datasource 'lookup' } 
} 
+0

Lo stesso codice esatto non funziona per me. (L'unica differenza è che sto usando Postgres). Ho eseguito dbm-gorm-diff per creare la migrazione ma lì non è un codice nella migrazione per la costruzione della tabella. Puoi confermare che questo codice ha funzionato per te e sei stato in grado di generare ed eseguire le migrazioni ??? –

+0

Non funziona con g rails 2.4.4 con query di criteri, funziona con i finder dinamici. con query di criteri, devo farlo come Domain.lookup.createCriteria - anche se il dominio è configurato per utilizzare l'origine dati di ricerca. –

-1

Esempio di come si possa utilizzare più origini dati in Grails Services con SQL.

Suggerimento: è possibile utilizzare sia TestServiceWithInjection o TestService. Entrambi funzionano bene.

DataSource.groovy

dataSource { 
    pooled = true 
    jmxExport = true 
    driverClassName = "com.mysql.jdbc.Driver" 
    dialect = "org.hibernate.dialect.MySQL5InnoDBDialect" 
} 
hibernate { 
    cache.use_second_level_cache = true 
    cache.use_query_cache = false 
// cache.region.factory_class = 'org.hibernate.cache.SingletonEhCacheRegionFactory' // Hibernate 3 
    cache.region.factory_class = 'org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory' // Hibernate 4 
    singleSession = true // configure OSIV singleSession mode 
    flush.mode = 'manual' // OSIV session flush mode outside of transactional context 
} 

// environment specific settings 
environments { 
    development { 
     dataSource { 
      dbCreate = "update" // one of 'create', 'create-drop', 'update', 'validate', '' 
      url = "jdbc:mysql://localhost:3306/database1" 
      username = "root" 
      password = "password" 
     } 
     dataSource_second { 
      driverClassName = "com.mysql.jdbc.Driver" 
      dialect = "org.hibernate.dialect.MySQL5InnoDBDialect" 
      dbCreate = "update" // one of 'create', 'create-drop', 'update', 'validate', '' 
      url = "jdbc:mysql://localhost:3306/database2" 
      username = "root" 
      password = "password" 
     } 
    } 
    test { 
     dataSource { 
      //Used by local test run (grails test-app) 
      dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', '' 
      url = "jdbc:mysql://test-server.com:3306/test_ci" 
      username = "root" 
      password = "password" 
     } 
    } 
} 

TestServiceWithInjection.groovy

package com.github.biniama 

import grails.transaction.Transactional 
import groovy.sql.Sql 

import javax.annotation.PostConstruct 

@Transactional 
class TestService { 

    def dataSource_second 

    Sql sql 

    @PostConstruct 
    def initSql() { 
     sql = new Sql(dataSource_second) 
    } 

    def getData() { 
     def q = "SELECT id FROM job LIMIT 1" 
     return sql.rows(q) 
    } 
} 

TestService.groovy

package com.github.biniama 

import grails.transaction.Transactional 
import groovy.sql.Sql 

@Transactional 
class TestService { 

private Sql sql 

void setDataSource_second(def dataSource) { 
    sql = new Sql(dataSource) 
} 

Integer getData() { 
    def q = "SELECT id FROM job LIMIT 1" 
    return sql.rows(q) 
} 

}

TestController.groovy

package com.github.biniama 

class TestController { 

    TestService testService 

    def index() { 
    Integer result = testService.getData() 
    render "Returned value is ${result}" 
    } 
} 
0

Mi chiedo perché nessuno ha menzionato 'c3p0: c3p0: 0.9.1.2' plug-in qui.

Si tratta di migliori pratiche per implementare più database in applicazione graal

Buildconfig.groovy

compile 'c3p0:c3p0:0.9.1.2' 

origine dati

dataSource { 
      dialect = 'com.example.hibernateutil.MySQL5InnoDBDialectBitFixed' 
      dbCreate = "update" // one of 'create', 'create-drop', 'update', 'validate', '' 
      driverClassName = "com.mysql.jdbc.Driver" 
      url = "jdbc:mysql://127.0.0.1/demo 
      username = "root" 
      password = "" 
     } 

     dataSource_Demo { 
      dialect = 'com.example.hibernateutil.MySQL5InnoDBDialectBitFixed' 
      dbCreate = "update" // one of 'create', 'create-drop', 'update', 'validate', '' 
      driverClassName = "com.mysql.jdbc.Driver" 
      url = "jdbc:mysql://127.0.0.1/demo2" 
      username = "root" 
      password = "" 
     } 

resources.groovy

beans = { 


    dataSource_Demo(ComboPooledDataSource) { bean -> 
     bean.destroyMethod = 'close' 
     //use grails' datasource configuration for connection user, password, driver and JDBC url 
     user = grailsApplication.config.dataSource_Demo.username 
     password = grailsApplication.config.dataSource_Demo.password 
     driverClass = grailsApplication.config.dataSource_Demo.driverClassName 
     jdbcUrl = grailsApplication.config.dataSource_Demo.url 
     idleConnectionTestPeriod = 2 * 60 * 60 //2 hours 
     testConnectionOnCheckin = true 
    } 

    /** 
    * c3P0 pooled data source that allows 'DB keepalive' queries 
    * to prevent stale/closed DB connections 
    * Still using the JDBC configuration settings from DataSource.groovy 
    * to have easy environment specific setup available 
    */ 
    dataSource(ComboPooledDataSource) { bean -> 
     bean.destroyMethod = 'close' 
     //use grails' datasource configuration for connection user, password, driver and JDBC url 
     user = grailsApplication.config.dataSource.username 
     password = grailsApplication.config.dataSource.password 
     driverClass = grailsApplication.config.dataSource.driverClassName 
     jdbcUrl = grailsApplication.config.dataSource.url 
     idleConnectionTestPeriod = 2 * 60 * 60 //2 hours 
     testConnectionOnCheckin = true 
    } 
} 
Problemi correlati