Spring JDBC的主要目标是为了简化JDBC的编程,方便我们构建健壮的应用程序。这里,它的一个基本设计理念,就是将JDBC编程中变化的和不变化的分开。先看一段普通建立数据库连接的方式:
Java 代码:
-
public List getAvailableSeatlds(DataSource ds, int performanceld,
-
int seatType) throws ApplicationException {
-
String sql = "SELECT seat_id AS id FROM available_seats " +
-
"WHERE performance_id = ? AND price_band_id = ?";
-
List seatlds = new LinkedList();
-
Connection con = null;
-
PreparedStatement ps = null;
-
ResultSet rs = null;
-
try {
-
con = ds.getConnection(); //1。建立Connection
-
ps = con.prepareStatement(sql); //2。创建preparedStatement
-
ps.setlnt(1, performanceld); //3。设置ps的参数
-
ps.setlnt(2, seatType);
-
rs = ps.executeQuery(); //4.执行查询
-
while (rs.next()) { //5.解析ResultSet
-
int seatld = rs.getlnt(1);
-
seatlds.add(new Integer(seatld));
-
}
-
rs.close(); //6.关闭资源,做好善后工作。rs,ps,connection
-
ps.close();
-
}
-
catch (SQLException ex) {
-
throw new ApplicationException ("Couldn't run query [" + sql + "]", ex);
-
}
-
finally {
-
try {
-
if (con != null)
-
con.close(); //如果没有连接池的话,不要轻易关。connection属于耗费资源:)
-
}
-
catch (SQLException ex) {
-
// Log and ignore
-
}
-
}
-
return seatlds;
-
}
从上面看,什么是不变的。首先,咱们这个使用JDBC的方式是良好的,正确的,也是不变的,也就是workflow不变。其次,这里头的很多操作是不变的,比如说:关闭资源,处理异常。
什么是变的?设置PreparedStament的参数是变化的,利用PreparedStatement做什么是变化的。
还有什么是变的?取得Connection可能是变化的,我们可以从ConnectionPool中取,也可以裸从Database取。
还有什么是变的?在主工作流之外,还可以对PreparedStament设置一些属性。比如fetchSize等。
还有什么是变的?解析ResultSet是变的。但是可以抽象,都是从结果集中取得你想要的东西。
下面是使用JdbcTemplate的三种方式:
1.重载PreparedStatementCreator方法
重点在于从写它的createPreparedStatement方法,方法内部一般功能JDBC书写标准的。
public int add(final Groupinfo g){
final String sql = "insert into groupinfo values(?,?,?,?,?,?,?,?)";
return jdbcTemplate.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection con)
throws SQLException {
PreparedStatement ps=con.prepareStatement(sql);
ps.setString(1, null);
ps.setString(2, g.getGname());
ps.setString(3, g.getDeptName());
ps.setString(4, g.getGuser());
ps.setString(5, g.getGtel());
ps.setString(6, g.getGfax());
ps.setString(7, g.getGaddress());
ps.setString(8, g.getGpostCode());
return ps;
}
});
}
2.重载PreparedStatementSeter方法
重点在于重写setValues方法,参数是个PreparedStatement实例。
public int add(final Groupinfo g){ final String sql = "insert into groupinfo values(?,?,?,?,?,?,?,?)"; return jdbcTemplate.update(sql, new PreparedStatementSetter() { @Override public void setValues(PreparedStatement ps) throws SQLException { ps.setString(1, null); ps.setString(2, g.getGname()); ps.setString(3, g.getDeptName()); ps.setString(4, g.getGuser()); ps.setString(5, g.getGtel()); ps.setString(6, g.getGfax()); ps.setString(7, g.getGaddress()); ps.setString(8, g.getGpostCode()); } });}