在 Hibernate 5.1 中通过自定义 SQL 查询定义实体
Define an entity via a custom SQL query in Hibernate 5.1
我正在使用非标准化的第 3 方数据库,这意味着我无法更改架构。我正在尝试使用 Hibernate 5.1
将 table 映射到 JPA 实体
有2个简单的tables A和B:
| A_ID(pk) | | B_ID(pk) |
------------- -------------
| 1 | | 1 |
------------- | 2 |
-------------
Table C 有复合主键并且与 Table A:
有多对一关系
| A_ID(pk&fk) | QUANTITY(pk) | VALID_FROM(pk) |
---------------------------------------------------
| 1 | 1 | 2017-05-21 |
| 1 | 1 | 2018-01-01 |
| 1 | 2 | 2017-05-21 |
Table D 有复合主键:
| A_ID(pk&fk) | QUANTITY(pk) | VALID_FROM(pk) | B_ID(pk&fk) |
--------------------------------------------------------------------
| 1 | 1 | 2018-01-21 | 1 |
| 1 | 2 | 2018-01-21 | 1 |
| 1 | 2 | 2018-05-01 | 2 |
VALID_FROM 列不是 table 之间的连接条件的一部分,可以占用任何值。
我正在尝试建立 Table C 和 D 之间的关系,但由于 VALID_FORM 主键组件,它们无法使用多对一建模。而且由于没有连接 table 它们也不能用多对多建模。
最好的解决方案是创建一个像
这样的视图
CREATE VIEW C_NORM AS
SELECT DISTINCT A_ID, QUANTITY
FROM TABLE_C;
这将产生视图 C_NORM:
| A_ID(pk&fk) | QUANTITY(pk) |
----------------------------------
| 1 | 1 |
| 1 | 2 |
在此视图上创建 C_NORM 实体可能
- 与 Table C
的一对多关系
- 和另一个与 Table D
的一对多关系
但我无法更改架构,因此无法创建新视图。
是否有任何方法可以将实体定义为 class 并带有基本上基于本机 SQL 查询而不是视图或 table 的注释在数据库中?
不,那不可能,也没有意义。
实体用于更新、插入和删除。如果您不想执行任何这些操作,则不应使用实体。
您可以使用 @SqlResultSetMapping 将本机查询的结果映射到 class
Query q = em.createNativeQuery(
"SELECT c.id, c.name, COUNT(o) as orderCount, AVG(o.price) AS avgOrder " +
"FROM Customer c " +
"JOIN Orders o ON o.cid = c.id " +
"GROUP BY c.id, c.name",
"CustomerDetailsResult");
@SqlResultSetMapping(name="CustomerDetailsResult",
classes={
@ConstructorResult(targetClass=com.acme.CustomerDetails.class,
columns={
@ColumnResult(name="id"),
@ColumnResult(name="name"),
@ColumnResult(name="orderCount"),
@ColumnResult(name="avgOrder", type=Double.class)})
})
或者使用 QLRM:https://github.com/simasch/qlrm
我正在使用非标准化的第 3 方数据库,这意味着我无法更改架构。我正在尝试使用 Hibernate 5.1
将 table 映射到 JPA 实体有2个简单的tables A和B:
| A_ID(pk) | | B_ID(pk) |
------------- -------------
| 1 | | 1 |
------------- | 2 |
-------------
Table C 有复合主键并且与 Table A:
有多对一关系| A_ID(pk&fk) | QUANTITY(pk) | VALID_FROM(pk) |
---------------------------------------------------
| 1 | 1 | 2017-05-21 |
| 1 | 1 | 2018-01-01 |
| 1 | 2 | 2017-05-21 |
Table D 有复合主键:
| A_ID(pk&fk) | QUANTITY(pk) | VALID_FROM(pk) | B_ID(pk&fk) |
--------------------------------------------------------------------
| 1 | 1 | 2018-01-21 | 1 |
| 1 | 2 | 2018-01-21 | 1 |
| 1 | 2 | 2018-05-01 | 2 |
VALID_FROM 列不是 table 之间的连接条件的一部分,可以占用任何值。
我正在尝试建立 Table C 和 D 之间的关系,但由于 VALID_FORM 主键组件,它们无法使用多对一建模。而且由于没有连接 table 它们也不能用多对多建模。
最好的解决方案是创建一个像
这样的视图CREATE VIEW C_NORM AS
SELECT DISTINCT A_ID, QUANTITY
FROM TABLE_C;
这将产生视图 C_NORM:
| A_ID(pk&fk) | QUANTITY(pk) |
----------------------------------
| 1 | 1 |
| 1 | 2 |
在此视图上创建 C_NORM 实体可能
- 与 Table C 的一对多关系
- 和另一个与 Table D 的一对多关系
但我无法更改架构,因此无法创建新视图。
是否有任何方法可以将实体定义为 class 并带有基本上基于本机 SQL 查询而不是视图或 table 的注释在数据库中?
不,那不可能,也没有意义。
实体用于更新、插入和删除。如果您不想执行任何这些操作,则不应使用实体。
您可以使用 @SqlResultSetMapping 将本机查询的结果映射到 class
Query q = em.createNativeQuery(
"SELECT c.id, c.name, COUNT(o) as orderCount, AVG(o.price) AS avgOrder " +
"FROM Customer c " +
"JOIN Orders o ON o.cid = c.id " +
"GROUP BY c.id, c.name",
"CustomerDetailsResult");
@SqlResultSetMapping(name="CustomerDetailsResult",
classes={
@ConstructorResult(targetClass=com.acme.CustomerDetails.class,
columns={
@ColumnResult(name="id"),
@ColumnResult(name="name"),
@ColumnResult(name="orderCount"),
@ColumnResult(name="avgOrder", type=Double.class)})
})
或者使用 QLRM:https://github.com/simasch/qlrm