【问题标题】:How to join 2 entities based on NOT condition如何根据 NOT 条件加入 2 个实体
【发布时间】:2015-09-02 21:15:41
【问题描述】:

我有 2 个表 - 例如 TableA 和 TableB,其中包含本文中定义的一些数据 - How to join results of 2 tables based on not condition

现在我计划为表和实体创建 Hibernate 实体,它们彼此不相关。

现在我想根据我之前提到的帖子中给出的 NOT 条件获得结果。

结果是使用SQL查询:

SELECT id, name, partNumber, Aid, Aname, Apart
FROM TableB AS t
CROSS JOIN (SELECT id AS Aid, name AS Aname, partNumber AS Apart
            FROM TableA AS a
            WHERE NOT EXISTS (SELECT 1
                              FROM TableB AS b
                              WHERE b.partNumber = a.partNumber)) AS c
ORDER BY id   

现在如何为此类场景创建 HQL 查询或条件查询。我已经浏览了 HQL & Criteria 查询的 Hibernate 文档,但我无法理解如何将此 SQL 查询转换为 HQL 和 Criteria 查询。你能帮我解决这个问题吗?

更新 1:

根据 Vlad 给出的答案,我没有得到正确的输出。

这是我写的代码:

List<Object[]> list = session.createQuery(
                "select a, b " + "from TableB b, TableA a "
                        + "where b.partNumber != a.partNumber "
                        + "ORDER BY b.id").list();

        for (Object[] objects : list) {
            for (Object object : objects) {
                System.out.println(object);
            }
        }

我得到以下输出:

A: id=2, name=a2, partNumber=20
B: id=5, name=b1, partNumber=10

A: id=3, name=a3, partNumber=30
B: id=5, name=b1, partNumber=10

A: id=4, name=a4, partNumber=40
B: id=5, name=b1, partNumber=10

A: id=1, name=a1, partNumber=10
B: id=6, name=b2, partNumber=20

A: id=3, name=a3, partNumber=30
B: id=6, name=b2, partNumber=20

A: id=4, name=a4, partNumber=40
B: id=6, name=b2, partNumber=20

A: id=1, name=a1, partNumber=10
B: id=7, name=b3, partNumber=60

A: id=2, name=a2, partNumber=20
B: id=7, name=b3, partNumber=60

A: id=3, name=a3, partNumber=30
B: id=7, name=b3, partNumber=60

A: id=4, name=a4, partNumber=40
B: id=7, name=b3, partNumber=60

A: id=1, name=a1, partNumber=10
B: id=8, name=b4, partNumber=70

A: id=2, name=a2, partNumber=20
B: id=8, name=b4, partNumber=70

A: id=3, name=a3, partNumber=30
B: id=8, name=b4, partNumber=70

A: id=4, name=a4, partNumber=40
B: id=8, name=b4, partNumber=70

从输出中,我得到了 TableA 的记录,其中 id's = 1,2,3,4 & for TableBid's= 5,6,7,8

但所需的输出应该有 TableA 的 ID 为 3&amp;4TableB 的 ID 为 5,6,7,8。详情在我的另一篇文章中给出:How to join results of 2 tables based on not condition

Hibernate 生成的查询是:

Hibernate: 
    /* select
        a,
        b 
    from
        TableB b,
        TableA a 
    where
        b.partNumber != a.partNumber 
    ORDER BY
        b.id */ 

select
    tablea1_.id as id1_0_0_,
    tableb0_.id as id1_1_1_,
    tablea1_.name as name2_0_0_,
    tablea1_.partNumber as partNumber3_0_0_,
    tableb0_.name as name2_1_1_,
    tableb0_.partNumber as partNumber3_1_1_ 
from
    TableB tableb0_ cross 
join
    TableA tablea1_ 
where
    tableb0_.partNumber<>tablea1_.partNumber 
order by
    tableb0_.id

更新 2:

我现在尝试过的代码:

List<Object[]> list = session.createQuery("select b, a "
                + "from TableB b, TableA a "
                + "where not exists ( "
                + "select 1 "
                + "from TableB b1, TableA a1 "
                + "where "
                + "b1.partNumber = a1.partNumber and "
                + "b1.id = b.id and "
                + "a1.id = a.id " 
                + ") "
                + "order by b.id").list();
        for (Object[] objects : list) {
            for (Object object : objects) {
                System.out.println(object);
            }
        }

