有人可以帮我弄清楚如何在grails中创建简单的一对一映射的域类!
假设我们有2个表(oracle):
create table table_a(long_common_id_name number(5) primary key using index,
notes varchar2(10 byte),
update_seq number(3)not null );
create table table_b (long_common_id_name number(5) primary key using index,
extra_notes varchar2(200 byte),
update_seq number(3) not null);
alter table table_b add (constraint table_b_fk foreign key (long_common_id_name)
references table_a (long_common_id_name));
我创建了2个域类:
class TableA {
static mapping = {
table 'table_a'
columns {
id column:'LONG_COMMON_ID_NAME'
data column:'NOTES'
version column:'UPDATE_SEQ'
}
}
String data
TableB extraData
}
class TableB {
static mapping = {
table 'table_b'
columns {
id column:'LONG_COMMON_ID_NAME'
data column:'EXTRA_NOTES'
version column:'UPDATE_SEQ'
}
}
String data
}
这个特定的定义是不正确的。 Grails(或Hibernate)为TableA构建了一个不正确的SQL:
select this_.LONG_COMMON_ID_NAME as LONG1_66_0_, this_.UPDATE_SEQ as UPDATE2_66_0_, this_.NOTES as NOTES66_0_, this_.extra_data_id as extra4_66_0_ from table_a this_
我尝试了很多东西:从属,拥有独特的玛尼,但似乎没什么用。
提前致谢。
答案 0 :(得分:1)
回答我自己的问题,也许有人会发现它很有用......
我正在为我们的旧数据库编写一个快速的web-ui,因此我没有编写大量的SQL来回答用户问题,而是希望将其自动化。我无法修改数据结构,通过UI访问将是只读的。
以下是我可以使用的解决方案/解决方法:
域/ TableA.groovy
class TableA {
static mapping = {
table 'table_a'
columns {
id column:'LONG_COMMON_ID_NAME'
data column:'NOTES'
version column:'UPDATE_SEQ'
}
}
// will manually handle persistence of TableB
static transients = [ 'extraData' ]
String data
TableB extraData
}
域/ TableB.groovy
class TableB {
static mapping = {
table 'table_b'
columns {
id column:'LONG_COMMON_ID_NAME'
data column:'EXTRA_NOTES'
version column:'UPDATE_SEQ'
}
//actual id is copied from TableA after it is persisted
id generator:'assigned'
}
static transients = [ "parent" ]
String data
TableA parent
}
“views / tableA / create.gsp”中的表单包含TableA和TableB属性的输入字段,因此我将获取TableA和TableB实例的数据
在“controllers / TableAController.groovy”中我手动更新/删除/加载TableB实例
def list = {
...
def rv = TableA.list( params)
rv.each() { it.extraData = TableB.get(String.valueOf(it.id)) }
...
}
def show = {
....
tableAInstance.extraData = TableB.get(tableAInstance.id)
...
}
def delete = {
...
// delete tableB instance first before tableA
def tb = TableB.get(tableAInstance.id)
if (tb) tb.delete()
tableAInstance.delete()
...
}
def save = {
....
// after tableAInstance.save() call
def tb = new TableB()
tb.data = params.extraData?.data
// copy id from tableA instance
tb.id = tableAInstance.id
tb.save()
.....
}
答案 1 :(得分:0)
你必须以这种方式设置外键吗?我希望在TABLE_A上有一个TABLE_B_ID列。
无论如何,我认为要做你想要的,你需要为extraData的映射闭包添加一行。
我不确定这是否会很好地将它作为主键
e.g。
static mapping = {
extraData column:'LONG_COMMON_ID_NAME'
}
答案 2 :(得分:0)
同意leebuts,Grails将在子表中预期单独的FK ID字段。
此表设置看起来更像是每类表继承。您可以创建一个继承类TableA的类TableB,其中TableA包含Notes,TableB包含“data”。 Grails可能还需要TableB中的一个鉴别器列,但看起来这些表看起来符合Grails惯例的继承。
看看:http://grails.org/GORM+-+Mapping+DSL
寻找关闭每个层次表的方法