分页技术原理与实现之Java+Oracle代码实现分页(二)

紧接着上篇—分页技术原理与实现之分页的意义及方法(一) ,本篇继续分析分页技术。上篇讲的是分页技术的简单原理与介绍,这篇深入分析一下分页技术的代码实现。
上篇最后讲到了分页的最佳实现是在数据库层进行分页,而且不同的数据库有不同的分页实现,比如Oracle是用三层sql嵌套实现分页的、MySQL是用limit关键字实现的(上篇已讲到)。
这篇以Java+Oracle为基础,讲解代码层的实现
就如平时我们很在分页中看到的,分页的时候返回的不仅包括查询的结果集(List),而且还包括总的页数(pageNum)、当前第几页(pageNo)等等信息,所以我们封装一个查询结果PageModel类,代码如下:

package kane;
import java.util.List;
public class PageModel<E> {
 private List<E> list;
 private int pageNo;
 private int pageSize;
 private int totalNum;
 private int totalPage;

 public List<E> getList() {
 return list;
 }

 public void setList(List<E> list) {
 this.list = list;
 }

 public int getPageNo() {
 return pageNo;
 }

 public void setPageNo(int pageNo) {
 this.pageNo = pageNo;
 }

 public int getPageSize() {
 return pageSize;
 }

 public void setPageSize(int pageSize) {
 this.pageSize = pageSize;
 }

 public int getTotalNum() {
 return totalNum;
 }

 public void setTotalNum(int totalNum) {
 this.totalNum = totalNum;
 setTotalPage((getTotalNum() % pageSize) == 0 ? (getTotalNum() / pageSize)
 : (getTotalNum() / pageSize + 1));
 }

 public int getTotalPage() {
 return totalPage;
 }

 public void setTotalPage(int totalPage) {
 this.totalPage = totalPage;
 }

 // 获取第一页
 public int getFirstPage() {
 return 1;
 }

 // 获取最后页
 public int getLastPage() {
 return totalPage;
 }

 // 获取前页
 public int getPrePage() {
 if (pageNo > 1)
 return pageNo - 1;
 return 1;
 }

 // 获取后页
 public int getBackPage() {
 if (pageNo < totalPage)
 return pageNo + 1;
 return totalPage;
 }

 // 判断'首页'及‘前页'是否可用
 public String isPreable() {
 if (pageNo == 1)
 return "disabled";
 return "";
 }

 // 判断'尾页'及‘下页'是否可用
 public String isBackable() {
 if (pageNo == totalPage)
 return "disabled";
 return "";
 }
}

其中使用泛型是为了能使的该分页类能进行重用,比如在查询用户时可以封装User对象、在查询财务中的流向单时可以封装流向单FlowCard类。
我们以查询用户为例,用户选择查询条件,首先调用Servlet获取查询参数,然后请求业务逻辑层取得分页封装结果类。业务逻辑调用Dao层取得结果集、取得中记录数封装成分页类。最后Servlet将结果设置到jsp页面显示。
首先来讲解Servlet,代码如下:

package kane;
import java.io.*;
import java.util.*;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kane.UserInfo;
import kane.UserInfoManage;
import kane.PageModel;

public class UserBasicSearchServlet extends HttpServlet {
 private static final long serialVersionUID = 1L;
 private int pageSize = 0;

 @Override
 public void init(ServletConfig config) throws ServletException {
 pageSize = Integer.parseInt(config.getInitParameter("pageSize"));
 }

 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
 throws ServletException, IOException {
 doPost(req, resp);
 }

