后再想办法与JDBC结合起来,这就是Java数据库开发中的层出不穷的对象包装技术。
3.1 对象包装技术
3.1.1 传统包装与演变
传统包装顾名思义,就是最初出现的包装方式,很多公司都经历过这一步,产生了很多风格各异的包装方法。当然,笔者也有过还算丰富的尝试过程。
举例来说,如果我们有一个用户类:
public class User {
public int userId;
public String name;
public java.util.Date birthday;
}
我们可以将其当作一个简单的数据类,然后写一些工具方法来实现与JDBC的交互。这些方法,我们可以放到一个另外的工具类中,也可以放到User类中作为静态方法。这些方法包括简单的增、删、改、查(以Oracle为例):
public class User {
public int userId;
public String name;
public java.util.Date birthday;
public static User addUser(String name, Date birthday) throws SQLException {
Connection conn = …; //获取一个JDBC连接
PreparedStatement ps = conn.prepareStatement("…"); // 获取一个序列值来作为用户标识
ResultSet rs = ps.executeQuery();
rs.next();
User user = new User();
user.userId = rs.getInt(1); //读取序列值为新用户标识
user.name = name;
user.birthday = birthday;
ps = conn.prepareStatement("insert into …."); //插入用户数据记录的SQL
ps.setInt(1,user.id);
ps.setString(2,user.name);
ps.setDate(3,user.birthday);
ps.executeUpdate();
rs.close();
ps.close();
conn.close();
return user;
}
public static void deleteUser(int userId) throws SQLException {
Connection conn = ….;
//…
}
public static User getById(int userId) throws SQLException {
//…
}
//…
}
Java数据对象(JDO)的前世今生(3)
时间:2010-12-05
以上就是一个简单的数据包装的基本雏形,我们可以看到,这是一个非常简单的JDBC包装,一些代码可以模块化,以实现重用。另外,这段代码还有很大隐患,就是中途如果出现异常的话,就会使系统出现JDBC资源漏洞,因为JDBC分配的资源(conn,ps,rs等)是不能被Java虚拟机的垃圾回收机制回收的。因此,我们的addUser方法就需要改成下面的样子:
public static User addUser(String name, Date birthday) throws SQLException {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
User user = new User();
try {
conn = …; //获取一个JDBC连接
ps = conn.prepareStatement("…"); // 获取一个序列值来作为用户标识
rs = ps.executeQuery();
rs.next();
user.userId = rs.getInt(1); //读取序列值为新用户标识
user.name = name;
user.birthday = birthday;
ps = conn.prepareStatement("insert into …."); //插入用户数据记录的SQL
ps.setInt(1,user.id);
ps.setString(2,user.name);
ps.setDate(3,user.birthday);
ps.executeUpdate();
} finally {
//这里注意一定要按照创建的顺序关闭JDBC资源:
if(rs != null) try { rs.close(); } catch(SQLException ex) { ex.printStackTrace(); }
if(ps != null) try { ps.close(); } catch(SQLException ex) { ex.printStackTrace(); }
if(conn != null) try { conn.close(); } catch(SQLException ex) { ex.printStackTrace(); }
}
return user;
}
所有的数据库访问方法都必须进行这样的包装,当我们的数据类达到一定的数量后(比如十几个,几十个),这些方法占据了大量的代码,维护困难、出现BUG机会增多,并且不易排错,尤其是资源漏洞这种容易引起服务器稳 |