2010-11-11 34 views
6

Tôi đang tạo một ứng dụng trong grails mà nên đọc từ một cơ sở dữ liệu và ghi vào cơ sở dữ liệu khác. Tôi đã tạo datasources.groovy cho yêu cầu này và đã cài đặt plugin datasources. Tuy nhiên, tôi bị mắc kẹt tại cách sử dụng nguồn dữ liệu này khi thực hiện truy vấn sql (chọn * từ ........ v.v.).Sử dụng hai cơ sở dữ liệu cho một ứng dụng trong grails

Ví dụ: Dưới đây là cách tôi chạy truy vấn trong hành động của mình. Tôi đang sử dụng truy vấn được tùy chỉnh và không sử dụng gorm.

EDITED:

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) 
    } 
} 

Trong trường hợp trên, datasources không được đọc và có một giá trị null. Có sẵn mã mẫu nào cho yêu cầu này không.

Tôi có thiếu gì đó ở đây không?

CHỈNH SỬA:

Mục nhập Datasources.groovy của tôi như sau.

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) 
      } 
     } 
    } 
} 

Trả lời

5

Nguồn dữ liệu thứ cấp có sẵn bằng cách sử dụng tiêm phụ thuộc, nhưng tên của chúng được dựa trên tên trong Datasources.groovy. Ví dụ, nếu bạn đã xác định một nguồn dữ liệu có tên là 'foo', sau đó bạn sẽ bơm rằng với 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) 
     ... 
    } 
} 

Lưu ý rằng bạn phải đặt def dataSource_foo như một lĩnh vực tầm cỡ quy mô và không phải bên trong hành động của bạn (hoặc phương pháp) . Điều này đúng cho mỗi lần tiêm phụ thuộc - nếu nó nằm trong một phương thức hoặc một đóng, nó chỉ là một biến phạm vi phương thức.

+0

Có quan điểm của bạn. Đã chỉnh sửa mã của tôi theo đề xuất của bạn. Vui lòng kiểm tra mã đã chỉnh sửa của tôi. Tên nguồn dữ liệu của tôi là ds2. Bây giờ tôi đã xác định nguồn dữ liệu của mình là def dataSource_ds2. Các tùy chọn khác def ds2 Vẫn nhận được cùng một lỗi "Phải chỉ định kết nối không null". Tôi có thiếu gì đó không? – MAlex

+0

Bạn có nghĩ rằng một số vấn đề với cách tôi đã viết dataSource của tôi – MAlex

+0

@ Burt: Cảm ơn sự giúp đỡ của bạn. Câu trả lời này và plugin tuyệt vời của bạn xứng đáng được bỏ phiếu một cách chắc chắn – MAlex

0

Tôi đã làm điều này trong BootStrap của dự án cuối cùng tôi đã làm việc. Chỉ cần nhớ, mã Java hợp lệ cũng là Groovy hợp lệ (chủ yếu), và bạn không phải làm mọi thứ theo "Grails Way". Chỉ cần kết nối với cơ sở dữ liệu "từ" theo cách bạn cảm thấy thoải mái và lưu trữ nội dung trong nguồn dữ liệu Grails thông qua thao tác đối tượng miền Grails. Mã mẫu:

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

Cảm ơn Eric. tôi nhận được quan điểm của bạn. Nhưng yêu cầu nghiêm ngặt nói "Làm điều đó trong GRAILS": ( – MAlex

0

Tôi đã cập nhật dữ liệu của mìnhSource thành tài nguyên sau và hoạt động. Tôi không chắc chắn lý do đằng sau nó là gì.

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

Chỉ cần cập nhật câu trả lời cho câu hỏi này (Tôi vừa nhận được một dự án mới yêu cầu sử dụng hai DBs mysql khác nhau). Tôi đã phải nâng cấp lên grails 2.0 (vâng, tôi đã quá lười biếng nâng cấp từ 1.3.7) kể từ khi nó đã được xây dựng trong hỗ trợ cho nhiều datasources (không cần phải sử dụng các plugin).

Grails 2.0 - multiple datasources

Từ ví dụ này, bạn chỉ cần thiết lập các DBS trong DataSource.groovy nộp

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' 
    } 
} 

Sau đó, trong lớp miền, xác định các nguồn dữ liệu:

class ZipCode { 

    String code 

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

Mã giống hệt nhau không hoạt động đối với tôi (sự khác biệt duy nhất là tôi đang sử dụng postgres) .Tôi chạy dbm-gorm-diff để tạo di chuyển nhưng có không có mã trong quá trình di chuyển để xây dựng bảng.Bạn có thể xác nhận rằng mã này đã hoạt động cho bạn và bạn có thể tạo và chạy các di chuyển không? –

+0

Nó không hoạt động với g đường ray 2.4.4 với các truy vấn tiêu chí, hoạt động với những người tìm kiếm động. với các truy vấn tiêu chí, tôi phải thực hiện nó như Domain.lookup.createCriteria - ngay cả khi tên miền được cấu hình để sử dụng nguồn dữ liệu tra cứu. –

-1

Ví dụ về cách người ta có thể sử dụng nhiều nguồn dữ liệu trong Grails Services với SQL.

Gợi ý: Bạn có thể sử dụng TestServiceWithInjection hoặc TestService. Cả hai đều hoạt động tốt.

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

Tôi tự hỏi tại sao không có ai có đề cập 'C3P0: C3P0: 0.9.1.2' Plugin đây.

Đây là thực hành tốt nhất để thực hiện nhiều cơ sở dữ liệu trong ứng dụng grails

Buildconfig.groovy

compile 'c3p0:c3p0:0.9.1.2' 

nguồn dữ liệu

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 
    } 
} 
Các vấn đề liên quan