原创

模板方法设计模式的原理及测试代码(手写JdbcTemplate)

模板方法模式介绍:

简单介绍

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method 使得子类可以不改变
一个算法的结构即可重定义该算法的某些特定步骤。
Template Method 模式一般是需要继承的。这里想要探讨另一种对 Template Method 的理解。Spring
中的 JdbcTemplate,在用这个类时并不想去继承这个类,因为这个类的方法太多,但是我们还是想用
到 JdbcTemplate 已有的稳定的、公用的数据库连接,那么我们怎么办呢?我们可以把变化的东西抽出
来作为一个参数传入 JdbcTemplate 的方法中。但是变化的东西是一段代码,而且这段代码会用到
JdbcTemplate 中的变量。怎么办?那我们就用回调对象吧。在这个回调对象中定义一个操纵
JdbcTemplate 中变量的方法,我们去实现这个方法,就把变化的东西集中到这里了。然后我们再传入
这个回调对象到 JdbcTemplate,从而完成了调用。这就是 Template Method 不需要继承的另一种实
现方式。

归类:行为型模式

特点:执行流程固定,但中间有些步骤有细微差别(运行时才确定)。可实现批量生产。

举例:Spring ORM数据模型,JdbcTemplate

示例代码:

JdbcTemplate:

package com.debuggg.test1.templatemethod2;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class JdbcTemplate {

    private DataSource dataSource;

    public JdbcTemplate(DataSource dataSource){
        this.dataSource = dataSource;
    }

    private Connection getConnection() throws SQLException {
        return this.dataSource.getConnection();
    }

    private PreparedStatement getPreparedStatement(Connection connection, String sql) throws SQLException {
        return connection.prepareStatement(sql);
    }

    private ResultSet getResultSet(PreparedStatement preparedStatement, Object[] values) throws SQLException {
        for (int i = 0; i < values.length; i++) {
            preparedStatement.setObject(i, values[i]);
        }
        return preparedStatement.executeQuery();
    }

    private List<Object> pareseResultSet(ResultSet resultSet, RowMapper rowMapper) throws Exception {
        ArrayList<Object> list = new ArrayList<>();
        int num = 1;
        while (resultSet.next()){
            list.add(rowMapper.mapRow(resultSet,num++));
        }
        return list;
    }

    private void closeResultSet(ResultSet resultSet) throws SQLException {
        resultSet.close();
    }

    private void closePreparedStatement(PreparedStatement preparedStatement) throws SQLException {
        preparedStatement.close();
    }

    private void closeConnection(Connection connection) throws SQLException {
        connection.close();
    }

    public List<Object> executeQuery(String sql, Object[] values, RowMapper rowMapper) throws Exception {
        //创建连接
        Connection connection = this.getConnection();
        //创建语句集
        PreparedStatement preparedStatement = this.getPreparedStatement(connection, sql);
        //得到结果集
        ResultSet resultSet = this.getResultSet(preparedStatement, values);
        //解析结果集
        List<Object> objects = this.pareseResultSet(resultSet, rowMapper);
        //关闭结果集
        this.closeResultSet(resultSet);
        //关闭语句集
        this.closePreparedStatement(preparedStatement);
        //关闭连接
        this.closeConnection(connection);
        return objects;
    }
}

RowMapper:

package com.debuggg.test1.templatemethod2;

import java.sql.ResultSet;

public interface RowMapper<T> {
    T mapRow(ResultSet rs, int rowNum) throws Exception;
}

测试:
User

package com.debuggg.test1.templatemethod2.entity;

public class User {

    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

dao层代码:

package com.debuggg.test1.templatemethod2.dao;

import com.debuggg.test1.templatemethod2.JdbcTemplate;
import com.debuggg.test1.templatemethod2.entity.User;

import java.util.List;

public class UserDao {

    private JdbcTemplate jdbcTemplate = new JdbcTemplate(null);

    public List<Object> query() throws Exception {
        String sql = "select * from t_user";
        return this.jdbcTemplate.executeQuery(sql,null,(resultSet,rowNum) -> {
            User user = new User();
            user.setUsername(resultSet.getString("username"));
            user.setPassword(resultSet.getString("password"));
            return user;
        });
    }

}
正文到此结束
本文目录