模板方法设计模式是常用的设计模式之一,通过继承实现代码复用。
设计思想:
- 定义一个抽象类概括完成一件事情的步骤或者抽象出相同的代码实现复用,具体的实现逻辑由子类实现。
- 定义抽象类的实现类,重写父类中的抽象方法以实现具体的逻辑处理。
例如常见的jdbc查询操作,1)加载数据库驱动 2)获取连接 3) 获取执行sql的statement 4)执行sql 语句 5) 结果集处理 6)释放资源 这些操作是查询的必须步骤,无论查询何种数据步骤1,2,3,4,6都是不变的,只有 步骤5是需要变的。所以我们可以定义一个抽象类包含一个模板方法和一个抽象方法,其中该抽象方法需要子类去实现。
代码如下:
定义一个工具类,获取连接,释放资源import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class JDBCUtils { //定义数据库基本信息 private enum DriverInfo { DRIVERURL("jdbc:mysql://localhost:3306/jdbc"),DRIVERUSERNAME("root"),DRIVERPASSWORD(""); private String info; private String getInfo() { return info; } private DriverInfo(String info) { this.info = info; } } //加载数据库驱动 static { try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); throw new ExceptionInInitializerError(); } } //获取数据库连接 public static Connection getConnection() throws SQLException { return DriverManager.getConnection(DriverInfo.DRIVERURL.getInfo(), DriverInfo.DRIVERUSERNAME.getInfo(), DriverInfo.DRIVERPASSWORD.getInfo()); } //释放资源 public static void close(Connection conn) { close(conn, null, null); } //释放资源 public static void close(Connection conn, Statement statement) { close(conn, statement, null); } //释放资源 public static void close(Connection conn, Statement statement, ResultSet rs) { if(rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if(statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
说明:定义数据库信息之所以用枚举纯属熟悉一下(公司用的比较多)。
创建tb_user表:
create table tb_user (id int(11) primary key auto_increment, name varchar(20) , birthday date);
定义一个User实体:import java.util.Date; public class User { private int id; private String name; private Date birthday; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } }
抽象类:public abstract class AbstractDao { /** * @param sql * @param params * @return */ protected Object queryForObject(String sql, Object[] params) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; Object obj = null; try { //1,2加载驱动以及获取数据库连接 conn = JDBCUtils.getConnection(); //3获取执行sql的statement ps = conn.prepareStatement(sql); for (int i = 0; i < params.length; i++) { ps.setObject(i + 1, params[i]); } //4执行sql rs = ps.executeQuery(); //5需要子类处理结果集 if(rs.next()) {//只取第一个结果 obj = rowMapper(rs); } } catch (Exception e) { throw new RuntimeException(e.getMessage()); } finally { //6使用资源 JDBCUtils.close(conn, ps, rs); } return obj; } /** * 需要子类实现的抽象方法,不同的查询返回的结果集是不同的 * @throws SQLException */ protected abstract Object rowMapper(ResultSet rs) throws SQLException; }
抽象类的实现:public class UserDaoImpl extends AbstractDao { public User findById(int id) { String sql = "select id,name,birthday from tb_user where id=?"; Object[] params = new Object[] {id}; return (User) super.queryForObject(sql, params); } @Override protected Object rowMapper(ResultSet rs) throws SQLException { User user = new User(); user.setId(rs.getInt("id")); user.setName(rs.getString("name")); user.setBirthday(rs.getDate("birthday")); return user; } //测试 public static void main(String[] args) { System.out.println(new UserDaoImpl().findById(1).getName()); } }