 @Override
 protected void doPost(HttpServletRequest req, HttpServletResponse resp)
 throws ServletException, IOException {
 // 1.取得页面参数并构造参数对象
 int pageNo = Integer.parseInt(req.getParameter("pageNo"));
 String sex = req.getParameter("gender");
 String home = req.getParameter("newlocation");
 String colleage = req.getParameter("colleage");
 String comingyear = req.getParameter("ComingYear");

 UserInfo u = new UserInfo();
 u.setSex(sex);
 u.setHome(home);
 u.setColleage(colleage);
 u.setCy(comingyear);

 // 2.调用业务逻辑取得结果集
 UserInfoManage userInfoManage = new UserInfoManage();
 PageModel<UserInfo> pagination = userInfoManage.userBasicSearch(u,
 pageNo, pageSize);
 List<UserInfo> userList = pagination.getList();

 // 3.封装返回结果
 StringBuffer resultXML = new StringBuffer();
 try {
 resultXML.append("<?xml version='1.0' encoding='gb18030'?>/n");
 resultXML.append("<root>/n");
 for (Iterator<UserInfo> iterator = userList.iterator(); iterator
 .hasNext();) {
 UserInfo userInfo = iterator.next();
 resultXML.append("<data>/n");
 resultXML.append("/t<id>" + userInfo.getId() + "</id>/n");
 resultXML.append("/t<truename>" + userInfo.getTruename()
 + "</ truename >/n");
 resultXML.append("/t<sex>" + userInfo.getSex() + "</sex>/n");
 resultXML.append("/t<home>" + userInfo.getHome() + "</home>/n");
 resultXML.append("</data>/n");
 }
 resultXML.append("<pagination>/n");
 resultXML.append("/t<total>" + pagination.getTotalPage()
 + "</total>/n");
 resultXML.append("/t<start>" + pagination.getFirstPage()
 + "</start>/n");
 resultXML.append("/t<end>" + pagination.getLastPage() + "</end>/n");
 resultXML.append("/t<pageno>" + pagination.getPageNo()
 + "</pageno>/n");
 resultXML.append("</pagination>/n");

 resultXML.append("</root>/n");
 } catch (Exception e) {
 e.printStackTrace();
 }
 writeResponse(req, resp, resultXML.toString());

 }

 public void writeResponse(HttpServletRequest request,
 HttpServletResponse response, String result) throws IOException {
 response.setContentType("text/xml");
 response.setHeader("Cache-Control", "no-cache");
 response.setHeader("Content-Type", "text/xml; charset=gb18030");
 PrintWriter pw = response.getWriter();
 pw.write(result);
 pw.close();
 }
}

其中User对象代码如下:

package kane;
import java.util.Date;
public class UserInfo {
 private int id;
 private String username;
 private String password;
 private String truename;
 private String sex;
 private Date birthday;
 private String home;
 private String colleage;
 private String comingYear;

 public int getId() {
 return id;
 }

 public void setId(int id) {
 this.id = id;
 }

 public String getUsername() {
 return username;
 }

 public void setUsername(String username) {
 this.username = username;
 }

 public String getPassword() {
 return password;
 }

 public void setPassword(String password) {
 this.password = password;
 }

 public String getTruename() {
 return truename;
 }

 public void setTruename(String truename) {
 this.truename = truename;
 }

 public String getSex() {
 return sex;
 }

 public void setSex(String sex) {
 this.sex = sex;
 }

 public Date getBirthday() {
 return birthday;
 }

 public void setBirthday(Date birthday) {
 this.birthday = birthday;
 }

 public String getHome() {
 return home;
 }

 public void setHome(String home) {
 this.home = home;
 }

 public String getColleage() {
 return colleage;
 }

 public void setColleage(String colleage) {
 this.colleage = colleage;
 }

 public String getCy() {
 return comingYear;
 }

 public void setCy(String cy) {
 this. comingYear= cy;
 }
}

接着是业务逻辑层代码,代码如下:

package kane;
import java.sql.Connection;

import kane.DBUtility;
import kane.PageModel;

public class UserInfoManage {
 private UserInfoDao userInfoDao = null;

 public UserInfoManage () {
 userInfoDao = new UserInfoDao();
 }

