用Java 8 lambda优化JDBC
2015-11-12 16:30
393 查看
本教程源码下载
https://github.com/jexenberger/lambda-tuples
首先创建一个函数接口ResultSetProcessor :
@FunctionalInterface
public interface ResultSetProcessor {
}
下面做个简单查询案例,使用这个接口遍历
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 {
}
这是一个遍历器,每次返回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。
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。
相关文章推荐
- Java 反射与内省
- Java8教程
- java排列三个随机数
- Spring scope属性详解
- java 排列三个随机数
- Spring缓存注解
- java 求最大公约数和最小公倍数
- java 求最大公约数和最小公倍数
- Java 多线程警告不阻塞,单线程处理警告实现
- java 九九乘法表
- java 九九乘法表
- java中判断字符串是否为数字的方法
- Eclipse V4.5.1 Mars使用Eclipse Color Them更换主题
- 使用java的File类遍历文件夹,打印树状结构(递归实现)
- 【软件使用】GitHub使用教程for Eclipse
- Java异常处理中同时有finally和return语句的执行问题
- 依赖关系Error:java: Annotation processing is not supported for module cycles.
- spring 项目加载完立刻执行
- Maven 创建java web项目并运行
- 【Java并发编程】之三:线程挂起、恢复与终止的正确方法(含代码)