Java8学习之旅2---基于Lambda的JDBC编程
Java8的Lambda表达式确实是一个很好的特性。可是在哪些场合下使用。事实上还是须要细致考虑的。我们当然不能为了使用而使用,而是须要找到切实实用的场合。在JDBC编程中,比如查询语句,首先须要进行查询參数绑定,其次是处理返回的结果集,这两步操作是每一个查询都不同的,而获取JDBC连接,准备PreparedStatement,以及释放资源则都是全然同样的,这就是一个Lambda表达式应用的绝佳场景。
在讨论详细的实现细节之前,想先讨论一下JDBC的问题。
眼下相信90%以上的Java程序猿都不会再用JDBC了,基本都採用某种OR映射机制。如Hibernate、Persistent API等,採用所谓OO的方式来操作数据库。
可是实际上这样的方式在理论上非常好,在实际应用中是有非常大问题的,尤其在眼下大数据的情况下。将数据和程序绑在一起是非常不可取的,同一时候採用OR映射之后,抽象出的数据操作在功能和性能方面,都全然不能与SQL相比,因此直接使用JDBC还是值得考虑的。如今的语言之争,基本是该语言下最流行的框架之争,Java语言下基本就是SSH和JBOSS,因为这两个异常流行和笨重的框架。使Java基本淡出了互联网应用开发领域。事实上结合Java的NIO
2以及近期的Lambda表达式、Stream API的新特性。全然有可能写比Node.js更优秀的框架,仅仅可惜java开发社区在自己的思维惯性下。非常难使这样的可能变为现实。
好了,言归正传。我们首先如果我们须要查询数据库中的t_user表,当中有user_id, user_name, nick_name, birthday等字段,我们须要构造一个SQL查询。找出user_id小于10000的记录。
首先我们先定义值对象:
public class UserInfo {
public long getUserId() {
return userId;
}
public void setUserId(long userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public Calendar getBirthday() {
return birthday;
}
public void setBirthday(Calendar birthday) {
this.birthday = birthday;
}
private long userId = 0;
private String userName = null;
private String nickName = null;
private Calendar birthday = null;
}
其次我们定义获取和释放JDBC连接的函数:
private Connection getConnection() {
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/WkyDb?
user=wky&password=wky123&" +
"useUnicode=true&characterEncoding=utf-8&" +
"autoReconnect=true&failOverReadOnly=false");
} catch (Exception e) {
System.exit(0);
}
return conn;
}
private void closeConnection(Connection conn) {
try {
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
以下我们来定义參数绑定函数式接口:
@FunctionalInterface
public interface FParamBinder<T> {
public void bindParams(PreparedStatement stmt, T param) throws SQLException;
}
接下来我们定义接收返回结果的函数式接口:
@FunctionalInterface
public interface FResetSetter<T> {
public List<T> getResultSet(ResultSet rst) throws SQLException;
}
以下是SQL查询的详细实现函数:
public <T> List<T> executeQuery(String sql, FParamBinder<T> binder, T cond, FResetSetter<T> setter) {
Connection conn = getConnection();
PreparedStatement stmt = null;
ResultSet rst = null;
List<UserInfo> items = new ArrayList<UserInfo>();
UserInfo item = null;
List<T> recs = null;
try {
stmt = conn.prepareStatement(sql);
binder.bindParams(stmt, cond); // 调用參数绑定函数式接口
rst = stmt.executeQuery();
recs = setter.getResultSet(rst); // 获取返回结果集
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (rst != null) {
rst.close();
}
if (stmt != null) {
stmt.close();
}
} catch (Exception ex) {}
}
closeConnection(conn);
return recs;
}
这个函数实现与普通的JDBC编程中的查询不同。參数绑定和接收结果集这两部分都是通过传入的函数式接口变量来实现,因此代码显得很简洁。
以下是其它函数调用SQL查询时对上面函数的调用,例如以下所看到的:
public void testIt() {
String sql = "select user_id, user_name, nick_name, birthday from t_user where user_id<?";
FParamBinder<UserInfo> binder = (PreparedStatement stmt, UserInfo param) -> {
stmt.setLong(1, param.getUserId());
};
UserInfo cond = new UserInfo();
cond.setUserId(10000000L);
FResetSetter<UserInfo> setter = (ResultSet rst) -> {
List<UserInfo> items = new ArrayList<UserInfo>();
UserInfo item = null;
while (rst.next()) {
item = new UserInfo();
item.setUserId(rst.getLong(1));
item.setUserName(rst.getString(2));
items.add(item);
}
return items;
};
List<UserInfo> recs = executeQuery(sql, binder, cond, setter);
System.out.println("size=" + recs.size() + "!");
for (UserInfo u : recs) {
System.out.println("U:" + u.getUserName() + "-" + u.getUserId() + "!");
}
}
如上所述。调用者须要指定查询SQL语句,定义參数绑定函数式接口变量,结果集接收函数式接口变量,然后调用上面的executeQuery方法,就能够获取到结果集。然后就能够进行下一步的操作了。
Java8学习之旅2---基于Lambda的JDBC编程的更多相关文章
- Java8学习笔记(一)--Lambda表达式
两个概念 函数式接口 函数式接口就是只显式声明一个抽象方法的接口.为保证方法数量不多不少,java8提供了一个专用注解@FunctionalInterface,这样,当接口中声明的抽象方法多于或少于一 ...
- Java8函数之旅 (六) -- 使用lambda实现Java的尾递归
前言 本篇介绍的不是什么新知识,而是对前面讲解的一些知识的综合运用.众所周知,递归是解决复杂问题的一个很有效的方式,也是函数式语言的核心,在一些函数式语言中,是没有迭代与while这种概念的,因为此类 ...
- Java8 学习笔记--函数式接口与lambda表达式的关系
在java中,lambda表达式与函数式接口是不可分割的,都是结合起来使用的. 对于函数式接口,我们可以理解为只有一个抽象方法的接口,除此之外它和别的接口相比并没有什么特殊的地方.为了确保函数式接口的 ...
- 【小梅哥FPGA进阶学习之旅】基于Altera FPGA 的DDR2+千兆以太网电路设计
DDR2电路设计 在高速大数据的应用中,高速大容量缓存是必不可少的硬件.当前在FPGA系统中使用较为广泛的高速大容量存储器有经典速度较低的单数据速率的SDRAM存储器,以及速度较高的双速率DDR.DD ...
- Java网络编程学习A轮_07_基于Buffer的Socket编程
示例代码: https://github.com/gordonklg/study,socket module A. LineSeparate 基于 Buffer 实现逐行读取的 EchoServer ...
- Java8学习笔记目录
Java8学习笔记(一)--Lambda表达式 Java8学习笔记(二)--三个预定义函数接口 Java8学习笔记(三)--方法引入 Java8学习笔记(四)--接口增强 Java8学习笔记(五)-- ...
- Java8学习笔记----Lambda表达式 (转)
Java8学习笔记----Lambda表达式 天锦 2014-03-24 16:43:30 发表于:ATA之家 本文主要记录自己学习Java8的历程,方便大家一起探讨和自己的备忘.因为本人 ...
- Java8学习(3)- Lambda 表达式
猪脚:以下内容参考<Java 8 in Action> 本次学习内容: Lambda 基本模式 环绕执行模式 函数式接口,类型推断 方法引用 Lambda 复合 上一篇Java8学习(2) ...
- JAVA8学习——深入浅出Lambda表达式(学习过程)
JAVA8学习--深入浅出Lambda表达式(学习过程) lambda表达式: 我们为什么要用lambda表达式 在JAVA中,我们无法将函数作为参数传递给一个方法,也无法声明返回一个函数的方法. 在 ...
随机推荐
- PatentTips - Supporting address translation in a virtual machine environment
BACKGROUND A conventional virtual-machine monitor (VMM) typically runs on a computer and presents to ...
- python-string中部分string替换
今天遇到一个问题,就是需要把 “/home/zhangshuli/32_kk/” 中的32_kk 替换成为 52_kk 然后就在网上找方法,刚开始尝试的方法是 aaa = "/home/zh ...
- Redis笔记教程
一.redis简介 1.1.1.什么是redis? REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. 读 ...
- Android 6.0 最简单的权限获取方法 RxPermition EasyPermition
Android 6.0 要单独的获取权限 这里提供两种很简单的方法 EasyPermition RxPermition EasyPermition https://github.com/googles ...
- 3. Vue-router 路由
路由是根据不同的url地址展现不同的内容或页面. 前端路由就是把不同路由对应不同的内容或页面的任务交给前端来做(在单页面应用,大部分页面结构不变,只改变部分内容的使用),之前是通过服务器根据url的不 ...
- request.getRemoteUser() Spring Security做权限控制后
一. request.getRemoteUser();//获取当前缓存的用户,比如Spring Security做权限控制后就会将用户登录名缓存到这里 request.getRemoteAddr(); ...
- C#调用天气预报网络服务
本程序通过调用网络上公开的天气预报网络服务来显示某个地区三天的天气,使用到的网络服务地址:http://www.webxml.com.cn/WebServices/WeatherWebService. ...
- amazeui学习笔记--css(常用组件9)--导航nav
amazeui学习笔记--css(常用组件9)--导航nav 一.总结 1.导航基本使用:<ul> 添加 .am-nav class 以后就是一个基本的垂直导航.默认样式中并没有限定导航的 ...
- Windows 7 Ultimate with SP1(x64) MSDN 官方简体中文旗舰版原版
Windows 7 Ultimate(旗舰版)64位功能齐全,所有其他版本所具有的高级功能它都有!它是最好的Windows 7操作系统.旗舰版很受网友欢迎,下载速度飞快. MSDN 我告诉你下载官网: ...
- Node.js自学笔记之回调函数
写在前面:如果你是一个前端程序员,你不懂得像PHP.Python或Ruby等动态编程语言,然后你想创建自己的服务,那么Node.js是一个非常好的选择.这段时间对node.js进行了简单的学习,在这里 ...