分页查询:
1.逻辑分页查询:用户第一次访问时就把全部数据访问出来,添加到一个大集合中,然后放到session中,进行转发。通过页码等的计算,把要显示的内容添加到一个小集合中,转发、遍历小集合以显示当前页码的数据
代码实现:
Dao:
package general.page.query;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.SQLException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
public class PageQueryDao {
private static Connection con=null; private static PreparedStatement prst=null; private static ResultSet rs=null; public static<T> List<T> pageQuery(Class<T> clazz,String sql,Object...objects) throws SQLException, InstantiationException, IllegalAccessException, InvocationTargetException{ List<T> beanList=new ArrayList<T>(); Connection con=C3P0Tool.getConnection(); prst=con.prepareCall(sql); for(int i=0;i<objects.length;i++){ prst.setObject(i+1,objects[i]); } rs=prst.executeQuery(); List<String> columnLabelList=getColumnlabel(rs); Map<String,Object> map=new HashMap<String,Object>(); List<Map<String,Object>> list=new ArrayList<Map<String,Object>>(); while(rs.next()){ if(columnLabelList.size()>0){ for(String columnLabel:columnLabelList){ Object fieldValue=rs.getObject(columnLabel); map.put(columnLabel, fieldValue); } } } list.add(map);//增强for遍历,要判断集合是否为空
if(list.size()>0){ T t=null; for(Map<String,Object> mapList:list){ for(Map.Entry<String, Object> entry:map.entrySet()){ t=clazz.newInstance(); String columnlabel=entry.getKey(); Object fieldValue=entry.getValue(); BeanUtils.setProperty(t, columnlabel, fieldValue); } } beanList.add(t); } return beanList; } public static List<String> getColumnlabel(ResultSet rs) throws SQLException{ List<String> columnLabelList=new ArrayList<String>(); ResultSetMetaData rsmd=rs.getMetaData(); int columnCount=rsmd.getColumnCount(); for(int i=0;i<columnCount;i++){ String columnLabel=rsmd.getColumnLabel(columnCount+1); columnLabelList.add(columnLabel); } return columnLabelList; }
}
Servlet:
package general.page.query;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;public class pageQueryServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); int pageNo=Integer.parseInt(request.getParameter("pageNo")==null?"1":request.getParameter("pageNo")); int pageSize=10; HttpSession session=request.getSession(); List<Student> bigList = (List<Student>)session.getAttribute("bigList"); //如果第一次访问 if(bigList == null){//实体类的字段名,要与属性的别名相同
String sql="select sno no,sname name,ssex sex,sbirth birth,zno zn,sclass zclass from student"; try { bigList=new ArrayList<Student>(); bigList=PageQueryDao.pageQuery(Student.class, sql); session.setAttribute("bigList", bigList); request.getRequestDispatcher("/show.jsp").forward(request, response); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
//添加显示记录的小集合
List<T> smallList=new ArrayList<T>();
//计算显示的记录从几行到几行
//定义开始行
int beginIndex=pageSize*(pageNo-1);
//定义结束行
int endIndex=pageSize*pageNo>bigList.size()?bigList.size():pageSize*pageNo;
//注意:集合的索引是从零开始的
for(int i=beginIndex;i<endIndex;i++){
smallList.add(bigList.get(i));
}
request.setAttribute("smallList",smallList);
//转发
2.物理分页查询:通过分页查询的SQL进行查询,所查询的结果集中的内容就是当前页面要显示的内容
代码实现:(以Student类,MySQL数据库(sql="select * from tbName limit ? offset ?")为例,limit限制显示的size,offset跳过前pageNo-1页的记录)
public List<Student> getStudentList(int pageNo,int pageSize String sql){
List<Student> list=new ArrayList<Student>();
Connection con=null;
PreparedStatement prst=null;
ResultSet rs=null;
con=c3p0.getConnection();
prst=con.prepareStatement(sql);
prst.setInt(1,pageSize);
prst.setInt(2,pageSize*(pageNo-1));
rs.executeQuery();
while(rs.next()){
Student student=new Student();
student.setString(rs.get(1));
.
.
.
}
list.add(student);
//转发
}
总结逻辑分页查询和物理分页查询的区别:
逻辑分页查询:
1.是把所有的相关记录都查出来,然后再通过计算得出在显示页面上要显示的记录,不实实在在的对记录进行分页。
2.如果需要查询的数据量过大,session将耗费大量的内存; 3.因为是在session中获取数据,如果第二次或者更多此的不关闭浏览器访问,会直接访问session,从而不能保证数据是最新的。
3.这种分页很少使用。但是在数据量小,不会被修改的数据,使用逻辑分页会提高程序的执行效率。
物理分页查询:
1.是通过sql语句的编写只查询出想要显示的记录
2.数据能够保证最新,由于根据分页条件会查询出少量的数据,所以不会占用太多的内存。
3.物理分页使用了数据库自身带的机制,所以这样的SQL语句不通用,导致不能进行数据库的移植。