如何以正确的方式处理结果集?
Posted
技术标签:
【中文标题】如何以正确的方式处理结果集?【英文标题】:How to Process ResultSets the right way? 【发布时间】:2015-08-02 08:00:48 【问题描述】:在 Java 中从 Sqlite 数据库处理 ResultSet 的正确方法是什么?
目前我有一个执行所有 SQL 查询的“SQL”类。
如果另一个类需要一些数据,它会调用 SQL 类的方法,SQL 类获取 ResultSet 将其存储在 Array 或其他东西中并返回该数组。
但这有点愚蠢,我知道这肯定不是正确的方法。
那么我如何在不使用这种讨厌的方法的情况下将 ResultSet 的数据获取到我的其他类中呢?
我挣扎的一点是,一旦 Statement 关闭,ResultSet 就会关闭,所以我无法返回 ResultSet。
我很确定我有一个非常大的概念问题,但我不知道如何解决它。
【问题讨论】:
不要使用数组,而是使用List<YourClass>
,或者,在最糟糕的情况中,使用List<Map<String,String>>
作为从ResultSet
读取数据的结果。
【参考方案1】:
当谈到普通的 JDBC 时,常见的做法
-
定义您的程序将运行的抽象。
将这些抽象映射到数据库结构。
为这些抽象实现类 - 实体。
在您的代码中提供一个特殊层来为这些实体执行CRUD 操作。
对于上述设计,建议使用 DAO 模式 - 它允许您为逻辑上分离的代码部分(例如,为单独的实体分离 DAO)分离 DB 访问,从而导致松散耦合。
就ResultSet
处理而言:
ResultSet
处理
DAO 中的ResultSet
s 应该被翻译成代表程序抽象的类,并且只有这些类应该从 DAO 返回
【讨论】:
感谢帮助很大。是否可以在实体类中有一个构造函数来获取 ResultSet 并填充实体,还是必须在 CRUD 操作类中填充实体? 好吧,从完美主义者的角度来看,您应该将ResultSet
处理留在 DAO 中 - 这样可以简化代码维护,尤其是在 DB/DB 结构发生变化的情况下。
此外,建议将业务逻辑分离到一个单独的层中:例如为Person
和PersonDAO
提供PersonProcessor
类(例如PersonProcessor.login(String login)
使用PersonDAO
加载Person
通过登录,还可以向他发送通知电子邮件等)。所有其他代码只使用PersonProcessor
,最好对PersonDAO
一无所知。但这是一个完美的例子)对于一个简单的应用程序,这个结构看起来很复杂,所以 *Processor 和 *DAO 通常被实现为一个类等等。
好的,我可以看到处理器类的优化,但我不会这样做。但是,如果 ResultSet 只是在 DAO 中处理,那么 DAO 类会不会很厉害?因此,对于所有具有处理的 CRUD 的每个实体:O 如果它们都卡在一个类中并且没有以某种方式分开,那不是“不太好”吗?
对,如果您将 all 实体的 all 数据库访问操作放在 one DAO 类中,这将是巨大的。重点是为每个实体类(或至少一组相关实体类)创建单独的 DAO类。但是,是的,它会导致一些代码重复,如 DAO wiki 文章的缺点部分所述。 ***.com/questions/19154202/… 包含一些有用的讨论和主题链接。【参考方案2】:
您应该将 ResultSet 映射到一个类并返回该类。
例如,如果您有一个 User
类并且有一个带有 name
列的 user
表
List<User> results = new ArrayList<User>();
while (resultSet.next())
User user = new User();
user.setName(rs.getString("name");
results.add(user);
【讨论】:
好吧,我有时已经这样做了。但是我仍然必须为每个表和视图创建一个类!不同表的选择语句需要不同的方法。没有更有效的方法吗? @Teifun2 这就是手工的方式。如果您想要更“自动”的东西,请寻找 JPA。以上是关于如何以正确的方式处理结果集?的主要内容,如果未能解决你的问题,请参考以下文章
正确使用MySQL JDBC setFetchSize()方法解决JDBC处理大结果集 java.lang.OutOfMemoryError: Java heap space