 public PageModel<UserInfo> userBasicSearch(UserInfo u, int pageNo,
 int pageSize) throws Exception {
 Connection connection = null;
 PageModel<UserInfo> pagination = new PageModel<UserInfo>();
 try {
 connection = DBUtility.getConnection();
 DBUtility.setAutoCommit(connection, false);
 pagination.setList(userInfoDao.getUserList(u, pageNo, pageSize));
 pagination.setPageNo(pageNo);
 pagination.setPageSize(pageSize);
 pagination.setTotalNum(userInfoDao.getTotalNum(u));
 DBUtility.commit(connection);
 } catch (Exception e) {
 DBUtility.rollBack(connection);
 e.printStackTrace();
 throw new Exception();
 } finally {
 DBUtility.closeConnection();
 }
 return pagination;
 }
}

其中DBUtility为数据库的连接封装类。
最后是Dao层代码实现,代码如下:

package kane;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import kane.UserInfo;
import kane.DBUtility;

public class UserInfoDao {

 public List<UserInfo> getUserList(UserInfo userInfo, int pageNo,
 int pageSize) throws Exception {
 PreparedStatement pstmt = null;
 ResultSet rs = null;
 List<UserInfo> userList = null;
 try {
 String sql = "select * from(select rownum num,u.* from(select * from user_info where sex = ? and home like '"
 + userInfo.getHome()
 + "%"
 + "' and colleage like '"
 + userInfo.getColleage()
 + "%"
 + "' and comingyear like '"
 + userInfo.getCy()
 + "%"
 + "' order by id) u where rownum<=?) where num>=?";
 userList = new ArrayList<UserInfo>();
 Connection conn = DBUtility.getConnection();
 pstmt = conn.prepareStatement(sql);
 pstmt.setString(1, userInfo.getSex());
 pstmt.setInt(2, pageNo * pageSize);
 pstmt.setInt(3, (pageNo - 1) * pageSize + 1);
 rs = pstmt.executeQuery();
 while (rs.next()) {
 UserInfo user = new UserInfo();
 user.setId(rs.getInt("id"));
 user.setTruename(rs.getString("truename"));
 user.setSex(rs.getString("sex"));
 user.setHome(rs.getString("home"));
 userList.add(user);
 }
 } catch (SQLException e) {
 e.printStackTrace();
 throw new Exception(e);
 } finally {
 DBUtility.closeResultSet(rs);
 DBUtility.closePreparedStatement(pstmt);
 }
 return userList;
 }

 public int getTotalNum(UserInfo userInfo) throws Exception {
 PreparedStatement pstmt = null;
 ResultSet rs = null;
 int count = 0;
 try {
 String sql = "select count(*) from user_info where sex=? and home like '"
 + userInfo.getHome()
 + "%"
 + "' and colleage like '"
 + userInfo.getColleage()
 + "%"
 + "' and comingyear like '"
 + userInfo.getCy()+ "%" + "'";
 Connection conn = DBUtility.getConnection();
 pstmt = conn.prepareStatement(sql);
 pstmt.setString(1, userInfo.getSex());
 rs = pstmt.executeQuery();
 if (rs.next()) {
 count = rs.getInt(1);
 }
 } catch (SQLException e) {
 e.printStackTrace();
 throw new Exception(e);
 } finally {
 DBUtility.closeResultSet(rs);
 DBUtility.closePreparedStatement(pstmt);
 }
 return count;
 }
}

最后就是servlet将得到的结果返回给jsp页面显示出来。
注:其中DBUtility代码是封装数据库连接操作的代码,如下:

