函数式编程理解

学习《廖雪峰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"), // id
							rs.getString("email"), // email
							rs.getString("password"), // password
							rs.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{
	@Override
	public 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,接着查看这个定义

@FunctionalInterface
public interface PreparedStatementCallback<T> {
    @Nullable
    T 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);  //  语句 1
            this.applyStatementSettings(ps);
            T result = action.doInPreparedStatement(ps); // 语句 2
            this.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"), // id
							rs.getString("email"), // email
							rs.getString("password"), // password
							rs.getString("name")); // name
				}
}

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值