【问题标题】:Relational Mapping between tables in different schema不同模式中表之间的关系映射
【发布时间】:2015-05-14 06:37:30
【问题描述】:

当前应用程序正在处理数据库中的多个架构,因此我们有一个通用架构来存储主表,而其他架构则用于存储客户特定的数据。

所以,具体的场景是这样的

(以下表格仅供参考)

AnimalType 的主表位于 common 架构中,而 Animal 表在所有客户端架构上都可用,例如 schema1schema2...schemaN

我们使用Grails,默认使用Hibernate,所以关系就像

class AnimalType {
   String type

   static mapping = {
     datasources(['index'])
   }
}

class Animal {
   String name
   AniamlType animalType

}

所以,当我启动应用程序时,它会显示以下异常:

引起:org.springframework.beans.factory.BeanCreationException: 创建名为“sessionFactory”的 bean 时出错:调用 init 方法失败;嵌套异常是 org.hibernate.MappingException: An 来自表 animal 的关联指的是未映射的类: org.sample.AnimalType

我从中理解的是,Animal 试图在它自己的架构中引用AnimalType,但AnimalType 在那里不存在。

所以,基本上我想将Animal 映射到AnimalType 指向common 架构。

Grails 中的语法如下所示

class Animal {
   String name

   @(POINTING TO COMMON SCHEMA)
   AnimalType animalType
}

【问题讨论】:

  • 你的意思是你真的为每个客户都有一个架构吗?
  • 是的,根据业务和法律要求,我们为每个客户提供新架构。
  • 我的回答有帮助吗?如果没有,您是否解决了问题?一个被接受的答案将帮助那些稍后搜索问题的人。
  • @Nathan:对不起,Nathan,但这并没有解决我的问题。最后我决定手动只存储引用表的 id 而没有任何外部约束。
  • 这是否导致数据非规范化?

标签: grails grails-orm multi-tenant


【解决方案1】:

在您的mapping 中添加如下内容:

table name: "animal_type", schema: "common"

来自当前docs

【讨论】:

  • 我已经将AnimalType 的架构级别定义为datasources(['index'])。但我想在Animal 中引用“AnimalType”来引用index 数据源,即common
【解决方案2】:

修改后的答案

Hibernate 是数据库之上的一个抽象层。根据您的 @(POINTING TO COMMON SCHEMA) 表示法,您可能来自 Java 背景。使用我们小组下面的基本方法连接到数十个模式和多个数据库。在连接到各种模式时,利用 Grails 域类使用约定优于配置。请参阅mapping tables to domain classes 上的 Grails 文档。让我通过描述示例数据库模式和域类映射来尝试和解释。

希望您通过应用程序用户访问数据库。我们称它为 ANIMAL_APP。 ANIMAL_APP 可以访问以下表格:

  • ANIMAL_TYPE(公共表,所有动物都可以访问)
  • TIGER(仅限老虎使用)
  • SNAKE(仅适用于蛇)
  • BEE(仅限蜜蜂使用)

每个都可以有自己的域类。他们还将拥有自己的控制器,其中可以内置个性化逻辑。蜜蜂会飞,而老虎不会,这可以在单独的控制器动作中进行说明。

AnimalType 域类

class AnimalType{   
    //AnimalType properties  
    static mapping = {
        table 'ANIMAL_TYPE', schema: 'ANIMAL_APP'
        id column: 'id'
    }
}

TIGER DOMAIN CLASS //可以是任何动物

class Tiger{
    Sting name
    String value
    static belongsTo = [animalType:AnimalType]

    static mapping = {
        table 'TIGER', schema: 'ANIMAL_APP'
        //Be aware that you could map to a different schema as follows
        //table TIGER, schema: 'TIGER_SCHEMA'
        id column: 'id'
    }
}

一旦类相互链接,在数据库中管理应该管理的表访问。为模式 ANIMAL_APP 可用于 TIGER、SNAKE 和 BEE 的表创建同义词。为这些表中的每一个授予对 ANIMAL_APP 的正确权限。

配置Config.groovyDataSource.groovy中的数据源

Config.groovy 为每个环境配置 JNDI 数据源。请记住,您正在使用 ANIMAL_APP 映射到数据库。

grails.naming.entries = [
        "jdbc/devanimalapp": [
                type: "javax.sql.DataSource", //required
                auth: "Container", // optional
                description: "Data source for Production", //optional
                driverClassName: "oracle.jdbc.OracleDriver",
                url: "[replace with your databaseDriver]@[jndi location]",
                username: "ANIMAL_APP",
                password: "secret",
        ],
        "jdbc/prodanimalapp": [
                type: "javax.sql.DataSource", //required
                auth: "Container", // optional
                description: "Data source for Production", //optional
                driverClassName: "oracle.jdbc.OracleDriver",
                url: "[replace with your databaseDriver]@[jndi location]",
                username: "ANIMAL_APP",
                password: "secret",
        ]
]

DataSource.groovy 然后配置如下。请记住,这是一个指南,文档可以在 Grails knowledge base 中找到。

environments {
    development {
        dataSource {
            dbCreate = "validate" // one of 'create', 'create-drop', 'update', 'validate', ''
            dialect = "[insert your database dialect]"
            jndiName = "java:comp/env/jdbc/devredapp"
        }
    }

    production {
        dataSource {
            dbCreate = "validate" // one of 'create', 'create-drop', 'update', 'validate', ''
            dialect = "[insert your database dialect]"
            jndiName = "java:comp/env/jdbc/prodanimalapp"
        }
    }
}

以这种方式映射您的域类将允许您利用 Grails 的配置约定并通过仅通过 ANIMAL_APP 模式访问必要的表来确保安全。控制 ANIMAL_APP 架构中的权限和同义词将允许您连接到不同的架构甚至远程数据库。

下面是透明度的原始答案

我不确定我是否正确理解了这个问题,但如果您试图让 Animal 类继承(参见 Grails GORM Inheritence)AnimalType 类,您必须声明 Hibernate 的关系。

class AnimalType{
    //some properties
    static hasMany = [animals:Animal, ...]
}

class Animal{
    String name
    String value
    static belongsTo = [animalType:AnimalType]
}

class Animal extends AnimalType{
    String animalName
}

如果我严重误解了您的问题,请告诉我,我会再试一次。

【讨论】:

  • 是的,您似乎误解了这个问题。我不想在这里实现继承,而是想将 AnimalType 引用到 AnimalType 位于不同架构中而 Animal 位于不同架构中的 Animal。
  • Parth,我已经更新了我的答案。请通读整个答案,如果有帮助,请告诉我。
猜你喜欢
  • 1970-01-01
  • 2012-10-10
  • 1970-01-01
  • 2021-05-23
  • 2017-09-03
  • 2021-09-28
  • 1970-01-01
  • 2011-05-31
  • 1970-01-01
相关资源
最近更新 更多