java 8 jdbc_用Java 8 lambda优化JDBC

用Java 8 lambda优化JDBC

本教程源码下载github

首先创建一个函数接口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这是个函数,所以我们传入的是一个匿名函数。

java 8提供了更强大的 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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值