自定义MVC框架(是一个分页案列 )

来源:互联网 发布:java 接口 抽象类 编辑:程序博客网 时间:2024/06/05 07:06

自定义MVC框架 (中)

街上上次的增删改这次的来了个分页的后台

一个案列   只有后台

到junit进行测试


前台的过几天补上


首先我们要有个控制分页的类

package util;


import java.io.Serializable;
import java.util.Map;


import javax.servlet.http.HttpServletRequest;


public class PageBean implements Serializable {


private static final long serialVersionUID = -7544706514503688395L;


// 三个要素
private int pindex = 1;
private int psize = 10;
private int rows;


private String url;
private Map<String, String> parameterMap;


/**
* 初始化参数
* @param request
*/
public void setRequest(HttpServletRequest request) {
this.setPindex(request.getParameter("pindex"));
this.setPsize(request.getParameter("psize"));
this.url = request.getContextPath() + request.getServletPath();
this.parameterMap = request.getParameterMap();
}
//设置第几页
private void setPindex(String pindex) {
if(pindex!=null&&!"".equals(pindex.trim())){
this.pindex=Integer.parseInt(pindex);
}
}
//设置每页显示多少
private void setPsize(String psize) {
if(psize!=null&&!"".equals(psize.trim())){
this.psize=Integer.parseInt(psize);
}
}

public int getPindex() {
return pindex;
}


public void setPindex(int pindex) {
this.pindex = pindex;
}


public int getPsize() {
return psize;
}


public void setPsize(int psize) {
this.psize = psize;
}


public int getRows() {
return rows;
}


public void setRows(int rows) {
this.rows = rows;
}


public String getUrl() {
return url;
}


public Map<String, String> getParameterMap() {
return parameterMap;
}

//首先获得最大值
public int getMaxNumber(){
int max=this.rows/this.psize;
max=this.rows%this.psize==0?max:max+1;
return max;
}

//然后是下一页
public int getNextNumber(){
int nextNumber=this.pindex+1;
nextNumber=nextNumber<this.getMaxNumber()?nextNumber:this.getMaxNumber();
return nextNumber;
}


//上一页
public int getBeforeNumber(){
int beforeNumber=this.pindex-1;
beforeNumber=beforeNumber<1?1:beforeNumber;
return beforeNumber;
}

//开始页码(下标)
public int getStartNumber(){
return (this.pindex-1)*this.psize;
}

//结束页码(下标)
public int getEndNumber(){
return this.pindex*this.psize-1;
}

}


然后又个base这个就是每个都是会用到分页的只要写一次就好了  以后进行调用就是

是一个万能的分页

package base;


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


import util.DBHepler;
import util.PageBean;


public class BaseDao {

/**
* 回调函数  专门用来遍历rs
* @author Administrator
*
*/
public static interface ForeachCallback{
public List<?> foreach(ResultSet rs) throws SQLException;
}


/**
* 分页的方法
* @param sql  传过来的sql语句
* @param pageBean  要进行一个分页的赋值
* @param foreachCallback 最后的结果集采用回调函数
* @return list集合  ?代表未知类型
*/
public List<?> executeQuery(String sql,PageBean pageBean,ForeachCallback foreachCallback){
//三个对象
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;

try {
conn=DBHepler.getConn();
//  第一次查满足条件的总记录数
int rows = queryRows(conn, sql);
//为pageBean里面的rows进行赋值
pageBean.setRows(rows);

//第二次查指定页码并满足条件的记录(调用方法转化好的sql语句)
ps=conn.prepareStatement(this.converSql(sql, pageBean));

rs=ps.executeQuery();
//使用回调接口来进行一个动态的遍历rs
return foreachCallback.foreach(rs);
} catch (Exception e) {
throw new RuntimeException(e);
}finally{
DBHepler.myClose(conn, ps, rs);
}

}

//首先第一步是取到  总行数(要从后台取出来  于是需要conn的对象因为要去找数据库)
private int queryRows(Connection conn,String sql){
PreparedStatement ps=null;
ResultSet rs=null;
int count=0;
try {
//调用转为查询全部的sql语句
ps=conn.prepareStatement(this.converSql(sql));
rs=ps.executeQuery();
if(rs.next()){
count = rs.getInt(1);
}
//System.out.println(count);
return count;
} catch (Exception e) {
throw new RuntimeException(e);
}finally{
//conn对象不关闭是因为还有个二次查询
DBHepler.myClose(null, ps, rs);
}
}

/**
* 将普通的sql语句转成查询总行数的sql语句
* @param sql
* @return
*/
private String converSql(String sql){
//全部转为小写  (只有一个是不能进行排序的所以需要截取  转为小写是因为传过来的值是区分大小写的)
String s1=sql.toLowerCase();
sql=sql.substring(0,s1.indexOf("order by"));
String newSql="select count(*) from ("+sql+") t";
//System.out.println(newSql);
return newSql;
}

/**
* 将普通的sql语句转成查询有条件的sql语句
* @param sql
* @param pageBean
* @return
*/
private String converSql(String sql,PageBean pageBean){
//全部转为小写 ss用来找 (只有一个是不能进行排序的所以需要截取  转为小写是因为传过来的值是区分大小写的)
String ss=sql.toLowerCase();
//将sql代码分成两个部分  一order by来进行区分(前面部分)
String s1=sql.substring(0,ss.indexOf("order by"));
//后面部分
String s2=sql.substring(ss.indexOf("order by"));
s2=" ROW_NUMBER() OVER("+s2+") as rownum,"; 

//System.out.println(s2);

StringBuffer sf=new StringBuffer(s1.trim());
//从第六个字符开始插入
sf.insert(6, s2);
//System.out.println(sf);
//新创建一个字符用来拼接
StringBuffer sb=new StringBuffer();
sb.append("with t1 as( ");
sb.append(sf);
sb.append(") select * from t1 where rownum between "+(pageBean.getStartNumber()+1)+" and "+(pageBean.getEndNumber()+1)+"");
//System.out.println(sb);

return sb.toString();
}



}


上面那个BaseDao里面一个回调接口  作用就是遍历rs对象

下面是实现这个这个接口的的用法   

是一个分页的dao方法(有加上模糊查询)

/**
* 分页的查询所有
* @param b  book对象
* @param pageBean  分页类
* @return   List<Book>
*/
@SuppressWarnings("unchecked")
public List<Book> list(Book b,PageBean pageBean){
if(b.getBook_name()==null){
b.setBook_name("");
}
String sql="select * from t_book where book_name like '%"+b.getBook_name()+"%' order by book_id";

//返回值(就是调用了BaseDao里面的方法    然后回调接口调用方法来进行为对象赋值转入集合当中)
return (List<Book>)this.executeQuery(sql, pageBean,new ForeachCallback() {

public List<?> foreach(ResultSet rs) throws SQLException{
List<Book> lt=new ArrayList<Book>();
while(rs.next()){
Book b=new Book();
b.setBook_id(rs.getInt("book_id"));
b.setBook_name(rs.getString("book_name"));
b.setBook_isbn(rs.getString("book_isbn"));

b.setBook_price(rs.getFloat("book_price"));
b.setBook_brief(rs.getString("book_brief"));
b.setBook_category_id(rs.getInt("book_category_id"));
lt.add(b);
}
return lt;
}
});
}


这个分页是万能的  只需要写一次   之前学过的那个分页就是会要求要写很多遍

虽然有点复杂  但是很实用

小伙伴们赶快get起来吧~~~





原创粉丝点击