Java 如何使用Hibernate条件实现这个多重选择和where查询?

Java 如何使用Hibernate条件实现这个多重选择和where查询?,java,mysql,hibernate,hibernate-criteria,Java,Mysql,Hibernate,Hibernate Criteria,我遇到了Hibernate条件查询问题 表DataStatus数据如下所示: |-------------|--------------|--------------|---------------------| | name | info | server | starttime | |-------------|--------------|--------------|---------------------| | B

我遇到了Hibernate条件查询问题

表DataStatus数据如下所示:

|-------------|--------------|--------------|---------------------|
|     name    |     info     |    server    |      starttime      |
|-------------|--------------|--------------|---------------------|
|     Bob     | information1 |     www1     | 2018-02-14 10:32:43 |
|     Alice   | information2 |     www3     | 2018-02-14 17:34:43 |
|     Bob     | information3 |     www2     | 2018-02-14 10:32:43 |
|     Alice   | information4 |     www1     | 2018-02-14 11:25:51 |
|     Alice   | information5 |     www2     | 2018-02-14 08:42:25 |
|     Bob     | information6 |     www3     | 2018-02-14 10:32:43 |
|-------------|--------------|--------------|---------------------|
Criteria criteria = session.CreateCriteria(DataStatus.class);
criteria.add(
    Restrictions.and(
        criteria.add(Restrictions.isNotNull("server")),
        criteria.add(Restrictions.eq("name", "Bob")),
        criteria.add(Restrictions.lt("starttime", ))
    )
);
查询如下所示:

SELECT * FROM DataStatus sts 
WHERE sts.server IS NOT NULL 
AND sts.name = 'Bob' 
AND sts.starttime < (
   SELECT starttime FROM DataStatus 
   WHERE name = 'Alice' AND server = sts.server);
|-------------|--------------|--------------|---------------------|
|     name    |     info     |    server    |      starttime      |
|-------------|--------------|--------------|---------------------|
|     Bob     | information1 |     www1     | 2018-02-14 10:32:43 |
|     Bob     | information6 |     www3     | 2018-02-14 10:32:43 |
|-------------|--------------|--------------|---------------------|
我尝试过以下方法:

|-------------|--------------|--------------|---------------------|
|     name    |     info     |    server    |      starttime      |
|-------------|--------------|--------------|---------------------|
|     Bob     | information1 |     www1     | 2018-02-14 10:32:43 |
|     Alice   | information2 |     www3     | 2018-02-14 17:34:43 |
|     Bob     | information3 |     www2     | 2018-02-14 10:32:43 |
|     Alice   | information4 |     www1     | 2018-02-14 11:25:51 |
|     Alice   | information5 |     www2     | 2018-02-14 08:42:25 |
|     Bob     | information6 |     www3     | 2018-02-14 10:32:43 |
|-------------|--------------|--------------|---------------------|
Criteria criteria = session.CreateCriteria(DataStatus.class);
criteria.add(
    Restrictions.and(
        criteria.add(Restrictions.isNotNull("server")),
        criteria.add(Restrictions.eq("name", "Bob")),
        criteria.add(Restrictions.lt("starttime", ))
    )
);
我不知道如何使用Hibernate条件实现这个嵌套的where和select查询


提前感谢。

我不熟悉Hibernate,但您可以重写查询以避免子选择

   SELECT bob.* /** Only include cols from Bob records */
     FROM DataStatus bob 

          /** Only include rows with a later Alice record on the same server */   
     JOIN DataStatus alice
       ON alice.name = 'Alice'
      AND alice.server = bob.server
      AND alice.starttime > bob.starttime

    WHERE bob.name = 'Bob'
您可能会发现使用Hibernate语法时效果更好

注意:假设每个名称和服务器最多有一条记录。这可以通过名称、服务器上的唯一密钥强制执行


此假设基于以下条件:从原始查询中{bob server row starttime}
   SELECT bob.* /** Only include cols from Bob records */
     FROM DataStatus bob 

          /** Only include rows with a later Alice record on the same server */   
     JOIN DataStatus alice
       ON alice.name = 'Alice'
      AND alice.server = bob.server
      AND alice.starttime > bob.starttime

    WHERE bob.name = 'Bob'
您可能会发现使用Hibernate语法时效果更好

注意:假设每个名称和服务器最多有一条记录。这可以通过名称、服务器上的唯一密钥强制执行


这个假设是基于这样的条件,即从原始查询中{bob server row starttime}
我的建议是继续尝试,多看看Javadocs,在IDE中进行实验。如果放弃,请尝试以下方法,假设您的表是在DataStatus类中建模的:



你们确定sql查询是有效的吗?我怀疑它会返回一个错误,说子查询返回的比一行多或者类似的东西。我很确定sql是正确的。它为我返回了正确的数据。@Almett您的查询只返回1行:Bob information1 www1 2018-02-14 10:32:43。也许你发布的数据不是实际数据。另外,在您的查询中,将“ALice”更改为“ALice”,除非是打字错误或等式不区分大小写。非常抱歉,它是“ALice”而不是“ALice”。我更改了Alicewww3的开始时间,使其比BobWW3的“开始时间”更大。现在它返回与我相同的结果。谢谢您的努力。@JoakimDanielson假设名称为,服务器是唯一的,否则OP就可以了。。可能会有麻烦!你们确定sql查询是有效的吗?我怀疑它会返回一个错误,说子查询返回的比一行多或者类似的东西。我很确定sql是正确的。它为我返回了正确的数据。@Almett您的查询只返回1行:Bob information1 www1 2018-02-14 10:32:43。也许你发布的数据不是实际数据。另外,在您的查询中,将“ALice”更改为“ALice”,除非是打字错误或等式不区分大小写。非常抱歉,它是“ALice”而不是“ALice”。我更改了Alicewww3的开始时间,使其比BobWW3的“开始时间”更大。现在它返回与我相同的结果。谢谢您的努力。@JoakimDanielson假设名称为,服务器是唯一的,否则OP就可以了。。可能会有麻烦!这段代码工作得很好。好极了!好极了!非常感谢。但是它只适用于Hibernate-5.2+。并且createCriteria方法在Hibernate-5.2+中被弃用。如果有一堆标准是用createCriteria编写的,那么应该重构这些标准。不管怎么说,答案很好。这个代码工作得很好。好极了!好极了!非常感谢。但是它只适用于Hibernate-5.2+。并且createCriteria方法在Hibernate-5.2+中被弃用。如果有一堆标准是用createCriteria编写的,那么应该重构这些标准。回答得很好。嗨,亚瑟,谢谢你的努力。是的,它使用Hibernate语法,但我的项目要求使用Hibernate标准。您对这个问题的深入思考看起来非常令人印象深刻,我将尝试用您的提示重新设计SQL。谢谢@阿尔梅特很乐意帮忙!我的意思是,使用Hibernate标准可能会更好。根据我使用PHP框架的经验,连接似乎比子查询更受支持。话虽如此,这只是一个更复杂答案的补充,但内容太丰富了,无法发表评论!嗨,亚瑟,谢谢你的努力。是的,它使用Hibernate语法,但我的项目要求使用Hibernate标准。您对这个问题的深入思考看起来非常令人印象深刻,我将尝试用您的提示重新设计SQL。谢谢@阿尔梅特很乐意帮忙!我的意思是,使用Hibernate标准可能会更好。根据我使用PHP框架的经验,连接似乎比子查询更受支持。话虽如此,这只是一个更复杂答案的补充,但内容太丰富了,无法发表评论!