学习JavaWeb中场案例——三层架构与新手小案例(下)

前言

承接上一篇,继续通过三层架构来完成我们的用户信息管理系统

 

 

 

 


继续编码

修改功能

分析功能

上一篇末尾,我们完成了删除功能,现在,我们来完成删除功能旁边的修改功能。

首先我们要明确思路,修改功能和增加功能可谓相似相仿,我们需要另一个jsp页面update.jsp来完成修改功能。

修改的功能会稍微比增删改会麻烦一些。

没关系,我们慢慢来。

找到list.jsp中那个“修改”按钮的位置,重写一下那里,让它可以访问findUserServlet接口:

<a class="btn btn-default btn-sm"
      href="${pageContext.request.contextPath}/findUserServlet?id=${user.id}">
      修改</a>&nbsp;

回显数据

我们首先来写FindUserServlet,我这里将doPost方法列出:

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //1.获取id
        String id = request.getParameter("id");
        //2.调用Service查询
        UserService service=new UserServiceImpl();
        User user=service.findUserById(id);
        //3.将user存入request
        request.setAttribute("user",user);
        //4.转发到update.jsp
        request.getRequestDispatcher("/update.jsp").forward(request,response);
    }

我们的FindUserServlet,利用UserService的infdUserById方法得到user对象,然后保存到request域,然后请求转发。

我们的UserServiceImpl如下(接口声明就不列出了):

    @Override
    public User findUserById(String id) {
        return dao.findById(Integer.parseInt(id));
    }

往下到Dao层,我们的定义如下(同理,省略接口声明):

    @Override
    public User findById(int id) {
        String sql="SELECT * FROM user WHERE id=?";
        return template.queryForObject(sql,
                new BeanPropertyRowMapper<User>(User.class),id);
    }

如此一来,就可以从数据库中找到数据并封装为User,接下来我们来写update.jsp:

<head>
    <!-- 指定字符集 -->
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>修改用户</title>

    <link href="css/bootstrap.min.css" rel="stylesheet">
    <script src="js/jquery-2.1.0.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script>
        //初始化下拉列表
        var initSelectList=function(){
            var selectList=["陕西","北京","上海","山东","河北","南京","天津"];
            var select=$("#address");
            for(var i=0;i<selectList.length;i++){
                var option=$("<option value="+selectList[i]+
                    ">"+selectList[i]+"</option>");
                //如果相同,则被选中
                if(selectList[i]=="${requestScope.user.address}"){
                    option.attr("selected","selected");
                }
                select.append(option);
            }
        }
        $(function(){
            //初始化下拉列表
            initSelectList();
            //正则表达式校验
            $("#age").change(function(){
                if(!testAge()){
                    //不符合正则表达式
                    if(!$("#age + span")[0]) {
                        //没有span提示,则添加span提示
                        var text = $("<span style='color:red'>" +
                            "请输入数字" +
                            "</span>");
                        $("#age").parent().append(text);
                    }
                }else {
                    //符合正则表达式
                    $("#age + span").remove();
                }
            });
            $("#qq").change(function(){
                if(!testQq()){
                    //不符合正则表达式
                    if(!$("#qq + span")[0]) {
                        //没有span提示,则添加span提示
                        var text = $("<span style='color:red'>" +
                            "请输入QQ账号" +
                            "</span>");
                        $("#qq").parent().append(text);
                    }
                }else {
                    //符合正则表达式
                    $("#qq + span").remove();
                }
            });
            $("#email").change(function(){
                if(!testEmail()){
                    //不符合正则表达式
                    if(!$("#email + span")[0]) {
                        //没有span提示,则添加span提示
                        var text = $("<span style='color:red'>" +
                            "请输入正确的邮箱地址" +
                            "</span>");
                        $("#email").parent().append(text);
                    }
                }else {
                    //符合正则表达式
                    $("#email + span").remove();
                }
            });

            var testAge=function(){
                var regexp=/^[0-9]{1,3}$/;
                var age=$("#age").val();
                return regexp.test(age);
            }
            var testQq=function(){
                var regexp=/^[0-9]{8,11}$/;
                var qq=$("#qq").val();
                return regexp.test(qq);
            }
            var testEmail=function(){
                var regexp=/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;
                var email=$("#email").val();
                return regexp.test(email);
            }
            //提交按钮绑定单机事件
            $("#sub").click(function(){
                if(!(testAge()&&testQq()
                    &&testEmail())){
                    return false;
                }
            });
        })
    </script>
