从Database SQL查询创建Java对象

时间:2015-01-16 21:24:49

标签: java sql database

到目前为止,我从数据库查询中创建简单POJO的方式如下:

CallableStatementCallback<Integer> csc = new CallableStatementCallback<Integer>() {
        @Override
        public Integer doInCallableStatement(CallableStatement cs) 
                       throws SQLException, DataAccessException {
            cs.execute();

            ResultSet rs = cs.getResultSet();
            if (rs != null && rs.next()) {
                SomePojoClass spc = new SomePojoClass();

                spc.setFirstValue(rs.getLong("first")); //column names from table
                spc.setSecondValue(rs.getString("second"));
                spc.setThirdValue(rs.getString("third"));

                spcList.add(spc);
              return 1;
            }
          return 0;
        }
    };

显然,这会将每一行映射到一个新的POJO。但我有一个返回如下行的SQL查询:

 [parent row 1] - [child row 1] (returned as one row obviously)
 [parent row 1] - [child row 2]
 [parent row 2] - [child row 1]
 [parent row 2] - [child row 2]
 [parent row 2] - [child row 3]
 [parent row 3] - [child row 1]

等。由于一对多的关系,这是获取SQL结果集的非常常见的方式......并且对于相当简单的结构执行冗余查询似乎是不必要的(并且可能是低效的)。有没有一种简单的方法将其解析为java对象?即,不是迭代ResultSet类并为每一行创建和设置一个新对象,我想迭代该集合并为每个父行创建一个新对象,为每个子行创建一个新对象。

例如,一个想法可能是通过父主键对查询进行排序,然后仅在父ID更改时生成新的父对象,但仍然为每一行创建一个新的子对象,并绑定父项和子项每当下一行的父ID改变时,它们就在一起。但我不知道这是否是正确的做法。

1 个答案:

答案 0 :(得分:2)

  

这是一种非常常见的获取SQL结果集的方法   许多关系......并且做一个相当简单的冗余查询   结构似乎没必要(并且可能效率低下)。

我同意。在这种情况下,您必须执行n个其他查询,一个查询父查询结果中的每一行,以获取子记录。或者使用带有父ID的in子句一次选择所有子记录,然后以某种方式将它们映射回父记录。无论你把它切成什么方式,它都很难看。

  

是否有一种简单的方法可以将其解析为java对象?

有对象关系映射框架可以为您延迟加载子对象。这有帮助,因为除非从父对象专门请求子对象的集合,否则不会执行其他查询。但是,它并没有完全克服上述的低效率。特别是当您知道将从每个父对象使用子对象时。

由于您直接使用JDBC滚动自己的对象关系映射,因此没有确定如何实现目标的标准。

  

例如,一个想法可能是按父主要顺序排序查询   key,然后仅在父id时生成新的父对象   改变了,但仍然为每一行创建一个新的子对象,然后绑定   父母和孩子一起在下一行的父ID   会改变。但我不知道这是否是正确的做法。

您描述的解决方案是我所知道的最佳方式。我已多次使用它并发现它运作良好。

以上面的代码示例作为模板,您必须填充POJO中的所有父属和子属性,然后在代码中的更高级别检测它是否与前一个属性相同并且执行因此。这对我来说似乎并不优雅,但它可以奏效。

希望你能找到一种简单的方法来修改你的设计,以更好地支持这种算法。如果你愿意,我可以和你分享我自己建立的框架,这样你就可以看到我是如何做到的。