Hibernate 从其他 table 获取列的值
Hibernate get value of column from other table
我有一个名为 Trade 的实体,它可以映射到包含属性的 Table。此实体还有一个字段,用于存储另一个 table 的值。我的交易 table 包含第二个 table 的主键。我知道如何将整个第二个 table 作为我的贸易实体中的实体,但我只想要那 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;
}
如您所见,我尝试使用 @SecondaryTables
,但连接是在 Trade 实体的主键上执行的。我如何使用注释来 select 来自交易 table 的外键,将其连接到第二/第三 table 并直接仅从 col2/col3 中获取值?任何建议表示赞赏
Table 贸易:
ID col1 fk1 fk2
------------------------
1 abc 12 43
2 def 23 32
3 ghi 34 21
Table 2:
ID col2
----------
12 a
23 b
34 c
Table 3:
ID col3
-----------
43 d
32 e
21 f
现在我的交易 class 应该具有以下属性:
Long id;
String col1;
String col2;
String col3;
hibernate 查询:from Trade
在这个例子中应该给我 3 Trades 属性:
Trade1: 1, "abc","a","d"
Trade2: 2, "def","b","e"
Trade3: 3, "ghi","c","f"
我不想创建一个实体来访问属性 col2
和 col3
编辑:
select 语句如下所示:
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 服务器上执行这条语句,它会给我想要的结果。我想映射我的 class,以便休眠生成此语句。
基于 javadoc example,您应该使用 pkJoinColumn
和 foreignKey
来定义 列应该用于连接您的表。
// 编辑:
在你的版本之后我试着创造一些魔法:
@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% 确定...
我不明白你为什么要那样做?如果您的 Trade
class 中有映射的实体,您始终可以访问其属性,但我会尝试提供一个解决方案来回答您的问题。
你可以做到,但你应该在两个实体之间使用 OneToMany
映射(因此你也应该存储整个映射的实体),并将此 Table 中的 FK 用作实体中的属性并像这样映射它:
@JoinColumn(name="2ndtableID")
@ManyToOne(targetEntity=SecondTable.class,fetch=FetchType.LAZY)
private Message message;
@Column(name="2ndtableID")
private Long secondTableID;
我解决这个问题的方法是不将 TradeSearchResult
映射到任何 table 并使用 Criteria
/CriteriaQuery
API 来获取我的数据需要。我的 Trade
class 完美映射到 Trade-Table 并持有对其他 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
此代码 returns TradeSearchResult
实体的列表,其中仅包含所需的字段,而不是来自其他 classes
的整个对象
我有一个名为 Trade 的实体,它可以映射到包含属性的 Table。此实体还有一个字段,用于存储另一个 table 的值。我的交易 table 包含第二个 table 的主键。我知道如何将整个第二个 table 作为我的贸易实体中的实体,但我只想要那 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;
}
如您所见,我尝试使用 @SecondaryTables
,但连接是在 Trade 实体的主键上执行的。我如何使用注释来 select 来自交易 table 的外键,将其连接到第二/第三 table 并直接仅从 col2/col3 中获取值?任何建议表示赞赏
Table 贸易:
ID col1 fk1 fk2
------------------------
1 abc 12 43
2 def 23 32
3 ghi 34 21
Table 2:
ID col2
----------
12 a
23 b
34 c
Table 3:
ID col3
-----------
43 d
32 e
21 f
现在我的交易 class 应该具有以下属性:
Long id;
String col1;
String col2;
String col3;
hibernate 查询:from Trade
在这个例子中应该给我 3 Trades 属性:
Trade1: 1, "abc","a","d"
Trade2: 2, "def","b","e"
Trade3: 3, "ghi","c","f"
我不想创建一个实体来访问属性 col2
和 col3
编辑:
select 语句如下所示:
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 服务器上执行这条语句,它会给我想要的结果。我想映射我的 class,以便休眠生成此语句。
基于 javadoc example,您应该使用 pkJoinColumn
和 foreignKey
来定义 列应该用于连接您的表。
// 编辑:
在你的版本之后我试着创造一些魔法:
@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% 确定...
我不明白你为什么要那样做?如果您的 Trade
class 中有映射的实体,您始终可以访问其属性,但我会尝试提供一个解决方案来回答您的问题。
你可以做到,但你应该在两个实体之间使用 OneToMany
映射(因此你也应该存储整个映射的实体),并将此 Table 中的 FK 用作实体中的属性并像这样映射它:
@JoinColumn(name="2ndtableID")
@ManyToOne(targetEntity=SecondTable.class,fetch=FetchType.LAZY)
private Message message;
@Column(name="2ndtableID")
private Long secondTableID;
我解决这个问题的方法是不将 TradeSearchResult
映射到任何 table 并使用 Criteria
/CriteriaQuery
API 来获取我的数据需要。我的 Trade
class 完美映射到 Trade-Table 并持有对其他 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
此代码 returns TradeSearchResult
实体的列表,其中仅包含所需的字段,而不是来自其他 classes