一、模板
模板,很经典、也很常用的一种模式。无处不在,如,spring jdbcTemplate。模板,个人理解, 讲大同小异的东西抽出它们的共性,提供标准的套路。
二、为什么要用模板?
假设场景,我们需要查询个人资料信息,现提供两个api,getPersonById(int id)、 getPersonListByName(String name)
1、我们先来看下不使用模板的情况
①、注册jdbc、建立连接
1 static final String DB_URL = "jdbc:mysql://localhost/testdb"; 2 static final String USER = "root"; 3 static final String PWD = "root"; 4 5 private static Connection connection = null; 6 7 static { 8 try { 9 // 注册JDBC驱动程序:以打开与数据库的通信信道 10 Class.forName("com.mysql.jdbc.Driver"); 11 // 获取连接 12 connection = DriverManager.getConnection(DB_URL, USER, PWD); 13 } catch (ClassNotFoundException e) { 14 throw new RuntimeException("ClassNotFoundException"); 15 } catch (SQLException e) { 16 throw new RuntimeException("SQLException"); 17 } 18 }
②、根据Id查询
1 public static List<Person> getPersonById(int id) { 2 List<Person> res = new ArrayList<Person>(); 3 PreparedStatement ps = null; 4 ResultSet rs = null; 5 try { 6 String sql = "select * from person where id = ?"; 7 ps = (PreparedStatement) connection.prepareStatement(sql); 8 ps.setInt(1, id); 9 rs = ps.executeQuery(); 10 while (rs.next()) { 11 res.add(new Person(rs.getInt("id"), rs.getString("name"))); 12 } 13 return res; 14 } catch (SQLException e) { 15 16 } finally { 17 if (connection != null) { 18 try { 19 connection.close(); 20 } catch (SQLException e) { 21 22 } 23 } 24 if (ps != null) { 25 try { 26 ps.close(); 27 } catch (SQLException e) { 28 29 } 30 } 31 if (rs != null) { 32 try { 33 rs.close(); 34 } catch (SQLException e) { 35 36 } 37 } 38 } 39 return null; 40 }
③、根据名字查询
1 public static List<Person> getPersonListByName(String name) { 2 List<Person> res = new ArrayList<Person>(); 3 PreparedStatement ps = null; 4 ResultSet rs = null; 5 try { 6 String sql = "select * from person where name = ?"; 7 ps = (PreparedStatement) connection.prepareStatement(sql); 8 ps.setString(1, name); 9 rs = ps.executeQuery(); 10 while (rs.next()) { 11 res.add(new Person(rs.getInt("id"), rs.getString("name"))); 12 } 13 return res; 14 } catch (SQLException e) { 15 16 } finally { 17 if (connection != null) { 18 try { 19 connection.close(); 20 } catch (SQLException e) { 21 22 } 23 } 24 if (ps != null) { 25 try { 26 ps.close(); 27 } catch (SQLException e) { 28 29 } 30 } 31 if (rs != null) { 32 try { 33 rs.close(); 34 } catch (SQLException e) { 35 36 } 37 } 38 } 39 return null; 40 }
从②、③我们可以看出来,都一段冗余的判断关闭连接等代码,而且这些非业务性代码不应该浸入系统。代码看起来也不是很清晰。那有没有办法改进呢?答案当然是有的,模板可以很好解决这种诟病。
2、使用模板+回调结果(业务按照自身的需求封装,灵活性高)的场景
①、定义一个回调接口
public interface AssemblyResService<T> { public T assemblyRes(ResultSet rs) throws SQLException; }
②、采用匿名类的方式
根据id查询
public static List<Person> getPersonById(int id) { List<Person> res = new ArrayList<Person>(); try { String sql = "select * from person where id = ?"; res = queryTemp(sql, new Object[]{id}, new AssemblyResService<Person>() { @Override public Person assemblyRes(ResultSet rs) throws SQLException { return new Person(rs.getInt("id"), rs.getString("name")); } }); return res; } catch (Exception e) { } return null; }
根据名字查询
public static List<Person> getPersonListByName(String name) { List<Person> res = new ArrayList<Person>(); try { String sql = "select * from person where name = ?"; res = queryTemp(sql, new Object[]{name}, new AssemblyResService<Person>() { @Override public Person assemblyRes(ResultSet rs) throws SQLException { return new Person(rs.getInt("id"), rs.getString("name")); } }); return res; } catch (Exception e) { } return null; }
③、模板(类似spring jdbcTemplate)
public static List<Person> queryTemp(String sql, Object[] params, AssemblyResService<Person> resService) { List<Person> res = new ArrayList<Person>(); PreparedStatement ps = null; ResultSet rs = null; try { ps = (PreparedStatement) connection.prepareStatement(sql); for(int i=0; i<params.length; i++) { ps.setObject(i+1, params[i]); } rs = ps.executeQuery(); while (rs.next()) { res.add(resService.assemblyRes(rs)); } return res; } catch (SQLException e) { e.printStackTrace(); } finally { if (connection != null) { try { connection.close(); } catch (SQLException e) { } } if (ps != null) { try { ps.close(); } catch (SQLException e) { } } if (rs != null) { try { rs.close(); } catch (SQLException e) { } } } return null; }
时间: 2024-10-20 16:20:36