Hibernate 生成的查询:

Hibernate: 

select
            tableb0_.id as id1_1_0_,
            tablea1_.id as id1_0_1_,
            tableb0_.name as name2_1_0_,
            tableb0_.partNumber as partNumb3_1_0_,
            tablea1_.name as name2_0_1_,
            tablea1_.partNumber as partNumb3_0_1_ 
        from
            TableB tableb0_ cross 
        join
            TableA tablea1_ 
        where
            not (exists (select
                1 
            from
                TableB tableb2_ cross 
            join
                TableA tablea3_ 
            where
                tableb2_.partNumber=tablea3_.partNumber 
                and tableb2_.id=tableb0_.id 
                and tablea3_.id=tablea1_.id)) 
        order by
            tableb0_.id

此查询的输出:

B: id=5, name=b1, partNumber=10
A: id=4, name=a4, partNumber=40
B: id=5, name=b1, partNumber=10
A: id=2, name=a2, partNumber=20
B: id=5, name=b1, partNumber=10
A: id=3, name=a3, partNumber=30
B: id=6, name=b2, partNumber=20
A: id=1, name=a1, partNumber=10
B: id=6, name=b2, partNumber=20
A: id=4, name=a4, partNumber=40
B: id=6, name=b2, partNumber=20
A: id=3, name=a3, partNumber=30
B: id=7, name=b3, partNumber=60
A: id=3, name=a3, partNumber=30
B: id=7, name=b3, partNumber=60
A: id=1, name=a1, partNumber=10
B: id=7, name=b3, partNumber=60
A: id=4, name=a4, partNumber=40
B: id=7, name=b3, partNumber=60
A: id=2, name=a2, partNumber=20
B: id=8, name=b4, partNumber=70
A: id=3, name=a3, partNumber=30
B: id=8, name=b4, partNumber=70
A: id=1, name=a1, partNumber=10
B: id=8, name=b4, partNumber=70
A: id=4, name=a4, partNumber=40
B: id=8, name=b4, partNumber=70
A: id=2, name=a2, partNumber=20

【问题讨论】:

    标签: java sql hibernate orm hql


    【解决方案1】:

    您需要使用 theta 样式的连接:

    select b, a
    from TableB b, TableA a 
    where not exists (
        select 1
        from TableB b1, TableA a1
        where 
            b1.partNumber = a1.partNumber and
            b1.id = b.id and
            a1.id = a.id    
    )   
    order by b.id
    

    或者您也可以使用 SQL 查询来获取实体:

    List result = session.createSQLQuery("SELECT b.*, c.* \n" +
            "FROM TableB b AS t\n" +
            "CROSS JOIN (SELECT id AS Aid, name AS Aname, partNumber AS Apart\n" +
            "            FROM TableA AS a\n" +
            "            WHERE NOT EXISTS (SELECT 1\n" +
            "                              FROM TableB AS b\n" +
            "                              WHERE b.partNumber = a.partNumber)) AS c\n" +
            "ORDER BY b.id ")
            .addEntity("b", B.class)
            .addEntity("a", A.class)
            .list();
    

    【讨论】:

    • 感谢 Vlad 的回答,但该解决方案没有按预期工作。我已经添加了有关我尝试过的内容和得到的输出的更多详细信息,请检查。
    • 这个查询也没有给出预期的输出。我在Update 2 会话中提供了详细信息。
    • 尝试添加不同的。
    • HQL 不支持加入表表达式。您可以使用 2 个查询来模拟本机查询结果。第一个从 B 中选择所有在 A 中没有等价的行。另一个从 A 中选择所有在 B 上没有等价的行。至于文档,您可以使用 Google Hibernate vs SQL。
    • 我指的是“交叉连接(选择..)作为c”。
    猜你喜欢
    • 2019-07-27
    • 2022-01-01
    • 2017-10-06
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 2021-06-23
    • 2015-04-28
    • 2020-07-14
    相关资源
    最近更新 更多