简体   繁体   中英

Spring Boot, JPA / Hibernate: How to execute two raw SELECT queries at once?

When I try to execute two SELECT statements at once as follows below, the logging console returns a runtime error:

java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT * FROM ...

The Java source code that generates the statements:

@Repository
public class VehicleObjectDbAccess {
    @PersistenceContext
    EntityManager entityManager;

    public List<Object[]>  getObjectById(long objectId, long year)     
    {
        int limit = 10;
        String tableName = ("i0i"+year)+objectId;
        String queryText =
            "START TRANSACTION;"
            + "SELECT t.created INTO @startTime FROM ObjectTable as t WHERE t.speed > 30 LIMIT 1;"
            + "SELECT * FROM ObjectTable WHERE created <= (CASE WHEN @startTime IS NULL THEN NOW() ELSE @startTime END) ORDER BY created DESC LIMIT 10;"
            + "COMMIT;";

        Query query = this.entityManager.createNativeQuery(queryText);
        return query.getResultList();
    }
}

Eventually the java source code above translates to

START TRANSACTION; 
SELECT t.created INTO @startTime FROM ObjectTable as t WHERE t.speed > 30 LIMIT 1;
SELECT * FROM ObjectTable WHERE created <= (CASE WHEN @startTime IS NULL THEN NOW() ELSE @startTime END) ORDER BY created DESC LIMIT 10; 
COMMIT;

I verified that SQL code running it on a MySQL client and it works properly.

How can I execute these two SELECT statements in a single query?

It seems you can divide your compound sql query to two separate SELECT queries:

 Query query1 = this.entityManager.createNativeQuery(queryText1);
 Query query2 = this.entityManager.createNativeQuery(queryText2);

After that you can get result lists from them and add result lists to one compound List:

 List<Object[]> result = new ArrayList<>();
 result.addAll(query1.getResultList());
 result.addAll(query2.getResultList());

Just use one select statement:

SELECT *, (SELECT t.created FROM ObjectTable as t WHERE t.speed > 30 LIMIT 1) as x FROM ObjectTable WHERE created <= 
  (CASE WHEN x IS NULL THEN NOW() 
   ELSE x
  END) 
  ORDER BY created DESC LIMIT 10;

If you don't want to do this for some reason, create a stored procedure that returns a result set and call it...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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