java—如何使用hibernate条件实现这个多重选择和where查询?

e0bqpujr  于 2021-06-18  发布在  Mysql
关注(0)|答案(2)|浏览(334)

我遇到了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 |
|-------------|--------------|--------------|---------------------|

查询如下所示:

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 |
|-------------|--------------|--------------|---------------------|

我试过以下方法:

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查询?
提前谢谢。

qij5mzcb

qij5mzcb1#

我的建议是继续尝试,多看看javadocs,在ide中进行实验。如果你放弃了,试试下面的方法(假设你的表是在课堂上建模的) DataStatus ):

CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<DataStatus> criteriaQuery = criteriaBuilder.createQuery(DataStatus.class);
Root<DataStatus> root = criteriaQuery.from(DataStatus.class);

Subquery<Date> subquery = criteriaQuery.subquery(Date.class);
Root<DataStatus> innerRoot = subquery.from(DataStatus.class);

subquery.select(innerRoot.get("startTime"))
        .where(criteriaBuilder.and(criteriaBuilder.equal(innerRoot.get("name"), "Alice"),
                criteriaBuilder.equal(innerRoot.get("server"), root.get("server"))));

criteriaQuery.select(root).where(
        criteriaBuilder.and( criteriaBuilder.isNotNull( root.get( "server" ) ),
                criteriaBuilder.equal(root.get("name"), "Bob" ),
                criteriaBuilder.lessThan(root.<Date> get("startTime"), subquery)

        ) );

Query<DataStatus> query = session.createQuery(criteriaQuery);
List<DataStatus> resultList = query.getResultList();
pgccezyw

pgccezyw2#

我不熟悉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语法会更好
n、 b.假设每个名称和服务器最多有一条记录。这可以由(名称、服务器)上的唯一密钥强制执行
这个假设是基于 WHERE {bob server row starttime} < SELECT {alice server row starttime} 如果select可以返回多行,那么这就没有意义了

相关问题