【问题标题】:How to avoid executing the query multiple times?如何避免多次执行查询?
【发布时间】:2016-01-23 10:35:47
【问题描述】:

假设我的 DAO 中有这个 nativeQuery:

SELECT a, b, c FROM table

它返回我需要的所有值。

问题是我的结果太多,我需要查询只运行一次,而不是对找到的每一行都运行。

我正在检索查询结果并将所有值设置到一个名为 Class 的类(值对象)中,如下所示:

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

我有点卡在这里,因为我以前从未将这个 Object[] 转换为 Class

【问题讨论】:

  • Class 不是 Object[]
  • 好的,我可以解决这个问题。但我的问题是关于该查询被重复。有什么提示吗?
  • 当然是重复的,是循环调用的。

标签: java hibernate hibernate-native-query


【解决方案1】:

更改以下行

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

【讨论】:

    【解决方案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;
        }
    

    【讨论】:

      【解决方案3】:

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

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

      您已经使用listaObjs = q.list(); 获得了列表,因此请在循环内处理listaObjs

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

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

          等等……

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-02-16
            • 1970-01-01
            • 2022-11-23
            • 2015-06-12
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多