2014-01-19 2 views
0

Я бы хотел добавить вторую временную БД (файловую H2) в наше приложение Play 2.1. Но не могу понять, как и где создать схему Squeryl для второго БД.Как определить схемы Squeryl для двух разных db в Play

Первая схема уже определена в классе scala, который расширяет org.squeryl.Schema. Где я должен помещать определения таблиц для второй БД?

Спасибо за любые подсказки.

+0

По копаться, я нашел подсказку в группе Squeryl Google: https://groups.google.com/forum/#!topic/squeryl/kdUmp1-hOmA - Я думаю, мне нужно для создания другого класса Schema и переопределения атрибута Schema.name. Все еще не уверен, как сказать Squeryl, какую схему использовать для чего DB – alboko

ответ

1

Я не использовал Play, так что вы, возможно, потребуется настроить это вокруг немного, чтобы заставить его работать, но вы должны быть в состоянии создать новую сессию для этой базы данных, что-то вроде:

object MySecondDBSchema extends SquerylSchema with SchemaDefaults { 
    def newSession[A](f: => A) = { 
    transaction(new org.squeryl.Session(//get java.sql.Connection, new H2Adapter)) { 
     f 
    } 
    } 

    val myTable = table[MyTable] 
} 

или, если вы просто хотите подключиться и планируете самостоятельно заниматься транзакциями.

def newSession[A](f: => A) = { 
    using(new org.squeryl.Session(//get java.sql.Connection, new H2Adapter)) { 
    //start your own transaction 
    f 
    } 
} 

Затем в коде, когда вы хотите получить доступ к этим другой базе данных вы можете обернуть ваши запросы в том, что:

def myMethodToAccessFirstDB() = { 
    import MySecondDBSchema._ 

    newSession{ 
    //access alternate database 
    from(myTable)(t => select(t)).toList 
    } 
} 

def myMethodToAccessDefaultDB() = { 
    import DefaultSchema._ //Or whatever your default Schema is named 

    //access default database 
    from(otherTable)(ot => select(ot)) 
} 

Логично определить и организовать таблицы во втором объекте, который расширяет org.squeryl.Schema, но любой запрос, сделанный в блоке newSession, будет выполнен против второй базы данных.

Что касается переопределения атрибута name, это изменит значение по умолчанию schema in the database, но не обязательно для создания отдельной схемы Squeryl.

+0

@jcem - спасибо. Мой вопрос состоял в том, чтобы создать вторую схему и привязать эту схему ко второй БД, а не о сеансах. Я как-то понял часть сеанса. В любом случае, является ли хорошей практикой создание нового сеанса для каждого запроса H2? Должен ли я лучше кэшировать его где-нибудь (например, в Play Cache)? – alboko

+0

Извините, я, возможно, понял. Вы хотите создать вторую схему существующей базы данных, например: 'db.schema1.tablename' и' db.schema2.tablename', или вы хотите использовать вторую отдельную базу данных вместе с существующей? Если последнее, то то, что я разместил, будет применяться. Если первое, то вы были на правильном пути - вы просто импортируете как Squeryl Schema, так и запрос к своим определениям таблиц (просто следите за конфликтами пространства имен). Вопрос, казалось, касался двух отдельных БД, поэтому я ответил так, как я это сделал. – jcern

+0

@jcem: последняя - отдельная база данных вместе с существующей. Вторая база данных должна иметь совершенно другую схему. И я до сих пор не понимаю, как сказать Squeryl использовать другой класс «Schema» для второй БД. – alboko

0

В дополнение к ответу jcern: не забудьте закрыть соединение. Мой вариант:

object MySecondDBSchema extends Schema { 

    var ds : DataSource = _ 

    def newSession[A](f: => A) = { 
    var conn: Option[Connection] = None 
    try { 
     conn = Some(ds.getConnection) 
     val proxyConn = conn.map { 
     case a : ArraySupportProxyConnection => a 
     case c : C3P0ProxyConnection => new ArraySupportProxyConnection(c) 
     }.get 
     using[A](new org.squeryl.Session(proxyConn, new AwesomePostgreSqlAdapter)) { 
     inTransaction { 
      f 
     } 
     } 
    } 
    finally { 
     conn.foreach(_.close()) 
    } 
    } 

    ... 
} 
Смежные вопросы