</head>
<body>
<div class="container" style="width: 400px;">
    <h3 style="text-align: center;">修改联系人</h3>
    <form action="${pageContext.request.contextPath}/updateUserServlet" method="post">
        <!--隐藏域,为了让表单服务端拿到id-->
        <input type="hidden" name="id" value="${requestScope.user.id}">
        <div class="form-group">
            <label for="name">姓名:</label>
            <input type="text" class="form-control" id="name" name="name"
                   readonly="readonly" value="${requestScope.user.name}" placeholder="请输入姓名" />
        </div>

        <div class="form-group">
            <label>性别:</label>
            <c:if test="${requestScope.user.gender=='男'}">
                <input type="radio" name="gender" value="男" checked />男
                <input type="radio" name="gender" value="女"  />女
            </c:if>
            <c:if test="${requestScope.user.gender=='女'}">
                <input type="radio" name="gender" value="男"  />男
                <input type="radio" name="gender" value="女" checked />女
            </c:if>
        </div>

        <div class="form-group">
            <label for="age">年龄:</label>
            <input type="text" class="form-control" id="age"  name="age"
                   value="${requestScope.user.age}" placeholder="请输入年龄" />
        </div>

        <div class="form-group">
            <label for="address">籍贯:</label>
            <select name="address" id="address" class="form-control" >
            </select>
        </div>

        <div class="form-group">
            <label for="qq">QQ:</label>
            <input type="text" id="qq" class="form-control" name="qq"
                   value="${requestScope.user.qq}" placeholder="请输入QQ号码"/>
        </div>

        <div class="form-group">
            <label for="email">Email:</label>
            <input type="text" id="email" class="form-control" name="email"
                   value="${requestScope.user.email}" placeholder="请输入邮箱地址"/>
        </div>

        <div class="form-group" style="text-align: center">
            <input class="btn btn-primary" type="submit" id="sub" value="提交" />
            <input class="btn btn-default" type="reset" value="重置" />
            <input class="btn btn-default" type="button" value="返回"/>
        </div>
    </form>
</div>
</body>

如上,就可以再点击某个用户的修改后,将用户的信息回显到对应的文本框下。

提交修改

下一步就是提交修改,将表达数据发送个UpdateUserServlet这个Servlet:

