java - 复杂 API 的 Java 尝试
问题描述
我想将一些 JDBC 代码包装到我自己的和不同的类中。因此在这些类中创建资源,返回结果集。如果客户端准备好了,那么该链中所有打开的资源都应该关闭。
我写了以下内容,但我不确定这是否足够正确和最简单的方法。
我为插入数据行构建了一个 SQL 字符串。
从我的数据源(hikari 池),我得到一个数据库连接。然后我创建一个准备好的语句,我执行它并得到一个ResultSet
回复。
这个结果集我返回给调用者。
连接和准备好的语句必须保持打开状态,直到调用者准备好返回的结果集
public DbResult insert(int cache, String shema, String table, LinkedHashMap<String, Object> data, boolean returnAutoCreate) throws SQLException
{
//building sql-string or take it from my cache
//...
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try
{
connection = ds.getConnection();
preparedStatement = connection.prepareStatement(sqlString);
int i = 0;
for (Object value : data.values())
{
preparedStatement.setObject(i++, value);
}
preparedStatement.executeUpdate();
resultSet = preparedStatement.getResultSet();
DbResult dbResult = new DbResult(connection, preparedStatement, resultSet);
return dbResult;
}
catch (Exception e)
{
try
{
if (resultSet != null) resultSet.close();
}
catch (Exception e2)
{
e.addSuppressed(e2);
}
try
{
if (preparedStatement != null) preparedStatement.close();
}
catch (Exception e2)
{
e.addSuppressed(e2);
}
try
{
if (connection != null) connection.close();
}
catch (Exception e2)
{
e.addSuppressed(e2);
}
throw e;
}
}
这是我的 DbResult 类
class DbResult implements AutoCloseable
{
private final ResultSet rs;
private final PreparedStatement ps;
private final Connection conn;
public DbResult(Connection conn, PreparedStatement ps, ResultSet rs)
{
this.conn = conn;
this.ps = ps;
this.rs = rs;
}
@Override
public void close() throws SQLException
{
try (conn; ps; rs;){}
}
public ResultSet getResultSet()
{
return rs;
}
}
这里是客户端/调用者代码
DatabaseHelper databaseHelper = new DatabaseHelper(ds, defaultShema);
try(DbResult result = databaseHelper.insert(1001, defaultShema, "test", new LinkedHashMap<>(), true);)
{
//do sth with result
}
在我的插入方法中,我添加了 try catch,因为如果那里出现问题,我必须关闭资源。
如果没有问题,我将资源添加到我的DbResult
对象中,然后使用 - 方法关闭资源close()
。在那里,我使用了 try-with,因为如果在该链中一个关闭失败,那么其他的仍然关闭,并且异常被正确转发。
close()
在我的调用者处,我还使用了一个 try-with,它在我完成结果后在 DbResult中调用该方法。
但它有很多代码,尤其是我的插入方法中的 try-catch 构造。
我不确定是否有更简单或更好的方法来做到这一点。
我还有一个问题:
我可以缓存结果,所以我不必在DatabaseHelper
课堂之外处理该资源的关闭。
存在一个CachedRowSet
. 但我不确定,这有多贵。这是否也复制了元信息?
我猜正常ResultSet
首先检索数据,如果我访问它们:元数据,行数据:逐行?
将数据缓存到 Hashmap 的 ArrayList 中是个好主意吗?
Arraylist -> Rows
HashMap -> 列名 -> 值
因此,如果我这样做,我可以立即关闭所有资源。
-> 我不必关心在我的 DatabaseClass 之外关闭
-> 池更快地恢复连接
但是,也许我检索了我不需要的数据(例如,元数据)。
此外,将我的数据副本构建到 ArrayList->Hashmap 构造中的成本很高。
那么你对此有什么想法?最佳做法是什么?
解决方案
推荐阅读
- java - 将项目导出到 zip 文件时如何更改 java 框架中的属性
- git - Git:git@gitlab.com:当我按下“同步更改”按钮时权限被拒绝(公钥)
- json - 从 MVC 中的控制器返回时出现 JavaScript 错误
- python - 为什么我在流式传输时收到“JSONDecoderError”?
- java - 在最近的 Java 版本(8+)中可以省略菱形运算符吗?
- javascript - 替代 FormData 以保持属性的顺序
- directx-11 - 像素着色器中如何使用顶点数据
- php - 为什么带有while循环的PHP Curl会产生504超时?
- javascript - “findById”方法不起作用,即使我提供了正确的对象 ID
- java - Java - 公历存储在变量中?