这是代码。让我们说数据库中有很多大图像,所以我想一次只在内存中保留一个。如何使用像lambda和streams这样的JDK 8功能来编写它?
我开始使用它们但是它仍然失败(来自https://spring.io/guides/gs/relational-data-access/和www.jooq.org/java-8-and-sql)并且使用ResultSetExtractor正在作为用户,但有没有办法在没有ResultSetExtractor的情况下执行此操作?
jdbcTemplate.query(
"select id,image,mimetype from images",
new ResultSetExtractor(){
@Override
public List extractData(ResultSet rs) throws SQLException, DataAccessException {
while(rs.next()){
createThumbnail( new ImageHolder(rs.getInt("id"), rs.getBytes("image"), rs.getString("mimetype") ));
}
return null;
}
}
);
这是一个很好看的流/ lambda版本,它可以在内存中保存太多东西,并且迟早会给OOME。
jdbcTemplate.query(
"select id,image,mimetype from images",
(rs,rowNum)->new ImageHolder(rs.getInt("id"), rs.getBytes("image"),rs.getString("mimetype"))
).stream().forEach(
imageHolder -> createThumbnail(imageHolder)
) );
这只会在开始之前加载所有行" streaming"它们。
答案 0 :(得分:2)
解决方案可能是在第一个lambda中移动缩略图的生成,直接翻译你的第一个例子。
if ($_POST['blob']) {
if ($profile->avatar==1) {
unlink('/images/avatars/'.$profile->avatar);
$profile->avatar=0;
}
$file = base64_decode($_POST['blob']);
$filename="avatar_".$user_id.'.'.$_POST['ext'];
file_put_contents($_SERVER['DOCUMENT_ROOT'] ."/images/avatars/".$filename, $file);
$profile->avatar=$filename;
}
要获得与您尝试实现查询方法的结构类似的结构,应该返回一个流,这样您就不必在流式传输之前收集所有内容。
答案 1 :(得分:1)
您可以将JDBC Statement.setFetchSize()
限制为比默认值see also some hints here更合理的值。
另一种方法是手动分页,如下所示:
int size = 10;
jdbcTemplate.query(
// This query creates chunks of 10 and shows the low/high id value in each chunk
"select id1, id2 "
+ "from ( "
+ " select "
+ " id AS id1, "
+ " lead(id, ?) over (order by id) AS id2, "
+ " row_number() over (order by id) rn from images) i "
+ " from images "
+ ") i
+ "where rn % ? = 0",
new Object[] { size, size },
rs1 -> {
while (rs1.next())
jdbcTemplate.query(
// This query fetches only images for each chunk
"select id, image, mimetype from images "
+ "where id >= ? and id < coalesce(?, 2147483647)",
new Object[] { rs1.getInt(1), rs1.getInt(2) },
rs2 -> {
createThumbnail(new ImageHolder(
rs2.getInt("id"),
rs2.getBytes("image"),
rs2.getString("mimetype")
));
return null;
}
);
return null;
}
);