package kane;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DBUtility {
 private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();

 public static Connection getConnection() {
 Connection conn = null;
 conn = threadLocal.get();
 if (conn == null) {
 try {
 Class.forName("oracle.jdbc.driver.OracleDriver");
 conn = DriverManager.getConnection(
 "jdbc:oracle:thin:@localhost:1521:oracle", "admin",
 "admin");
 threadLocal.set(conn);
 } catch (ClassNotFoundException e) {
 e.printStackTrace();
 } catch (SQLException e) {
 e.printStackTrace();
 }
 }
 return conn;
 }

 // 封装设置Connection自动提交
 public static void setAutoCommit(Connection conn, Boolean flag) {
 try {
 conn.setAutoCommit(flag);
 } catch (SQLException e) {
 e.printStackTrace();
 }
 }

 // 设置事务提交
 public static void commit(Connection conn) {
 try {
 conn.commit();
 } catch (SQLException e) {
 e.printStackTrace();
 }
 }

 // 封装设置Connection回滚
 public static void rollBack(Connection conn) {
 try {
 conn.rollback();
 } catch (SQLException e) {
 e.printStackTrace();
 }
 }

 // 封装关闭Connection、PreparedStatement、ResultSet的函数
 public static void closeConnection() {
 Connection conn = threadLocal.get();
 try {
 if (conn != null) {
 conn.close();
 conn = null;
 threadLocal.remove();
 }
 } catch (SQLException e) {
 e.printStackTrace();
 }

 }

 public static void closePreparedStatement(PreparedStatement pstmt) {
 try {
 if (pstmt != null) {
 pstmt.close();
 pstmt = null;
 }
 } catch (SQLException e) {
 e.printStackTrace();
 }
 }

 public static void closeResultSet(ResultSet rs) {
 try {
 if (rs != null) {
 rs.close();
 rs = null;
 }
 } catch (SQLException e) {
 e.printStackTrace();
 }
 }
}

