简体   繁体   English

如何实现这种多重选择以及在何处使用Hibernate条件进行查询?

[英]How to implement this multiple select and where query with Hibernate criteria?

I have faced a Hibernate criteria query issues. 我已经遇到了休眠标准查询问题。

Table DataStatus data looks like below: 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 |
|-------------|--------------|--------------|---------------------|

Query looks like this: 查询看起来像这样:

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

And the result looks like this: 结果看起来像这样:

|-------------|--------------|--------------|---------------------|
|     name    |     info     |    server    |      starttime      |
|-------------|--------------|--------------|---------------------|
|     Bob     | information1 |     www1     | 2018-02-14 10:32:43 |
|     Bob     | information6 |     www3     | 2018-02-14 10:32:43 |
|-------------|--------------|--------------|---------------------|

I have tried something like below: 我已经尝试过以下内容:

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", ))
    )
);

I have no idea how to implement this nested where and select query with Hibernate criteria? 我不知道如何实现此嵌套的位置,并选择与休眠条件的查询?

Thanks in advance. 提前致谢。

I'm not familiar with Hibernate, but you can rewrite the query to avoid the subselect 我不熟悉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'

You may find this plays nicer with the Hibernate syntax 您可能会发现,使用Hibernate语法会更好

NB This assumes that you have a maximum of one record per name and server. 注意:这假设每个名称和服务器最多有一个记录。 This could be enforced by a UNIQUE KEY on (name,server) 这可以通过(name,server)上的UNIQUE KEY强制执行

This assumption is based on the condition WHERE {bob server row starttime} < SELECT {alice server row starttime} from your original query, which doesn't really make sense if the SELECT can return more than one row 此假设基于条件WHERE {bob server row starttime} < SELECT {alice server row starttime} ,如果SELECT可以返回多个行,则没有任何意义

My advice is to keep trying, look more in the Javadocs, experiment in your IDE. 我的建议是继续尝试,在Javadocs中查找更多内容,在IDE中进行实验。 And if you give up, try the below (assuming your table is modeled in class DataStatus ): 如果您放弃了,请尝试以下操作(假设您的表在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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM