当前位置: 首页 > 知识库问答 >
问题:

Hibernate从其他表中获取列的值

庄宇
2023-03-14

我有一个名为Trade的实体,它可以映射到包含属性的表。这个实体也有一个字段,存储来自另一个表的值。我的贸易表包含第二个表的主键。我知道如何获得整个第二个表作为实体在我的贸易实体,但我只想要1列。

@Entity
@Immutable
@Table(name = "Trade table")
@SecondaryTables(value = {
    @SecondaryTable(name = "2nd table", pkJoinColumns = @PrimaryKeyJoinColumn(referencedColumnName = "id", foreignKey = @ForeignKey(name = "2ndtableID"))),
    @SecondaryTable(name = "3rd table", pkJoinColumns = @PrimaryKeyJoinColumn(referencedColumnName = "id", foreignKey = @ForeignKey(name = "3rdtableID"))) })
public class TradeSearchResult {
    @Id
    @Column(name = "ID")
    private Long primaryKey;
    @Column(name = "col2", table = "2nd table")
    private String valuefrom2ndtable;
    @Column(name = "col3", table = "3rd table")
    private String valuefrom3ndtable;
}

如你所见,我尝试了@二级表,但是连接是在贸易实体的主密钥上执行的。我如何使用注释从贸易表中选择外键,将其连接到第二/第三表,并直接只从col2/col3中获取值?任何建议都很感激

餐桌贸易:

ID    col1   fk1    fk2
------------------------
1     abc    12     43      
2     def    23     32
3     ghi    34     21

表2:

ID    col2
----------
12    a
23    b
34    c

表3:

ID    col3
-----------
43    d
32    e
21    f

现在,我的交易类应该具有以下属性:

Long id;
String col1;
String col2;
String col3;

hibernate查询:from Trade在本例中应该为我提供3个具有以下属性的交易:

Trade1: 1, "abc","a","d"
Trade2: 2, "def","b","e"
Trade3: 3, "ghi","c","f"

我不想创建一个实体,只是为了达到属性col2col3

编辑:

选择语句看起来像这样:

select trade.ID,TICKET,table2.col2,table3.col2 from trade join table 3 on table3.ID=trade.FKtable3 join table2 on table2.ID=trade.FKtable2

如果我在sql server中执行此语句,它将给出我想要的结果。我想映射我的类,以便hibernate生成这个语句。

共有3个答案

幸乐湛
2023-03-14

我解决这个问题的方法是不将TradeSearchResult映射到任何表,而是使用Criteria/CriteriaQueryAPI来获取我需要的数据。我的Trade类完美地映射到Trad-Table并保存对其他表的对象的引用。现在介绍如何构建查询:

CriteriaBuilder cb = emf.getCriteriaBuilder();
CriteriaQuery<TradeSearchResult> query = cb.createQuery(TradeSearchResult.class); //type is the entity you want to map to
Root<Trade> r = query.from(Trade.class); //root must be entity from which you can access all data

List<Predicate> predicates = new ArrayList<Predicate>(); //new list of predicates

predicates.add(cb.like(r.join("2ndTableEntityName").<String>get("valuefrom2ndtable"),"value to search for")); 
//get the needed value from 2nd table and map it to the field

query.multiselect(r.get("2ndTableEntityName")).where(predicates.toArray(new Predicate[] {}));
//create the query and execute it
EntityManager em = emf.createEntityManager();
List<TradeSearchResult> results = em.createQuery(query).getResultList();
em.close();
return results; //return results

此代码返回TradeSearchResult实体的列表,其中只有所需的字段,而不是来自其他类的整个对象

宋华灿
2023-03-14

基于javadoc示例,您应该使用pkJoinColumnforeignKey来定义用于连接表的列。

//编辑:

在你的版本之后,我试着创造一些魔力:

