案例:
分页三要素
后台:
- entity
- dao
视图层
效果图
分页三要素
page=1 页码 视图层传递过来
rows=10 页大小 视图层传递过来
total=0 总记录数 后台查出来
pagination=true 是否分页 视图层传递过来
getStartIndex() 基于MySql数据库分页,获取分页开始标记
(page-1)*rows
实体类(entity)
属性、get/set方法,toString
private int sid;
private String sname;
private String sname_pinyin;
private int age;
private String remark;
public Student() {
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
this.sname_pinyin = PinYinUtil.toPinyin(this.sname);
}
public String getSname_pinyin() {
return sname_pinyin;
}
public void setSname_pinyin(String sname_pinyin) {
this.sname_pinyin = sname_pinyin;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
@Override
public String toString() {
return "Student [sid=" + sid + ", sname=" + sname + ", sname_pinyin=" + sname_pinyin + ", age=" + age
+ ", remark=" + remark + "]";
}
dao包
增删改查方法,其中以分页查为重点,只放了分页的代码
public List<Student> find(Student student,PageBean pageBean){
List<Student> studentList = new ArrayList<Student>();
//where 1=1 为后面的模糊查询做准备, 作用是生成where子句
String sql ="select * from t_student where 1=1";
if(StringUtils.isNotBlank(student.getSname())) {
sql+=" and (sname like '%"+ student.getSname() +"%' or sname_pinyin like '%" +student.getSname()+ "%')";
}
return this.executeQuery(sql, pageBean,new Callback<Student>() {
@Override
public List foreach(ResultSet rs) throws SQLException {
List<Student> studentList = new ArrayList<Student>();
Student s = null;
while(rs.next()) {
s=new Student();
s.setSid(rs.getInt("sid"));
s.setSname(rs.getString("sname"));
s.setSname_pinyin(rs.getString("sname_pinyin"));
s.setAge(rs.getInt("age"));
s.setRemark(rs.getString("remark"));
studentList.add(s);
}
return studentList;
}
});
baseDao(匿名接口)
把callback接口当做是内部接口,这个接口只做分页的时候使用
public static interface Callback<k> {
public List<k> foreach(ResultSet rs) throws SQLException;
}
/**
* 通用分页查询
* @param sql 普通sql
* @param pageBean 分页工具类
* @return 集合
*/
public List<k> executeQuery(String sql, PageBean pageBean,Callback<k> callBack){
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
if(null !=pageBean && pageBean.isPagination()) {
//1、查询满足条件的总记录数
try {
con=DBAccess.getConnection();
String countSql = this.getCountSql(sql);
ps = con.prepareStatement(countSql);
System.out.println(countSql);
rs=ps.executeQuery();
if(rs.next()) {
int total = rs.getInt(1);
pageBean.setTotal(total);
}
} catch (Exception e) {
throw new RuntimeException(e);
}finally {
DBAccess.close(null, ps, rs);//这里没有关闭
}
}
//2、查询指定页码并满足条件的记录数
try {
//con = null!=con ?con:DBAccess.getConnection();
if(con==null) {
con = DBAccess.getConnection();
}
String pageSql = sql;
if(null!= pageBean && pageBean.isPagination()) {
pageSql = this.getPageSql(sql, pageBean);
}
ps = con.prepareStatement(pageSql);
System.out.println(pageSql);
rs = ps.executeQuery();
return callBack.foreach(rs);
} catch (Exception e) {
throw new RuntimeException(e);
}finally {
DBAccess.close(con, ps, rs);
}
}
/**
* 将一个普通的sql转换成查询全部的sql
*/
public String getCountSql(String sql) {
return "select count(*) from ("+sql+") t1";
}
/**
* 将一个普通的sql转换成支持分页的sql
*/
public String getPageSql(String sql,PageBean pageBean) {
return sql+ " limit "+pageBean.getStartIndex()+", "+pageBean.getRows()+"";
}
视图层(PageTag)
private PageBean pageBean;
public PageTag() {
super();
}
public PageBean getPageBean() {
return pageBean;
}
public void setPageBean(PageBean pageBean) {
this.pageBean = pageBean;
}
@Override
public int doStartTag() throws JspException {
try {
//输出
JspWriter out= this.pageContext.getOut();
out.println(this.toHtml());
//跳过标签体
return SKIP_BODY;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public String toHtml()throws Exception {
StringBuffer bf = new StringBuffer();
if(null==pageBean || !pageBean.isPagination()) {
return bf.toString();
}
//使用隐藏域,保存 请求及参数
//1、生成分页相关按钮
bf.append("<div style='text-align:center;font-size: 16px'>\r\n" +
" 当前第"+pageBean.getPage()+"页, 共"+pageBean.getMaxPage()+"页, 共"+pageBean.getTotal()+"条 \r\n" +
" <a href='javascript:doForward(1)'>首页</a> \r\n" +
" <a href='javascript:doForward("+pageBean.getPreviousPage()+")'>上一页</a> \r\n" +
" <a href='javascript:doForward("+pageBean.getNextPage()+")'>下一页</a> \r\n" +
" <a href='javascript:doForward("+pageBean.getMaxPage()+")'>尾页 </a> \r\n" +
" <input id='numTxt' type=\"text\" style='text-align: center;font-size: 16px;width: 30px' >\r\n" +
" <a href='javascript:doSkip()'>GO</a>\r\n" +
" </div>");
//2、生成分页的表单
bf.append("<form id ='pageForm' action='"+this.pageBean.getUrl()+"' method='post'>");
bf.append("<input type='hidden' name='page'>");
Map<String,String[]> parameterMap= pageBean.getParameterMap();
for(Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
String name = entry.getKey();
if("page".equals(name)) {//抛上一次的页码
continue;//跳转到下一次循环
}
String[] value = entry.getValue();
for(int i = 0; i<value.length;i++) {
bf.append("<input type='hidden' name='"+ name +"' value='"+ value[i] +"'>");
}
}
bf.append("</form>");
//3、动态生成js代码
bf.append("<script type='text/javascript'>");
bf.append(" function doForward(page){");
bf.append(" var f = document.getElementById('pageForm');");
bf.append(" f.page.value = page;");
bf.append(" f.submit();");
bf.append("}");
bf.append("");
bf.append(" function doSkip(){");
bf.append(" var num = document.getElementById('numTxt').value;");
bf.append(" if(!num || isNaN(num)||!/^[0-9]+$/.test(num)||parseInt(num)<=0||parseInt(num)>"+pageBean.getMaxPage()+"){");
bf.append(" alert(\"请输入1~"+pageBean.getMaxPage()+"之间的数字\");");
bf.append(" return;");
bf.append(" }");
bf.append(" doForward(num);");
bf.append("}");
bf.append("</script>");
return bf.toString();
效果图
注意:不能将分页表单嵌套到其它表单中,否则不能提交表单