使用ThreadLocal是为了保证事务的一致,使得同一个线程的所有数据库操作使用同一个Connection。
到此一个简单的代码实现就完成了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java中四种XML解析技术

    在平时工作中,难免会遇到把 XML 作为数据存储格式.面对目前种类繁多的解决方案,哪个最适合我们呢?在这篇文章中,我对这四种主流方案做一个不完全评测,仅仅针对遍历 XML 这块来测试,因为遍历 XML 是工作中使用最多的(至少我认为). 预 备 测试环境: AMD 毒龙1.4G OC 1.5G.256M DDR333.Windows2000 Server SP4.Sun JDK 1.4.1+Eclipse 2.1+Resin 2.1.8,在 Debug 模式下测试. XML 文件格式如下: <?

  • JAVA Web实时消息后台服务器推送技术---GoEasy

    越来越多的项目需要用到实时消息的推送与接收,我这里推荐大家使用GoEasy, 它是一款第三方推送服务平台,使用它的API可以轻松搞定实时推送! 浏览器兼容性:GoEasy推送 支持websocket 和polling两种连接方式,从而可以支持IE6及其以上的所有版本,同时还支持其它浏览器诸如Firefox, Chrome, Safari等等. 支持不同的开发语言:GoEasy推送 提供了Restful API接口,无论你的后台程序用的是哪种语言都可以通过Restful API来实现后台实时推送.

  • java的poi技术读取和导入Excel实例

    报表输出是Java应用开发中经常涉及的内容,而一般的报表往往缺乏通用性,不方便用户进行个性化编辑.Java程序由于其跨平台特性,不能直接操纵Excel.因此,本文探讨一下POI视线Java程序进行Excel的读取和导入. 项目结构: java_poi_excel 用到的Excel文件: xls XlsMain .java 类 //该类有main方法,主要负责运行程序,同时该类中也包含了用poi读取Excel(2003版) import java.io.FileInputStream; impor

  • JAVA使用JDBC技术操作SqlServer数据库实例代码

    JDBC(Java Data Base Connectivity,Java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成.JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序. JDBC并不能直接访问数据库,需要借助于数据库厂商提供的JDBC驱动程序. 数据库连接 如果要在Java访问数据库,首先要加载一个数据库驱动,数据库驱动只需要在第一次访问时加载一次.然后再每次访问

  • PHP、JAVA、.NET这三种技术的区别分析

    其实这三种编程技术各有优势,我们大概可以从语言.平台这二点来区分: 一.语言: PHP:PHP产生与1994年,其语法混合了C.Java.Perl 和他自创的一些编程语法:PHP是嵌入在HTML中执行的:它也是一种解释性语言.早期的PHP并非完全的面向对象编程语言,到了PHP4以后的版本才开始有了面向对象的概念. JAVA:JAVA产生与1995年,JAVA语言和JAVA平台统称为JAVA:它语法与C语言和C++语言很接近,并且JAVA是面向对象编程语言,JAVA是编译性语言,可以先将JAVA源

  • Java实现远程控制技术完整源代码分享

    Java实现远程控制技术 java自带的java.net.和java.awt.robot. 的混合可以用于实现通过网络对另一台计算机的远程控制,其中包括控制远程计算机鼠标的动作和键盘的输入,以及实时获得远程计算机屏幕的图像.本文将用简洁的语言和由浅入深的逻辑,教大家如何掌握这个技术. 首先先看一下效果图: 远程端计算机界面: 控制端计算机界面: 控制端输入: 远程端输入: 一下开始详细介绍远程控制的技术思路. 首先两台计算机通过java.net的Socket来进行连接. 一端先打开一个Serve

  • 总结Java常用到的六个加密技术和代码

    加密,是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信息的内容.大体上分为双向加密和单向加密,而双向加密又分为对称加密和非对称加密(有些资料将加密直接分为对称加密和非对称加密). 双向加密大体意思就是明文加密后形成密文,可以通过算法还原成明文.而单向加密只是对信息进行了摘要计算,不能通过算法生成明文,单向加密从严格意思上说不能算是加密的一种,应该算是摘要算法吧. 具体来说: 系统必须可用,非数学上不可译码. 系统不一定要保密,可以轻

  • 识别率很高的java文字识别技术

    java文字识别程序的关键是寻找一个可以调用的OCR引擎.tesseract-ocr就是一个这样的OCR引擎,在1985年到1995年由HP实验室开发,现在在Google.tesseract-ocr 3.0发布,支持中文.不过tesseract-ocr 3.0不是图形化界面的客户端,别人写的FreeOCR图形化客户端还不支持导入新的 3.0 traineddata.但这标志着,现在有自由的中文OCR软件了. java中使用tesseract-ocr3.01的步骤如下: 1.下载安装tessera

  • 你应该知道的21个Java核心技术

    写这篇文章的目的是想总结一下自己这么多年来使用java的一些心得体会,主要是和一些java基础知识点相关的,所以也希望能分享给刚刚入门的Java程序员和打算入Java开发这个行当的准新手们,希望可以给大家一些经验,能让大家更好学习和使用Java. 这次介绍的主要内容是和J2SE相关的部分,另外,会在以后再介绍些J2EE相关的.和Java中各个框架相关的内容. 经过这么多年的Java开发,以及结合平时面试Java开发者的一些经验,我觉得对于J2SE方面主要就是要掌握以下的一些内容. 1. JVM相

  • Java UrlRewriter伪静态技术运用深入分析

    通常我们为了更好的缓解服务器压力,和增强搜索引擎的友好面,都将文章内容生成静态页面. 但是有时为了能实时的显示一些信息,或者还想运用动态脚本解决一些问题,不能用静态的方式来展示网站内容,必须用到动态页面显示. 这样以来,就损失了对搜索引擎的友好面,怎么样在两者之间找个中间方法呢,如何增强你网站中地址的可读性和让搜索引擎快速的收录到你的站点? 这就需要你美化你的网页的地址,这就产生了伪静态技术,也就是我们常说的Url Rewriter重写技术.就是当我们访问一个页面时,地址栏中展示出来的是以".h

随机推荐