SSM 封装base(一) 实现了简单的增删查改,此篇会加上分页功能
首先是 service层 的实现类
- 省去了上一遍中实现过的增删查改
@Service public abstract class BaseService<T> implements IBaseService<T>{ public abstract IBaseDao<T> getBaseDao(); public abstract Class<T> getClasss(); public Class<T> clsss; { clsss = getClasss(); } @Override public Page<T> queryByPage(Page<T> page) { String tableName = clsss.getSimpleName().toLowerCase(); List<T> list = new ArrayList<>(); //分页 查询 数据 (表名,分页起始位置(利用mysql的limit),每页条数,[条件]) List<HashMap<Object, Object>> listmap = getBaseDao().queryByPage( tableName, (page.getPage()-1)*page.getSize() , page.getWhere() ); // 遍历每个 Map 并通过自定义的方法转换成目标实体类,并添加到结果集list中 for (HashMap<Object, Object> hashMap : listmap) { T t1 = hashMapToEntity(hashMap); list.add( t1 ); } //将转换好的数据集合放入 Page 对象 page.setList(list); //根据条件查询数据条数 if ( page.getWhere()==null || page.getWhere().length()<=0 ) { page.setCount( queryCount( ) ); }else { page.setCount( queryCount( page.getWhere() ) ); } //数据总条数 int tmp = page.getCount()/page.getSize(); //最大页数 page.setMax(page.getCount()<=page.getSize()?1:page.getCount()%page.getSize()>0?tmp+1:tmp); return page; } /** * 将HashMap 转成 实体类对象 */ private T hashMapToEntity( Map<Object, Object> map ) { T t = null; try { t = clsss.newInstance(); for (Field f : t.getClass().getDeclaredFields()) { f.setAccessible(true); f.set(t,map.get(f.getName())); } } catch (Exception e1) { e1.printStackTrace(); } return t; } //无条件查询记录数 public int queryCount() { String tableName = clsss.getSimpleName().toLowerCase(); return getBaseDao().queryCount( tableName , "1=1" ); } //有条件的查找记录数 public int queryCount(String where) { String tableName = clsss.getSimpleName().toLowerCase(); return getBaseDao().queryCount( tableName , where ); } }
IBaseDao 接口
- 同样的省去了上一篇中实现过的方法
public interface IBaseDao <T> { List<HashMap<Object, Object>> queryByPage( @Param("name")String name, @Param("page")int page, @Param("size")int size, String where); int queryCount( @Param("name")String lowerCase , @Param("where") String where); }
BaseMapper
- 经过 service 层的麻烦的数据处理,在语句方面已经非常简单了,同样省去上一篇已经实现了的方法
<mapper namespace="base.dao.IBaseDao" > <select id="queryByPage" resultType="hashmap"> select * from ${name} where ${where} limit #{page},#{size} </select> <select id="queryCount" resultType="int"> select count(1) from ${name} where ${where} </select> </mapper>
Page 对象
- 导航页码呢就是分页中·····额算了 直接上图吧
- 还有 地址 url 这个 在后面 BaseController 里面说
@Controller public class Page <T>{ private Integer page; //当前页 private Integer size = 5;//每页默认为5 private Integer max; //最大页数 private Integer count; //项目条数 private String url; //地址 private List<Integer> indexs;//要显示的页码 private Integer indexNum ;//可现实页码范围内的数量 private List<T> list; private String where; //在无参构造中初始化,当然我也在 BaseController 中初始化, //两种方式皆可,反正我都写上了 //当然可以写在配置文件中,这是更好的, //方便起见就没有写配置文件了 public Page() { page = 1; size = 5; indexNum = 5; where = " 1=1 "; } /** * 计算显示的导航页码 */ private void count() { Integer page = getPage(); Integer max = getMax(); if ( page!=null && max!=null ) { int begin = Math.max(page-indexNum, 1); int end = Math.min(page+indexNum, max); indexs = new ArrayList<>(); for( int i = begin ; i <= end ; i++ ) { indexs.add(i); } } } public void setPage(Integer page) { this.page = page; count(); //计算页码 } public void setMax(Integer max) { this.max = max; count(); //计算页码 } /** * 省去 普通的get set tostring等 */ }
BaseController 增强
-
在使用时,你自己的Controller中 拿到 Page 对象之前会 在这里做一些处理
-
可以在这里做一些初始化,将参数全部在这里截取并重新拼接(为了保留参数),方便后续开发中需要做相应的带条件的分页查询。
-
这里的 url 就是每次要访问的地址了
第一次分页查询时的地址
点击下一页后地址
从输出看,每次点击下一页,rul都是保持”干净的” - 所以说地址固定了,在分页页面中想要添加条件直接写&&条件即可,如果不在这里截取url ,那么之前的条件还是会在,所有条件堆在后面,地址栏会越来越长
@Controller public class BaseController <T> { @InitBinder public void initBinder( WebDataBinder binder , final HttpServletRequest request ){ binder.registerCustomEditor(Page.class,new PropertyEditorSupport(){ @Override public Object getValue() { Page<T> page = (Page<T>) super.getValue(); //提前操作 Page 对象 if ( page.getPage() == null ) { //没有设页数的时候 默认第一页 page.setPage(1); } //设置每页的条数 page.setSize(5); //解析request ,获得请求连接 String url = request.getRequestURI(); String params = request.getQueryString();//获取参数 //忽略掉一已经没用的参数,url变成"http://localhost:8080/SSM/stu/queryByPage?1=1" //所以页面中对page传参直接写:&参数=值 接上新的参数即可 if ( params!=null && !"".equals(params) ) { url += "?" + params; }else { url += "?1=1"; } //找到 每次要访问的地址 int index = -1; if ( (index = url.indexOf("&page="))!=-1 ) { url = url.substring(0, index); } page.setUrl(url); return page; } }); } }
page.jsp
-
这里我将page给单独分出来了,需要用的时候直接引入即可
-
如之前说的,在去到另一页时只需要用我们 page 中的url 加上需要的条件,参数即可
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <div> <c:if test="${page.page==1 }"> <a>首页</a> <a>上一页</a> </c:if> <c:if test="${page.page>1 }"> <a href="${page.url }&page=1">首页</a> <a href="${page.url }&page=${page.page-1}">上一页</a> </c:if> <!-- 页码 --> <c:forEach items="${page.indexs }" var="index"> <c:if test="${index == page.page }"> <b>${index}</b> </c:if> <c:if test="${index != page.page }"> <a href="${page.url }&page=${index}"><b>${index}</b></a> </c:if> </c:forEach> <c:if test="${page.page<page.max }"> <a href="${page.url }&page=${page.page+1}">下一页</a> <a href="${page.url }&page=${page.max}">尾页</a> </c:if> <c:if test="${page.page==page.max }"> <a >下一页</a> <a >尾页</a> </c:if> <a>当前第${page.page }页/共${page.max }页</a> </div>
使用中
@Controller @RequestMapping("/stu") public class StuController extends BaseController<Student> { @Autowired private IStudentService studentService ; @RequestMapping("/queryByPage") public String queryByPage( Model model , Page<Student> page ) { //这里用 page接收即可,数据也是放在其中的 page = studentService.queryByPage( page ); model.addAttribute("page",page); //可以选择是否设置条件,可以在一些需要特殊搜索的时候加上条件 //可以在页面中传参然后在这里设置条件 //比如 年龄大于20的 学生 并分页 page.setWhere("age>20"); System.out.println(page); return "stulist"; }
同上一篇 ,你自己的service和dao层该继承的继承,该实现的实现,
public interface IStudentService extends IBaseService<Student> {
}
@Service public class StudentService extends BaseService<Student> implements IStudentService { @Autowired private IStudentDao mapper; @Override public IBaseDao<Student> getBaseDao() { return mapper; } @Override public Class<Student> getClasss() { return Student.class; } }
public interface IStudentDao extends IBaseDao<Student> { }
下一篇呢 准备先写一个 简单的级联查询