doPost方法如下:

    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
                hrows ServletException, IOException {
        //1.设置编码
        request.setCharacterEncoding("utf-8");
        //2.封装对象
        User user=new User();
        Map<String, String[]> maps = request.getParameterMap();
        try {
            BeanUtils.populate(user,maps);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        //3.调用Service修改
        UserService service=new UserServiceImpl();
        service.updateUser(user);
        //4.重定向到list
        response.sendRedirect(request.getContextPath()+"/userListServlet");
    }

访问的Service层的UserService方法(接口定义我就不列出了):

    @Override
    public void updateUser(User user) {
        dao.update(user);
    }

访问的Dao层的UserDao方法(接口定义我就不列出了):

    @Override
    public void update(User user) {
        String sql="UPDATE user SET " +
                "name=?,gender=?,age=?," +
                "address=?,qq=?,email=? " +
                "WHERE id=?";
        template.update(sql,user.getName(),user.getGender(),
                user.getAge(),user.getAddress(),
                user.getQq(),user.getEmail(),
                user.getId());
    }

OK,修改功能就做完了!

删除选中

分析功能

完成了修改功能,我们来完成删除选中的功能。

这个例子让我终于亲身感受到Service层的实际用处了。

jsp页面

首先我们给列表套在了一个表单中,这样我们就能将数据提交给Servlet:

   <div style="float:right;margin:5px">
        <a class="btn btn-success"
           href="${pageContext.request.contextPath}/add.jsp">添加联系人</a>
        <a class="btn btn-success"
           href="javascript:void(0);" id="delSelected">删除选中</a>
    </div>
    <form id="form" action="${pageContext.request.contextPath}/delSelectedServlet"
        method="post">
    <table border="1" class="table table-bordered table-hover">
        <tr class="info">
            <th><input type="checkbox" id="firstBox"></th>
            <th>编号</th>
            <th>姓名</th>
            <th>性别</th>
            <th>年龄</th>
            <th>籍贯</th>
            <th>QQ</th>
            <th>邮箱</th>
            <th>操作</th>
        </tr>
        <C:forEach items="${requestScope.users}" var="user" varStatus="s">
            <tr>
                <td><input type="checkbox" name="uid" value="${user.id}"></td>
                <td>${s.count}</td>
                <td>${user.name}</td>
                <td>${user.gender}</td>
                <td>${user.age}</td>
                <td>${user.address}</td>
                <td>${user.qq}</td>
                <td>${user.email}</td>
                <td><a class="btn btn-default btn-sm"
                       href="${pageContext.request.contextPath}/findUserServlet?id=${user.id}">
                    修改</a>&nbsp;
                    <a class="btn btn-default btn-sm"
                       href="javascript:deleteUser(${user.id});">
                    删除</a>
                </td>
            </tr>
        </C:forEach>
    </table>
    </form>

对应的多选框处理以及点击“删除选中”后的事件逻辑,我们写在了当前页面的script中:

        $(function(){
            //给删除选中按钮添加单机事件以及相应提示
            $("#delSelected").click(function(){
                //判断是否有选中条目
                var flag=false;
                var cbs=$("input[name='uid']");
                for(var i=0;i<cbs.length;i++){
                    if(cbs[i].checked)
                        flag=true;
                }
                if(flag) {
                    if (confirm("确认删除选中条目吗?")) {
                        //提交表单
                        $("#form").submit();
                    }
                }else
                    alert("没有条目被选中!");
            });
            //全选按钮绑定
            $("#firstBox").click(function(){
                //1.获取下边列表中所有的多选框
                var cbs=$("input[name='uid']");
                //2.遍历
                for(var i=0;i<cbs.length;i++){
                    //3.设置这些cbs[i]的check状态(DOM操作)
                    cbs[i].checked=$("#firstBox")[0].checked;
                }
            });
            //单个按钮绑定对于全选按钮的控制
            $("input[name='uid']").click(function(){
                var cbs=$("input[name='uid']");
                var isAllChecked=true;
                //2.遍历
                for(var i=0;i<cbs.length;i++){
                    if(cbs[i].checked!=true){
                        isAllChecked=false;
                    }
                }
                $("#firstBox")[0].checked=isAllChecked;
            });
        });

Servlet接收

我们在jsp中设置表单提交给了delSelectedServlet,故我们在web.servlet包下创建DelSelectedServlet这个Servlet:

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取所有id
        String[] uids = request.getParameterValues("uid");
        //2.调用Service删除
        UserService service=new UserServiceImpl();
        service.delSelectedUser(uids);
        //3.重定向查询所有Servlet
        response.sendRedirect(request.getContextPath()+"/userListServlet");
    }

其中调用UserService的delSelectedUser方法,故我们在service.impl包下的UserService中应该有(对应接口声明在此不列):

    @Override
    public void delSelectedUser(String[] uids) {
        //后端拦截,防止空数据
        if(uids!=null&& uids.length>0) {//1.遍历数组
            for (String id : uids) {
                //2.调用dao删除
                dao.delete(Integer.parseInt(id));
            }
        }
    }

我们已经在dao层写过了delete方法,故这里我们就不必再动dao层,这个逻辑也就到此处理完毕,体验到业务逻辑层和数据访问层的意义了。

分页查询

分析功能

分页查询,将数据分成好几页。

好处:

  1. 减轻服务器内存的开销
  2. 提升用户体验

实现思路:

对于新手来说,分页功能着实棘手,但是也确实重要,下面我们来整理一下实现思路:

我们的服务端需要四个数据:

  1. int totalCount; :总记录数
  2. int   totalPage;:总页码
  3. List  list;:每页数据的list集合
  4. int  currentPage;:当前页码
  5. int  rows; :每一页的显示条数

客户端将会通过jsp页面给服务器提供 currentPage(当前页码)

客户端还会提供 rows(每一页的条数),根据每一页的条数rows,即可得到totalPage (总页码),公式:总页码=(总记录数%每页显示条数==0)?(总记录数/每页显示条数):(总记录数/每页显示条数+1)

服务端可以自行通过访问数据库得到totalCount(总记录数),sql语句:SELECT   COUNT(*)  FROM   user;,利用DQL中的聚合查询即可。

利用SQL语句中DQL的分页查询,即可得到list(每页数据的list集合),sql语句:SELECT *  FROM  user  LIMIT   ?   ?;第一个参数是开始索引的位置,第二个参数是索引条数。开始索引的位置:(currentPage-1)*rows;

这四个数据,我们会封装成一个JavaBean对象,然后保存在某域中,交给web显示层显示即可。

 

 

PageBean

在domain包下创建一个JavaBean:

public class PageBean<T>{
    private Integer totalCount; //总记录数
    private Integer totalPage; //总页码
    private List<T> list; //每页的数据
    private Integer currentPage; //当前页码
    private Integer rows;   //每页显示的记录数

    @Override
    public String toString() {
        return "PageBean{" +
                "totalCount=" + totalCount +
                ", totalPage=" + totalPage +
                ", list=" + list +
                ", currentPage=" + currentPage +
                ", rows=" + rows +
                '}';
    }

    public Integer getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(Integer totalCount) {
        this.totalCount = totalCount;
    }

    public Integer getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(Integer totalPage) {
        this.totalPage = totalPage;
    }

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }

    public Integer getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(Integer currentPage) {
        this.currentPage = currentPage;
    }

    public Integer getRows() {
        return rows;
    }

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

 

后端处理

这里我们先不写页面处理,先写好逻辑处理:

web.servlet包中创建一个servlet——FindUserByPageServlet

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
               throws ServletException, IOException {
        //1.获取参数
        String currentPage = request.getParameter("currentPage"); //当前页码
        String rows = request.getParameter("rows"); //每页显示行数

        if(currentPage==null||"".equals(currentPage))
            currentPage="1";
        if(rows==null||"".equals(rows))
            rows="8";

        //2.调用Service查询
        UserService service=new UserServiceImpl();
        PageBean<User> pb=service.findUserByPage(currentPage,rows);
        //3.将PageBean存入request域
        request.setAttribute("pagebean",pb);

        //4.转发到list.jsp页面
        request.getRequestDispatcher("list.jsp").forward(request,response);
    }

注意:我们的这个Servlet就代替了很久之前的那个UserListServlet,故记得将index.jsp中的页面跳转到findUserByPageServlet接口,以及DelSelectedServlet.java中,删除选中后也是跳转到新的接口;AddUserServlet.java中,添加新用户后也是跳转到新的接口。

这里我们将客户端的currentPage、rows传递UserService的方法findUserByPage。

在UserServiceImpl中方法实现如下(接口声明不列出了)

    @Override
    public PageBean<User> findUserByPage(String _currentPage, String _rows) {
        int currentPage=Integer.parseInt(_currentPage);
        int rows=Integer.parseInt(_rows);

        //1.创建空的PageBean
        PageBean<User> pb=new PageBean<User>();

        //2.调用dao查询总记录数
        int totalCount=dao.findTotalCount();
        pb.setTotalCount(totalCount);

        //3.计算总页码
        int totalPage=(totalCount%rows==0)?(totalCount/rows):(totalCount/rows+1);
        if(totalPage==0)
             totalPage=1;
        pb.setTotalPage(totalPage);

        //4.当前页的后端审核
        if(currentPage<=0)
            currentPage=1;
        else if(currentPage>totalPage)
            currentPage=totalPage;

        //5.设置当期页
        pb.setCurrentPage(currentPage);
        pb.setRows(rows);

        //6.调用dao查询list集合
        //6.1 计算开始的位置
        int start=(currentPage-1)*rows;
        //6.2分页查询
        List<User> users=dao.findByPage(start,rows);
        pb.setList(users);

        return pb;
    }

