title:?JSP頁面查詢顯示常用模式
author:?evan
email:?
evan_zhao@hotmail.com????
背景:
1.????需要將數(shù)據(jù)庫查詢結(jié)果在JSP中以列表方式顯示
2.????在一個(gè)良好的J2EE模式中數(shù)據(jù)庫查詢一般用DAO實(shí)現(xiàn)(Data?Access?Object),?JSP僅用于顯示數(shù)據(jù)
問題:
????通過JDBC?ResultSet可獲取查詢結(jié)果(存在于數(shù)據(jù)庫緩沖區(qū)內(nèi)),但在Statement、Connection關(guān)閉后ResultSet即不可用。因此需要一種方式取出所有查詢結(jié)果并傳遞至JSP頁面。
解決方法一:
????使用Value?Object。將每條記錄均封裝成JavaBean對象,把這些對象裝入Collection傳送給JSP顯示。這種方法的缺點(diǎn)是每一種查詢都需要定義一個(gè)java?class,并且將記錄數(shù)據(jù)封裝成java對象時(shí)也需要很多額外的代碼。
示例代碼:
- //查詢數(shù)據(jù)代碼
- ??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取出所有數(shù)據(jù)封裝進(jìn)Collection。
具體做法:
1.????生成一個(gè)List對象(List?list?=?new?ArrayList()?)。
2.????生成一個(gè)Map對象(Map?map?=?new?HashMap()?)。使用Map封裝一行數(shù)據(jù),key為各字段名,value為對應(yīng)的值。(map.put(“USER_NAME”),?rs.getString(“USER_NAME”))
3.????將第2?步生成的Map對象裝入第1步的list對象中(list.add(map)?)。
4.????重復(fù)2、3步直到ResultSet遍歷完畢
在DBUtil.?resultSetToList(ResultSet?rs)方法中實(shí)現(xiàn)了上述過程(所有列名均使用大寫),可參考使用。
示例代碼:
- //查詢數(shù)據(jù)部分代碼:
- ??…
- ??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對該接口有相應(yīng)實(shí)現(xiàn),其中很有用的是oracle.jdbc.rowset.OracleCachedRowSet。?OracleCachedRowSet實(shí)現(xiàn)了ResultSet中的所有方法,但與ResultSet不同的是,OracleCachedRowSet中的數(shù)據(jù)在Connection關(guān)閉后仍然有效。
oracle的rowset實(shí)現(xiàn)在
http://otn.oracle.com/software/content.html的jdbc下載里有,名稱是ocrs12.zip
示例代碼:
- //查詢數(shù)據(jù)部分代碼:
- ??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=?”;
- ????pst?=?conn.preparedStatement(sql);
- ????pst.setString(1,?“101”);
- ????rs?=?pst.executeQuery();
- ????OracleCachedRowSet?ors?=?newOracleCachedRowSet();
- ????//將ResultSet中的數(shù)據(jù)封裝到RowSet中
- ????ors.populate(rs);
- ????return?ors;
- ??}finally{
- ????DBUtil.close(rs,?pst,?conn);
- ??}
- //JSP顯示部分代碼
- <%
- ??javax.sql.RowSet?empRS?=?(javax.sql.RowSet)?request.getAttribute(“empRS”);
- %>
- …
- <table??cellspacing="0"?width=”90%”>
- ????<tr>??<td>代碼</td>?<td>姓名</td>??</tr>
- <%
- ??if?(empRS?!=?null)?while?(empRS.next()?)?{
- %>
- ??<tr>??
- ????<td><%=?empRS.get(“EMP_CODE”)%></td>?
- ????<td><%=?empRS.get(“REAL_NAME”)%></td>??
- ??</tr>
- <%
- ??}//?end?while
- %>
- </table>
適用場合:
??方法一使用于定制的查詢操作
??方法二適用于多條查詢語句或需要對查詢結(jié)果進(jìn)行處理的情況。
??方法三適合于單條查詢語句,適用于快速開發(fā)。
相關(guān)鏈接:
????如果需要分頁顯示請參考:
JSP分頁技術(shù)實(shí)現(xiàn)????如果查詢結(jié)果需要生成WORD或者EXCEL,請參考:
使用jsp實(shí)現(xiàn)word、excel格式報(bào)表打印附:
DBUtil代碼: