您的位置:首页 > 编程语言 > Java开发

用Java 8 lambda优化JDBC

2015-11-12 16:30 393 查看
本教程源码下载

https://github.com/jexenberger/lambda-tuples

首先创建一个函数接口ResultSetProcessor :

@FunctionalInterface

public interface ResultSetProcessor {

public void process(ResultSet resultSet,
long currentRow)
throws SQLException;


}

下面做个简单查询案例,使用这个接口遍历

public static void select(Connection connection,

String sql,

ResultSetProcessor processor,

Object… params) {

try (PreparedStatement ps = connection.prepareStatement(sql)) {

int cnt = 0;

for (Object param : params) {

ps.setObject(++cnt, param));

}

try (ResultSet rs = ps.executeQuery()) {

long rowCnt = 0;

while (rs.next()) {

processor.process(rs, rowCnt++);

}

} catch (SQLException e) {

throw new DataAccessException(e);

}

} catch (SQLException e) {

throw new DataAccessException(e);

}

}

调用这个select语句如下:

select(connection, “select * from MY_TABLE”,(rs, cnt)-> {

System.out.println(rs.getInt(1)+” “+cnt)

});

select的第三个参数ResultSetProcessor这是个函数,所以我们传入的是一个匿名函数。

Streams API

   java 8提供了更强大的 Streams API,我们可以对ResultSet处理更加强大。创建一个自己的Tuple 类型,代表ResultSet中一行记录。

   下面我们将一个查询和ResultSet包装在一个Iterator中:

public class ResultSetIterator implements Iterator {

private ResultSet rs;
private PreparedStatement ps;
private Connection connection;
private String sql;

public ResultSetIterator(Connection connection, String sql) {
assert connection != null;
assert sql != null;
this.connection = connection;
this.sql = sql;
}

public void init() {
try {
ps = connection.prepareStatement(sql);
rs = ps.executeQuery();

} catch (SQLException e) {
close();
throw new DataAccessException(e);
}
}

@Override
public boolean hasNext() {
if (ps == null) {
init();
}
try {
boolean hasMore = rs.next();
if (!hasMore) {
close();
}
return hasMore;
} catch (SQLException e) {
close();
throw new DataAccessException(e);
}

}

private void close() {
try {
rs.close();
try {
ps.close();
} catch (SQLException e) {
//nothing we can do here
}
} catch (SQLException e) {
//nothing we can do here
}
}

@Override
public Tuple next() {
try {
return SQL.rowAsTuple(sql, rs);
} catch (DataAccessException e) {
close();
throw e;
}
}


}

这是一个遍历器,每次返回ResultSet的一行记录,返回类型是我们定义Tuple.

关于tuple定义可见源码。

我们和Stream绑定在一起如下:

public static Stream stream(final Connection connection,

final String sql,

final Object… parms) {

return StreamSupport

.stream(Spliterators.spliteratorUnknownSize(

new ResultSetIterator(connection, sql), 0), false);

}

Java 8 提供StreamSupport静态方法.stream来创建 java.util.stream.Stream实例,同时还需要java.util.stream.Spliterator,这是一个用来遍历和分区一个序列元素(集合)的特殊类型,有了它才能并行处理我们饿操作,而Spliterators 这是能够对已经存在的集合如java.util.Iterator.提供并行操作。

我们调用上面stream如下:

long result = stream(connection, “select TEST_ID from TEST_TABLE”)

.filter((t) -> t.asInt(“TEST_ID”) % 2 == 0)

.limit(100)

.count();

这是查询所有的TEST_ID,然后过滤掉所有非偶数,最后再运行一个计数。非常简单明了。如果你使用ORM/JPA等框架,可能无法让自己的SQL代码如此优雅直接了,它类似Hibernate的 criteria。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: