2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 函数式编程理解

函数式编程理解

时间:2020-08-15 11:01:51

相关推荐

函数式编程理解

学习《廖雪峰java课程》,看到Spring开发-访问数据库-使用JDBC这一章节时,对比源码

public User getUserByName(String name) {return jdbcTemplate.execute("SELECT * FROM users WHERE name = ?", (PreparedStatement ps) -> {ps.setObject(1, name);try (var rs = ps.executeQuery()) {if (rs.next()) {return new User( // new User object:rs.getLong("id"), // idrs.getString("email"), // emailrs.getString("password"), // passwordrs.getString("name")); // name}throw new RuntimeException("user not found by id.");}});}

这个方法首先有个lambda表达式,没有看懂,又返回到函数式编程-lambda基础这一章节学习,

在Java程序中,我们经常遇到一大堆单方法接口,即一个接口只定义了一个方法

例如有这么一个方法:

@parm Rice 大米@parm doFood 做法,这是一个接口,具体实例可以自定义,包括:炒米饭、蒸米饭等public void getFood(Rice r , DoFood df){df.do(r);}// 下面是一个只定义一个方法的接口public interface DoFood{void do(Rice r);}

如果要使用getFood,通常的办法是定义一个实现DoFood接口的类

public Class FriedFood implement DoFood{@Overridepublic void do(Rice r){System.out.println("炒米饭”);}}

具体调用

getFood(new Rice(),new FiredFood());

如果用lambda表达式,可以简写成

getFood(new Rice(),(Rice r)->{System.out.println("炒米饭”);});

只需要写出方法定义即可,接着看代码:

查看源码,上面 jdbcTemplate.execute()的实现如下

public <T> T execute(String sql, PreparedStatementCallback<T> action) throws DataAccessException {return this.execute((PreparedStatementCreator)(new SimplePreparedStatementCreator(sql)), (PreparedStatementCallback)action);}

可以看到,第二个参数是 PreparedStatementCallback,接着查看这个定义

@FunctionalInterfacepublic interface PreparedStatementCallback<T> {@NullableT doInPreparedStatement(PreparedStatement var1) throws SQLException, DataAccessException;}

很明显,这是一个@FunctionalInterface的接口,可以用lambda表达式简写,注意:这个接口用泛型定义了一个方法,<T>是声明T这个泛型而已。

继续跟踪this.execute,这个方法

public <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action) throws DataAccessException {Assert.notNull(psc, "PreparedStatementCreator must not be null");Assert.notNull(action, "Callback object must not be null");if (this.logger.isDebugEnabled()) {String sql = getSql(psc);this.logger.debug("Executing prepared SQL statement" + (sql != null ? " [" + sql + "]" : ""));}Connection con = DataSourceUtils.getConnection(this.obtainDataSource());PreparedStatement ps = null;Object var13;try {ps = psc.createPreparedStatement(con); // 语句 1this.applyStatementSettings(ps);T result = action.doInPreparedStatement(ps); // 语句 2this.handleWarnings((Statement)ps);var13 = result;} catch (SQLException var10) {if (psc instanceof ParameterDisposer) {((ParameterDisposer)psc).cleanupParameters();}String sql = getSql(psc);psc = null;JdbcUtils.closeStatement(ps);ps = null;DataSourceUtils.releaseConnection(con, this.getDataSource());con = null;throw this.translateException("PreparedStatementCallback", sql, var10);} finally {if (psc instanceof ParameterDisposer) {((ParameterDisposer)psc).cleanupParameters();}JdbcUtils.closeStatement(ps);DataSourceUtils.releaseConnection(con, this.getDataSource());}return var13;}

语句1 就是通过sql 创建 conn,并通过conn得到preparedstatement,有了这个preparedstatement,就可以把它传给doInPreparedStatement(),具体实现方法是

{ps.setObject(1, name);try (var rs = ps.executeQuery()) {if (rs.next()) {return new User( // new User object:rs.getLong("id"), // idrs.getString("email"), // emailrs.getString("password"), // passwordrs.getString("name")); // name}}

可以看到就是设置“name”,然后填充User并返回,因为这个方法返回的是User,也就是T 就是 User,excute返回的就是User,正好与getUser的返回值相符。

== 函数式编程,可以理解传入的是一个函数,也可以理解就是一个接口的匿名继承 ==

可以查看 public T execute(ConnectionCallback action) 这个方法,更容易理解,实际上就是传入了一个接口而已,我们自己去实现这个接口唯一的方法doInConnection(Connection var1),通过方法名称可以很形象的理解,我们在这个方法里就是操作Connection就行,excute方法会传入一个实例的conn到doInConnection里

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。