使用Hibernate从Map中的表中加载数据作为列名称Vs Value

时间:2013-05-13 10:21:02

标签: hibernate hql hibernate-mapping hibernate-generic-dao

我一直在使用Hibernate一段时间,而这次我试图在这里做一些非传统的事情。甚至不确定它是否可能。

我想要做的是从Single表中加载数据,其中很少有这些列将为它们定义为休息(几乎大约20并且可以随时间增加)所有整数的字段,我想加载它们一张地图。这样,列的名称成为键,数据成为其值。

我正在使用Hibernate 4.1.4并使用Annotations将Fields映射到列。

进一步澄清: 表定义:

CREATE TABLE TempTable
(
 id SERIAL,
 revId TEXT,
 type INTEGER,
 group INTEGER,

 col_1 INTEGER,
 col_2 INTEGER,
 col_3 INTEGER,
 col_4 INTEGER,
 col_5 INTEGER,
 col_6 INTEGER,
 col_7 INTEGER,
 col_8 INTEGER,
 col_9 INTEGER
}

DAO模型看起来像

@Entity
@Table(name = "TempTable")
public class StatsModel {
    private Long entryId;
    private String revId;

    private Integer type;
    private Integer group;

    private Map<String, Integer> metrics; // Map in which I want columns col_1 to col_9 as "Column Name" Vs. "Value"

    @Id
    @Column(name = "id", columnDefinition = "serial")
    @Generated(GenerationTime.INSERT)
    public Long getEntryId() {
        return entryId;
    }

    public void setEntryId(Long entryId) {
        this.entryId = entryId;
    }

    @Column(name = "tx_rev")
    public String getRevId() {
        return revId;
    }

    public void setRevId(String revId) {
        this.revId= revId;
    }

    @Column(name = "nu_type")
    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    @Column(name = "nu_group")
    public Integer getGroup() {
        return group;
    }

    public void setGroup(Integer group) {
        this.group = group;
    }
}

2 个答案:

答案 0 :(得分:0)

可以使用剩余列的视图来“旋转”列。然后映射此视图,例如这样创建的视图(注意甚至可以通过读取数据库的数据字典来动态创建视图的DDL,但这是另一个问题!)

create or replace view TempTable_metrics as
select t.id,
       pv.name as key,
       case
          when pv.name = 'COL1' then t.col1
          when pv.name = 'COL2' then t.col2
          when pv.name = 'COL3' then t.col3
       end as value
from   temp_table t,
       (
       select 'COL1' as name from dual union all
       select 'COL2' as name from dual union all
       select 'COL3' as name from dual
       ) pv

编辑:(添加如何做hibernate部分) 忘了提一下,在java方面你需要你的地图注释这些注释:

@CollectionTable(name="TempTable_metrics", joinColumns=@JoinColumn(name="id"))
@MapKeyColumn(name="key", nullable=false)
@Column(name="value")
Map<String,Integer> metrics;

刚才意识到,为了做更新,你需要在你的数据库中使用一些凌乱的“而不是”触发器(我已经用甲骨文做了这个,但在其他地方用YMMV)。

答案 1 :(得分:0)

您可以将数据作为更改查询的地图加载,这是hibernate doc示例:

select 
    new map(
        max(bodyWeight) as max,
        min(bodyWeight) as min, count(*) as n 
    ) 
from Cat cat

http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-select