这里调用了UserDaoImpl中两个dao层的方法,

    @Override
    public int findTotalCount() {
        String sql="SELECT COUNT(*) FROM user";
        // 第二个参数传入类型class对象,即将返回值转成Integer,
        // 再通过自动拆箱,使返回值转成int基本类型
        return template.queryForObject(sql,Integer.class);
    }
    @Override
    public List<User> findByPage(int start, int rows) {
        String sql="SELECT * FROM user LIMIT ?,?";
        List<User> users = template.query(sql,
                new BeanPropertyRowMapper<User>(User.class), start, rows);
        return users;
    }

后端逻辑完成。

前端界面

在list.jsp中,我们主要修改了下面的分页组件的设置:

    <!--分页组件-->
    <div>
        <nav aria-label="Page navigation">
            <ul class="pagination">
                <!--上一页-->
                <c:if test="${requestScope.pagebean.currentPage==1}">
                    <li class="disabled">
                </c:if>
                <c:if test="${requestScope.pagebean.currentPage!=1}">
                    <li>
                </c:if>
                        <a href="${pageContext.request.contextPath
                        }/findUserByPageServlet?currentPage=${requestScope.pagebean.currentPage-1}"
                           aria-label="Previous">
                            <span aria-hidden="true">&laquo;</span>
                        </a>
                    </li>

                <!--分页-->
                <c:forEach begin="1" end="${requestScope.pagebean.totalPage}" var="i">
                    <c:if test="${requestScope.pagebean.currentPage==i}">
                        <li class="active">
                    </c:if>
                    <c:if test="${requestScope.pagebean.currentPage!=i}">
                        <li>
                    </c:if>
                            <a href="${pageContext.request.contextPath
                            }/findUserByPageServlet?currentPage=${i}">
                                    ${i}
                            </a>
                        </li>
                </c:forEach>
                <!--下一页-->
                <c:if test="${requestScope.pagebean.currentPage==requestScope.pagebean.totalPage}">
                    <li class="disabled">
                </c:if>
                <c:if test="${requestScope.pagebean.currentPage!=requestScope.pagebean.totalPage}">
                    <li>
                </c:if>
                        <a href="${pageContext.request.contextPath
                            }/findUserByPageServlet?currentPage=${requestScope.pagebean.currentPage+1}"
                           aria-label="Next">
                            <span aria-hidden="true">&raquo;</span>
                        </a>
                    </li>
                <span style="font-size: 25px;margin: 5px">
                    共${requestScope.pagebean.totalCount}条记录,
                    共${requestScope.pagebean.totalPage}页
                </span>
            </ul>
        </nav>
    </div>

条件查询

功能分析

我们要根据页面上客户端给出的条件来进行查询,目前是三个条件:name、address、email,查询结束后查询结果仍然要进行分页处理。

我们仍然会利用PageBean这个类,而这个类中的totalCount和list仍然是通过SEL语句获得:

  • totalCount:SELECT  COUNT(*)  FROM  user  WHERE  name  LIKE  ?   AND ……
  • list:SELECT  *   FROM   user    WHERE   name   LIKE   ?  AND  ……

这里我们有一个很经典的问题,就是用户进行搜索的时候,并不一定都会写搜索条件,甚至有可能就不写搜索条件,固然使用name  LIKE  ?,如果用户没有提供“姓名”信息则SQL语句是存在语法错误的。

我们的解决思路是使用动态的SQL语句,即SQL语句并不写死,会根据情况进行变更,我们将客户端发送来的数据封装成一个map,然后:

  1. 定义SQL=SELECT   COUNT(*)   FROM   user   WHERE   1=1
  2. 遍历map,判断其value是否有值,然后利用StringBuffer等类型变量来拼接字符串:”AND   Key   LIKE   ?”

这样就完成了根据客户端的输入信息来得到对应的totalCount以及list。

Servlet