@Entity
@Immutable
@Table(name = "\"Trade table\"")
@SecondaryTables(value = {
        @SecondaryTable(name = "2nd table", pkJoinColumns = @PrimaryKeyJoinColumn(name = "col2", referencedColumnName = "id")),
        @SecondaryTable(name = "3rd table", pkJoinColumns = @PrimaryKeyJoinColumn(name = "col3", referencedColumnName = "id"))
})
public class Trade {

    @Id
    @Column(name = "id")
    private Long primaryKey;

    @Column(name = "col2")
    private String valuefrom2ndtable;

    @Column(name = "col3")
    private String valuefrom3ndtable;


}

@Entity
@Table(name = "\"2nd table\"")
public class Table2 {

    @Id
    private long id;
}

@Entity
@Table(name = "\"3rd table\"")
public class Table3 {

    @Id
    private long id;
}

我得到的SQL是:

create table "2nd table" (
  id bigint not null,
  col2 bigint not null,
  primary key (col2)
);

create table "3rd table" (
  id bigint not null,
  col3 bigint not null,
  primary key (col3)
);

create table "trade table" (
  id bigint not null,
  col2 varchar(255),
  col3 varchar(255),
  primary key (id)
);

alter table "3rd table"
  add constraint FK7tkn132p8joplte47ce169h82
foreign key (col3)
references "trade table";

alter table "2nd table"
  add constraint FK9jsoykrvn4d0v4aor03g1l324
foreign key (col2)
references "trade table";

这看起来像是你想做的事,但我不是100%确定...

董昕
2023-03-14

我不明白你为什么要这么做?如果你的Trade类中有映射实体,你可以随时访问它的属性,但我会尝试提供一个解决方案来回答你的问题。

你可以这样做,但是你应该在两个实体之间使用一个OneToMany映射(所以你也应该存储整个映射的实体),并且使用这个表中的FK作为实体中的一个属性,并像这样映射它:

@JoinColumn(name="2ndtableID")
@ManyToOne(targetEntity=SecondTable.class,fetch=FetchType.LAZY)
private Message message; 

@Column(name="2ndtableID")
private Long secondTableID;
 类似资料:
  • 我正在尝试使用Java8流来组合列表。如何从两个现有列表中获得“对称差异列表”(只存在于一个列表中的所有对象)。我知道如何获取intersect列表,也知道如何获取union列表。 示例代码:

  • 我如何通过我自己的API从另一个API获取PDF,然后到前面供用户下载。 我现在得到的只是一张空白页。 后面是Scala的,当我打印文件时,我得到一个字符串。

  • 问题内容: 我将解释我在示例中需要做的事情。首先,我们有一个像这样的简单表,名为 table : 现在查询: 将使我们得到与这一结果相似的结果: 但是是否有可能收集 name的 所有值来得到这样的结果? 问题答案: 使用MySQL可以使用GROUP_CONCAT(expr) 此函数返回一个字符串结果,其中包含来自组的串联的非NULL值。如果没有非NULL值,则返回NULL。完整语法如下: 就像是

  • 当然,这些列表有setter和getter。现在我想实现以用户身份不参加这些事件的可能性。因此,我尝试了以下方法: 我得到的例外情况如下: 尽管我使用了一些方法来确保执行惰性提取:

  • 我有以下三个实体: 父: 孩子: 孙子: 当我调用,我会得到一个带着孩子和孙子孙女的父母。然而,这将导致两个问题: > 无限递归因为所有实体都包含对彼此的引用。 来自Hibernate的不必要的查询,因为我的只包含

  • 我正在使用hibernate 4和Spring 3。 我有5个表,每个表映射一个实体类。现在,如果我必须从1个表中选择列,我将执行以下操作: 此结果中的此值将为EmployeeEntity类型。 或者我也可以使用标准。 现在我的要求是我必须从所有5个表中得到结果。每个表中有1-2列。 早些时候,它是一个1表,所以我得到了一个实体,现在我得到了5个表的结果,所以如何在实体中映射它。 List res