简体   繁体   中英

How to avoid executing the query multiple times?

Say I have this nativeQuery in my DAO:

SELECT a, b, c FROM table

which returns all the values I need.

The problem is I have too many results and I need the query to run only once instead of running for every single row found.

I'm retrieving the query result and setting all the values into a class (value object) called Class like this:

public List<Class> listClass() {

    List<Class> listaObjs;

    String nativeQuery = "SELECT a, b, c FROM table";
    SQLQuery q = getSession().createSQLQuery(nativeQuery);

    int totalRecords = q.list().size();
    System.out.println("Total records: " + totalRecords);

    listaObjs = q.list();

    // For every ROW in query Result
    for (int i = 0; i < totalRecords; i++) {
        Object[] objs = (Object[]) q.list().get(i);
        Class item = new Class();

        // For every COLUMN in that ROW
        for (Object obj : objs) {
            item.setValueA((String) objs[0]);
            item.setValueB(((String) objs[1]));
            item.setValueC(((String) objs[2]));
            listaObjs.add(item);
        }
    }
    return listaObjs;
}

I'm a bit stuck here because I've never treated this Object[] to Class casting before.

Change the below lines

// For every ROW in query Result
for (int i = 0; i < totalRecords; i++) {
    Object[] objs = (Object[]) q.list().get(i);

Use

List<Object[]> objArr = q.list();
// For every ROW in query Result
for (int i = 0; i < totalRecords; i++) {
    Object[] objs = (Object[]) objArr.get(i);

Your code has lot of performance and programmatic issue . Please try below.

public List<Class> listClass() {

        List<Class> listaObjs = new ArrayList<Class>();

        String nativeQuery = "SELECT a, b, c FROM table";
        SQLQuery q = getSession().createSQLQuery(nativeQuery);

        List<Object[]> totalRecords = q.list();
        System.out.println("Total records: " + totalRecords.size());


        for (Object[] objects : totalRecords) {
            Class item = new Class();
            item.setValueA((String) objs[0]);
            item.setValueB(((String) objs[1]));
            item.setValueC(((String) objs[2]));
            listaObjs.add(item);
        }

        return listaObjs;
    }

This code will rerun the query on each iteration:

 Object[] objs = (Object[]) q.list().get(i);

You got the list already with listaObjs = q.list(); , so work on listaObjs inside the loop:

  for (int i = 0; i < totalRecords; i++) {
        Object[] objs = (Object[])listaObjs.get(i);

You should call q.list() outside of the loop. Then you should iterate through the ResultSet returned, that should be your loop. Read up how to properly iterate through a ResultSet (or maybe through the List returned by the API you're using).

Don't call q.list every time, just once and store the result in a List variable. (q.list() executes the sql, but you don't need it every time)

List resultList = q.list();
int totalRecords = resultList.size();

and so on...

You may consider using iterate instead of a for loop, maybe SqlQuery has an iterate method, if not, iteratr over the list.

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