我们要知道,条件的查询并不是一个另外的Servlet,而是FindUserByPageServlet的额外条件,故我们不是重创建Servlet,而是重写FindUserByPageServlet:

    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
                    throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        //1.获取参数
        String currentPage = request.getParameter("currentPage"); //当前页码
        String rows = request.getParameter("rows"); //每页显示行数

        if(currentPage==null||"".equals(currentPage))
            currentPage="1";
        if(rows==null||"".equals(rows))
            rows="8";
        //获取条件查询参数
        Map<String, String[]> condition = request.getParameterMap();

        //2.调用Service查询
        UserService service=new UserServiceImpl();
        PageBean<User> pb=service.findUserByPage(currentPage,rows,condition);
        //3.将PageBean存入request域
        request.setAttribute("pagebean",pb);
        request.setAttribute("condition",condition); //将查询条件也存入,方便反馈
        //4.转发到list.jsp页面
        request.getRequestDispatcher("list.jsp").forward(request,response);
    }

我们将request的请求封装成了map,并传给了Service层:

@Override
    public PageBean<User> findUserByPage(String _currentPage, String _rows, Map<String, String[]> condition) {
        int currentPage=Integer.parseInt(_currentPage);
        int rows=Integer.parseInt(_rows);

        //1.创建空的PageBean
        PageBean<User> pb=new PageBean<User>();

        //2.调用dao查询总记录数
        int totalCount=dao.findTotalCount(condition);
        pb.setTotalCount(totalCount);

        //3.计算总页码
        int totalPage=(totalCount%rows==0)?(totalCount/rows):(totalCount/rows+1);
        if(totalPage==0)
              totalPage=1;
        pb.setTotalPage(totalPage);

        //4.当前页的后端审核
        if(currentPage<=0)
            currentPage=1;
        else if(currentPage>totalPage)
            currentPage=totalPage;

        //5.设置当期页
        pb.setCurrentPage(currentPage);
        pb.setRows(rows);

        //6.调用dao查询list集合
        //6.1 计算开始的位置
        int start=(currentPage-1)*rows;
        //6.2分页查询
        List<User> users=dao.findByPage(start,rows,condition);
        pb.setList(users);

        return pb;
    }

和之前相比,Service层仅仅是将新参数condition传给了DAO层的findTotalCount、findByPage

  @Override
    public int findTotalCount(Map<String, String[]> condition) {
        //1.定义模板初始化SQL
        String sql="SELECT COUNT(*) FROM user WHERE 1=1";
        //2.根据condition凭借SQL,添加查询条件
        StringBuilder sb=new StringBuilder(sql);
        List<Object> params=new ArrayList<Object>();
        //2.1遍历map
        Set<String> keySet = condition.keySet();
        for(String key:keySet){
            //排除分页参数
            if("currentPage".equals(key)||"rows".equals(key))
                continue;
            //获取value(获取String[]的第一个值,因为jsp的文本框只可能发一个值)
            String value = condition.get(key)[0];
            //判断value是否有值
            if(value!=null&&!"".equals(value)){
                sb.append(" AND "+key+" LIKE ?");
                params.add("%"+value+"%");  //加参数到list,值是模糊查询,需要%
            }
        }
        sql=sb.toString();
        // 第二个参数传入类型class对象,即将返回值转成Integer,
        // 再通过自动拆箱,使返回值转成int基本类型
        return template.queryForObject(sql,Integer.class,params.toArray());
    }
@Override
    public List<User> findByPage(int start, int rows, Map<String, String[]> condition) {
        String sql="SELECT * FROM user WHERE 1=1 ";

        //添加条件
        StringBuilder sb=new StringBuilder(sql);
        List<Object> params=new ArrayList<Object>();
        Set<String> keySet = condition.keySet();
        for(String key:keySet){
            if("currentPage".equals(key)||"rows".equals(key))
                continue;
            String value = condition.get(key)[0];
            if(value!=null&&!"".equals(value)){
                sb.append(" AND "+key+" LIKE ?");
                params.add("%"+value+"%");
            }
        }

        //添加分页查询的分页LIMIT
        sb.append(" limit ?,?");
        params.add(start);
        params.add(rows);

        sql=sb.toString();

        List<User> users = template.query(sql,
                new BeanPropertyRowMapper<User>(User.class), params.toArray());
        return users;
    }

jsp页面展示

回到我们的list.jsp,首先是内联表单,实现查询

