日期:2014-05-16 浏览次数:20421 次
背景: 
1.??? 需要将数据库查询结果在JSP中以列表方式显示 
2.??? 在一个良好的J2EE模式中数据库查询一般用DAO实现(Data Access Object), JSP仅用于显示数据 
?
问题: 
??? 通过JDBC ResultSet可获取查询结果(存在于数据库缓冲区内),但在Statement、Connection关闭后ResultSet即不可用。因此需要一种方式取出所有查询结果并传递至JSP页面。 
?
解决方法一: 
??? 使用Value Object。将每条记录均封装成JavaBean对象,把这些对象装入Collection传送给JSP显示。这种方法的缺点是每一种查询都需要定义一个java class,并且将记录数据封装成java对象时也需要很多额外的代码。 
示例代码:
?
//查询数据代码 
? Connection conn = DBUtil.getConnection(); 
? PreparedStatement pst = null; 
? ResultSet rs = null; 
? try{ 
??? String sql=“select emp_code, real_name from t_employee where organ_id=?”; 
??? pst = conn.preparedStatement(sql); 
??? pst.setString(1, “101”); 
??? ResultSet rs = pst.executeQuery(); 
??? List list = new ArrayList(); 
??? Employee emp; 
??? while (rs.next()){ 
????? emp = new Employee(); 
????? emp.setReakName(rs.getString(“real_name”)); 
????? emp.setEmpCode(rs.getString(“emp_code”)); 
????? … 
????? list.add(emp); 
??? } 
??? return list; 
? }finally{ 
??? DBUtil.close(rs, pst ,conn); 
? } 
//jsp显示部分代码 
<% 
? List empList = (List)request.getAttribute(“empList”); 
? if (empList == null) empList = Collections.EMPTY_LIST; 
%> 
… 
<table? cellspacing="0" width=”90%”> 
??? <tr>? <td>代码</td> <td>姓名</td>? </tr> 
<% 
? Employee emp; 
? for (int i=0; i< empList.size(); i++){ 
??? emp = (Employee) empList.get(i); 
%> 
??? <tr>?? 
????? <td><%= emp.getEmpCode()%></td>? 
????? <td><%= emp.getRealName()%></td>?? 
??? </tr> 
<% 
? }// end for 
%> 
</table> 
解决方法二: 
??? 遍历ResultSet取出所有数据封装进Collection。 
具体做法: 
1.??? 生成一个List对象(List list = new ArrayList() )。 
2.??? 生成一个Map对象(Map map = new HashMap() )。使用Map封装一行数据,key为各字段名,value为对应的值。(map.put(“USER_NAME”), rs.getString(“USER_NAME”)) 
3.??? 将第2 步生成的Map对象装入第1步的list对象中(list.add(map) )。 
4.??? 重复2、3步直到ResultSet遍历完毕 
在DBUtil. resultSetToList(ResultSet rs)方法中实现了上述过程(所有列名均使用大写),可参考使用。 
示例代码:
?
//查询数据部分代码: 
? … 
? Connection conn = DBUtil.getConnection(); 
? PreparedStatement pst = null; 
? ResultSet rs = null; 
? try{ 
??? String sql=“select emp_code, real_name from t_employee where organ_id=?”; 
??? pst = conn.preparedStatement(sql); 
??? pst.setString(1, “101”); 
??? rs = pst.executeQuery(); 
??? List list = DBUtil. resultSetToList(ResultSet rs); 
??? return list; 
? }finally{ 
??? DBUtil.close(rs, pst ,conn); 
? } 
?
//JSP显示部分代码 
<% 
? List empList = (List)request.getAttribute(“empList”); 
? if (empList == null) empList = Collections.EMPTY_LIST; 
%> 
… 
<table? cellspacing="0" width=”90%”> 
??? <tr>? <td>代码</td> <td>姓名</td>? </tr> 
<% 
? Map colMap; 
? for (int i=0; i< empList.size(); i++){ 
??? colMap = (Map) empList.get(i); 
%> 
? <tr>?? 
??? <td><%=colMap.get(“EMP_CODE”)%></td>? 
??? <td><%=colMap.get(“REAL_NAME”)%></td>?? 
? </tr> 
<% 
? }// end for 
%> 
</table> 
解决方法三: 
??? 使用RowSet。 
RowSet是JDBC2.0中提供的接口,Oracle对该接口有相应实现,其中很有用的是oracle.jdbc.rowset.OracleCachedRowSet。 OracleCachedRowSet实现了ResultSet中的所有方法,但与ResultSet不同的是,OracleCachedRowSet中的数据在Connection关闭后仍然有效。 
oracle的rowset实现在http://otn.oracle.com/software/content.html的jdbc下载里有,名称是ocrs12.zip
示例代码:
//查询数据部分代码: 
? import javax.sql.RowSet; 
? import oracle.jdbc.rowset.OracleCachedRowSet; 
? … 
? Connection conn = DBUtil.getConnection(); 
? PreparedStatement pst = null; 
? ResultSet rs = null; 
? try{…… 
??? String sql=“select emp_code, real_name from t_employee where organ_id=?”; 
??? p