0

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.

4

5 回答 5

2

更改以下行

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

利用

List<Object[]> objArr = q.list();
// For every ROW in query Result
for (int i = 0; i < totalRecords; i++) {
    Object[] objs = (Object[]) objArr.get(i);
于 2015-10-23T19:30:24.377 回答
2

您的代码有很多性能和程序问题。请在下面尝试。

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;
    }
于 2015-10-23T19:30:26.540 回答
1

此代码将在每次迭代时重新运行查询:

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

你已经得到了列表listaObjs = q.list();,所以listaObjs在循环内工作:

  for (int i = 0; i < totalRecords; i++) {
        Object[] objs = (Object[])listaObjs.get(i);
于 2015-10-23T19:29:33.083 回答
0

您应该q.list()在循环之外调用。然后你应该遍历ResultSet返回的,这应该是你的循环。阅读如何正确迭代 a ResultSet(或者可能通过List您正在使用的 API 返回的)。

于 2015-10-23T19:29:24.727 回答
0

不要每次都调用 q.list,只调用一次并将结果存储在 List 变量中。(q.list() 执行sql,但不是每次都需要)

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

等等...

您可以考虑使用迭代而不是for循环,也许SqlQuery有一个迭代方法,如果没有,迭代列表。

于 2015-10-23T19:31:12.490 回答