<!--内联表单,实现查询-->
    <div style="float:left">
        <form class="form-inline"
              action="${pageContext.request.contextPath}/findUserByPageServlet"
              method="post">
            <div class="form-group">
                <label for="exampleInputName2">姓名</label>
                <input type="text" class="form-control"
                       value="${requestScope.condition.name[0]}"
                       name="name" id="exampleInputName2">
            </div>
            <div class="form-group">
                <label for="exampleInputName3">籍贯</label>
                <input type="text" class="form-control"
                       value="${requestScope.condition.address[0]}"
                       name="address" id="exampleInputName3">
            </div>
            <div class="form-group">
                <label for="exampleInputEmail2">邮箱</label>
                <input type="email" class="form-control"
                       value="${requestScope.condition.email[0]}"
                       name="email" id="exampleInputEmail2">
            </div>
            <button type="submit" class="btn btn-primary">查询</button>
        </form>
    </div>

input中的value是为了查询后,查询框上仍然显示查询条件信息,给用户很好的反馈。

然后在我们的分页条目下也要修改,为什么?分页条目会根据用户点击组件去访问Servlet,如果不添加参数(name、address、email),则又会将全部内容索引出来,用户查询之后,因为内容多而去翻页,但是导致一下全部内容又出来了,这就是bug。

 <!--分页组件-->
    <div>
        <nav aria-label="Page navigation">
            <ul class="pagination">
                <!--上一页-->
                <c:if test="${requestScope.pagebean.currentPage==1}">
                    <li class="disabled">
                </c:if>
                <c:if test="${requestScope.pagebean.currentPage!=1}">
                    <li>
                </c:if>
                        <a href="${pageContext.request.contextPath
                        }/findUserByPageServlet?currentPage=${
                        requestScope.pagebean.currentPage-1}&name=${
                            requestScope.condition.name[0]}&address=${
                            requestScope.condition.address[0]}&email=${
                            requestScope.condition.email[0]}"
                           aria-label="Previous">
                            <span aria-hidden="true">&laquo;</span>
                        </a>
                    </li>

                <!--分页-->
                <c:forEach begin="1" end="${requestScope.pagebean.totalPage}" var="i">
                    <c:if test="${requestScope.pagebean.currentPage==i}">
                        <li class="active">
                    </c:if>
                    <c:if test="${requestScope.pagebean.currentPage!=i}">
                        <li>
                    </c:if>
                            <a href="${pageContext.request.contextPath
                            }/findUserByPageServlet?currentPage=${i}&rows8&name=${
                            requestScope.condition.name[0]}&address=${
                            requestScope.condition.address[0]}&email=${
                            requestScope.condition.email[0]}">
                                    ${i}
                            </a>
                        </li>
                </c:forEach>
                <!--下一页-->
                <c:if test="${requestScope.pagebean.currentPage==requestScope.pagebean.totalPage}">
                    <li class="disabled">
                </c:if>
                <c:if test="${requestScope.pagebean.currentPage!=requestScope.pagebean.totalPage}">
                    <li>
                </c:if>
                        <a href="${pageContext.request.contextPath
                            }/findUserByPageServlet?currentPage=${
                            requestScope.pagebean.currentPage+1}&name=${
                            requestScope.condition.name[0]}&address=${
                            requestScope.condition.address[0]}&email=${
                            requestScope.condition.email[0]}"
                           aria-label="Next">
                            <span aria-hidden="true">&raquo;</span>
                        </a>
                    </li>
                <span style="font-size: 25px;margin: 5px">
                    共${requestScope.pagebean.totalCount}条记录,
                    共${requestScope.pagebean.totalPage}页
                </span>
            </ul>
        </nav>
    </div>

篇幅考虑,我在a标签中的EL表达式用回车换行了,你写的时候为了美观可以并成一行。

 


结局

经过三天的学习,终于将这个小案例搞定了,其实精心思索并不困难,主要是要应用好三层架构,将各种逻辑有条不紊地解耦。

这个例子还有很多细节就不在写在文中了,例如一些输入部分的正则表达式、一些页面的访问控制……

这个例子我想改成一个社工库,哈哈,这就是个人志愿了……

 

 

 

 

 

 

商业转载 请联系作者获得授权,非商业转载 请标明出处,谢谢

 

 

发表评论