SSM 封装base(二) -封装分页

本文介绍了一种在SSM框架中实现分页功能的方法,包括服务层、DAO层和控制器层的具体实现细节,以及如何通过MyBatis进行数据库查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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> {

}

 

下一篇呢 准备先写一个 简单的级联查询

转载于:https://www.cnblogs.com/huangjianlong/p/7861381.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值