Spring 匿名/回调类用于数据持久化的困难时期
我正在尝试适应 Spring JDBC,但让我烦恼的是使用这些匿名类,我们无法传递任何局部变量,除非它们是最终的,这可能很容易安排,但是如果我需要循环数组或集合怎么办? 我无法将“FedModel fm”声明为最终的,因为它在循环中重新初始化,但我需要调用执行方法 100 次。这是我遇到问题的具体场景,因为我不知道如何将 BLOB 插入数据库的任何其他方法。
for (int i = 0; i < fedModels.size(); i++) {
FedModel fm = fedModels.get(i);
jdbcTemplate.execute("INSERT INTO items (name, video_blob) VALUES (?, ?)",
new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
protected void setValues(PreparedStatement ps, LobCreator lobCreator)
throws SQLException {
ps.setString(1, fm.getName());
ps.setString(2, fm.getDifficultyLevel());
ps.setString(3, fm.getEquipment());
lobCreator.setBlobAsBinaryStream(ps, paramIndex, contentStream, contentLength);
}
});
}
我唯一能想到的就是创建一个静态嵌套类,该类扩展 AbstractLobCreatingPreparedStatementCallback 并添加 fedModels 的构造函数,以便我可以在内部执行循环。但仅使用 JDBC 会更容易。
I'm trying to accommodate to Spring JDBC, but what bugs me is using these anonymous classes, where we cannot pass any local variables unless they are final which might be easy to arrange, but what about if I need to loop an array or collection ?
I cannot declare "FedModel fm" to be final as it gets reinitialized in the loop, but I need to call the execute method 100 times. This is concrete scenario where I have the problem, cause I don't know any other way how to insert BLOB into a database.
for (int i = 0; i < fedModels.size(); i++) {
FedModel fm = fedModels.get(i);
jdbcTemplate.execute("INSERT INTO items (name, video_blob) VALUES (?, ?)",
new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
protected void setValues(PreparedStatement ps, LobCreator lobCreator)
throws SQLException {
ps.setString(1, fm.getName());
ps.setString(2, fm.getDifficultyLevel());
ps.setString(3, fm.getEquipment());
lobCreator.setBlobAsBinaryStream(ps, paramIndex, contentStream, contentLength);
}
});
}
The only thing I can think of, is creating a static Nested class that extends AbstractLobCreatingPreparedStatementCallback and adds constructor for fedModels so that I could do the loop inside. But it would be easier using only JDBC.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这不是Spring的错。它是 Java 编程语言的属性。
基本上,Java 语言(至少 Java 6 及更早版本)不支持闭包,闭包允许匿名类实例访问和更新实例封闭范围内的局部变量。作为解决方法,该语言允许您访问
final
封闭的局部变量。这是通过将相应变量的值复制到匿名类实例中并将它们存储在隐藏变量中来实现的(没有闭包)。在您的特定情况下,简单的解决方案是将
fm
声明为final
。如果需要访问匿名类中的循环变量,可以声明一个最终副本;例如This is not Spring's fault. It is property of the Java programming language.
Basically, the Java language (at least Java 6 and earlier) does not support closures which would allow the anonymous class instance to access and update local variables in the instance's enclosing scopes. As a workaround, the language allows you to access enclosing local variables that are
final
. This is implemented (without closures) by copying the respective variable's values into the anonymous class instance, and storing them in hidden variables.In your particular case, the simple solution is to declare
fm
asfinal
. If you needed to access the loop variable in the anonymous class, you could declare a final copy; e.g.