2013-03-01 69 views
0

为了让我的java代码更简单,我想将两行合并为一个,因为我真的需要这两个才能使用数据。休眠加入2行

比方说,那些都是我的表的字段:

ID, FIELD1, FIELD2, DISCRIMINATOR, VALUE 

显然,ID是主键。 FIELD1和2让我们确定一个仅由DISCRIMINATOR和VALUE区分的2行的“组”(鉴别符指示数值代表的是什么)

我想每个“组”有一个POJO(其中FIELD1和2将被用作复合ID),如:

FIELD1, FIELD2, VALUE1, VALUE2 

其中:

VALUE1 = VALUE用于鉴别器用于鉴别乙

VALUE2 = VALUE

在SQL中,我会要求它像这样:

SELECT a.FIELD1, a.FIELD2, a.VALUE as VALUE1, b.VALUE as VALUE2 
FROM TABLE a, TABLE b 
WHERE a.FIELD1 = b.FIELD1 and a.FIELD2 = b.FIELD2 
    AND a.DISCRIMINATOR = 'A' 
    AND b.DISCRIMINATOR = 'B' 

不幸的是,我不知道如何使它在休眠,我现在一切准备困惑。

我宁愿将解决方案作为映射的XML,但如果没有选择,仍然会采用注解解决方案。

+1

你在考虑表格。 Hibernate是一种ORM解决方案,可让您假装对象是Universe的中心。您应该根据对象来思考,或者将Hibernate用于Spring JdbcTemplate或iBatis等基于SQL的解决方案。 – duffymo 2013-03-01 15:05:56

+0

谢谢,不幸的是,应用程序已经使用hibernate进行了很多处理,我无法控制为db和api所做的选择。尽管我会为未来的作品记住这一点。 – Schumi77 2013-03-01 15:25:12

+0

它不一定是一个全或无解决方案。你不必强迫Hibernate做这一切。为什么不能直SQL在这里工作? – duffymo 2013-03-01 15:37:25

回答

0

如果您非常简单地映射表基于POJO(这里使用注释,但你可以使用XML):

@Entity 
@Table(name = "whatever") 
public class Fields { 

    @Id 
    @Column(name = "ID") 
    private String id; 

    @Column(name = "FIELD1") 
    private String field1; 

    @Column(name = "FIELD2") 
    private String field2; 

    @Column(name = "DISCRIMINATOR") 
    private String discriminator; 

    @Column(name = "VALUE") 
    private String value; 
} 

您可以定义包含两个字段值的独立POJO:

public class FieldValues { 
    private String field1, field2, value1, value2; 

    public FieldValues(String field1, String field2, String value1, String value2) { 
     this.field1 = field1; 
     this.field2 = field2; 
     this.value1 = value1; 
     this.value2 = value2; 
    } 
} 

然后,您可以使用JPQL精确地编写您所概述​​的查询,在EntityManager中执行该查询,并且它仍然会参与所有JPA事务等等。

String sql = "SELECT a.field1, a.field2, a.value as value1, b.value as value2 " 
      + " FROM Fields a, Fields b " 
      + " WHERE a.FIELD1 = b.FIELD1 and a.FIELD2 = b.FIELD2 " 
      + " AND a.DISCRIMINATOR = 'A' " 
      + " AND b.DISCRIMINATOR = 'B'"; 
List<Object[]> result = entityManager.createQuery(sql, Object[].class); 

List<FieldValues> result = new ArrayList<FieldValues>(); 
for (Object[] fieldSet : result) { 
    String field1 = (String) fieldSet[0]; 
    String field2 = (String) fieldSet[1]; 
    String value1 = (String) fieldSet[2]; 
    String value2 = (String) fieldSet[3]; 
    result.add(new FieldValues(field1, field2, value1, value2)); 
} 

我相信您甚至可以休眠映射到FieldValues你,但我不记得如何。它可能就像使用正确的列名注释(或XML映射)FieldValues类一样简单,然后强制Hibernate从查询中返回List<FieldValues>。这种方法的缺点是,您不能对FieldValue进行更改并将其保留到数据库。

另一种方法是使用普通的旧SQL与EntityManager.createNativeQuery。您必须确保在执行此操作之前清空实体管理器;否则任何挂起的更改可能没有写入数据库,因此查询不会看到。再次,我相信你可以在这种情况下让Hibernate映射到FieldValues类。

+0

谢谢。我想我可以使用SQL查询,但在这种情况下,hibernate映射将失去其用途(甚至有创建Fields POJO的用法)。我开始认为,无论是我的表格还是我试图实现的东西都远离冬眠的原始目的。 – Schumi77 2013-03-01 16:21:52