尚筹网03-后台-管理员维护

186 阅读2分钟

任务清单

  • 分页显示数据功能的实现

    1.不带关键词分页

    2.带关键词分页

  • 单条删除Admin数据

  • 新增Admin数据

  • 更新Admin数据

一、分页显示数据

1.1目标

将数据库中的Admin数据在前端分页显示,在后端带“关键词”的和“不带关键词”的用同一套代码进行分页显示

1.2思路

image.png

1.3代码

1.1 引入pageHelper插件

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
</dependency>

1.2 在SqlSessionFactoryBean配置pageHelper

image.png

image.png

<!-- 配置插件-->
<property name="plugins">
    <array>
        <!-- 配置pageHelper插件-->
        <bean class="com.github.pagehelper.PageHelper">
            <property name="properties">
                <props>
                    <!-- 配置数据库方言,告诉PageHelper目前使用的数据库-->
                    <prop key="dialect">mysql</prop>
                    <!-- 配置页码的合理化修正,在1~总页数之间修正-->
                    <prop key="reasonable"></prop>
                </props>
            </property>
        </bean>
    </array>
</property>

1.3 写sql语句

image.png

<select id="selectAdminKeyWord" resultMap="BaseResultMap">
  select id, login_acct, user_pswd, user_name, email, create_time
  from t_admin
  where login_acct like concat("%",#{keyword},"%") or
        user_name like concat("%",#{keyword},"%") or
        email like concat("%",#{keyword},"%")
</select>

1.4 service层

image.png

AdminService

/**
 * keyword:搜索的关键词信息
 * pageNum:总页数
 * pageSize每页显示的条数
 * */
PageInfo<Admin> getPageInfo(String keyword,Integer pageNum,Integer pageSize);

AdminServiceImpl

/**
 * 分页显示
 * */
@Override
public PageInfo<Admin> getPageInfo(String keyword, Integer pageNum, Integer pageSize) {
    // 1.调用pageHelper的静态方法,开启分页
    PageHelper.startPage(pageNum,pageSize);
    // 2.执行查询
    List<Admin> list = mapper.selectAdminKeyWord(keyword);
    // 3.将查询的结果封装到pageInfo对象中
    PageInfo pageInfo = new PageInfo(list);
    //System.out.println("总页数:"+pageInfo.getPageNum());
    return pageInfo;
}

1.5 Controller层

image.png

/**
 *  分页显示方法
 * */
@RequestMapping("/admin/get/page.html")
public String getPageInfo(
                                // 使用@RequestParam的defaultValue属性,指定默认值,
                                // 在请求中没有携带对应参数时使用默认值
                                // keyword默认使用空字符串和sql语句两种情况适配
                               @RequestParam(value = "keyword",defaultValue = "") String keyword,
                               @RequestParam(value = "pageNum",defaultValue = "1") Integer pageNum,
                               @RequestParam(value = "pageSize",defaultValue = "5") Integer pageSize,
                               ModelMap modelMap){

    System.out.println("keyword="+keyword);
    // 1.调用Service获取getInfo对象
    PageInfo<Admin> pageInfo = adminService.getPageInfo(keyword, pageNum, pageSize);

    // 2.将pageInfo对象存入模型
    modelMap.addAttribute(CrowdConstant.ATTR_NAME_PAGE_INFO,pageInfo);
    return "admin-page";
}

1.6 页面显示主体数据

image.png

1.6.1 引入Pagination插件用来显示导航条

image.png

1.6.2 在需要的页面引入

image.png 1.6.3 页面代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html lang="zh-CN">
<%@include file="/WEB-INF/jsp/include-head.jsp" %>
<link rel="stylesheet" href="css/pagination.css" />
<script type="text/javascript" src="jquery/jquery.pagination.js"></script>
<script type="text/javascript">

    $(function (){

        // 调用后面声明的函数对页码导航条进行初始化操作
        initPageination();
    })

    // 1.生成页码导航条函数
    function initPageination(){

        // 获取总记录条数
        var totalRecord =${requestScope.pageInfo.total};

        // 声明一个JSON对象存储Pagination要设置的属性
        var properties={
            num_edge_entries: 3,                               //边缘页数
            num_display_entries: 5,                            //主体页数
            callback: pageSelectCallback,                      //指定用户点击翻页按
                                                               //钮时跳转页面的函数
            items_per_page: ${requestScope.pageInfo.pageSize}, //每页显示的条数
            current_page: ${requestScope.pageInfo.pageNum-1},  
            //pageNum是从1开始的,而pagination内部使用pageIndex来管理的,里面是从0开始的
            prev_text: "上一页",                               //上一页按钮上显示的文本
            next_text: "下一页"                                //下一页按钮上显示的文本
        };

        //生成页码导航条
        $("#Pagination").pagination(totalRecord,properties);
    }

    // 2.用户点击“1”,“2”,“3”,,,这样的按钮时调用这个函数实现跳转
    function pageSelectCallback(page_index,jQuery){
        // 根据page_index来获取pageNum
        var pageNum = page_index+1;
        //跳转页面
        window.location.href="admin/get/page.html?pageNum="+pageNum+"&keyword=${param.keyword}";
        // 由于每一个页面都是超链接,所以在这个函数最后取消超链接的默认行为
        return false;
    }
</script>
<body>

<%@include file="/WEB-INF/jsp/include-nav.jsp" %>
<div class="container-fluid">
    <div class="row">
        <%@include file="/WEB-INF/jsp/include-sidebar.jsp" %>
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 class="panel-title"><i class="glyphicon glyphicon-th"></i> 数据列表</h3>
                </div>
                <div class="panel-body">
                    <form action="admin/get/page.html" method="post" class="form-inline" role="form" style="float:left;">
                        <div class="form-group has-feedback">
                            <div class="input-group">
                                <div class="input-group-addon">查询条件</div>
                                <input name="keyword" class="form-control has-success" type="text" placeholder="请输入查询条件">
                            </div>
                        </div>
                        <button type="submit" class="btn btn-warning"><i class="glyphicon glyphicon-search"></i> 查询</button>
                    </form>
                    <button type="button" class="btn btn-danger" style="float:right;margin-left:10px;"><i class=" glyphicon glyphicon-remove"></i> 删除</button>

                    <%--旧代码--%>
                    <%--<button type="button" class="btn btn-primary" style="float:right;" onclick="window.location.href='add.html'"><i class="glyphicon glyphicon-plus"></i> 新增</button>--%>
                    <%--新代码--%>
                    <a style="float:right;" href="admin/toAdd.html" class="btn btn-primary"><i class="glyphicon glyphicon-plus"></i>新增</a>

                    <br>
                    <hr style="clear:both;">
                    <div class="table-responsive">
                        <table class="table  table-bordered">
                            <thead>
                            <tr>
                                <th width="30">#</th>
                                <th width="30"><input type="checkbox"></th>
                                <th>账号</th>
                                <th>名称</th>
                                <th>邮箱地址</th>
                                <th width="100">操作</th>
                            </tr>
                            </thead>
                            <tbody>
                                <c:if test="${empty requestScope.pageInfo.list}">
                                    <tr>
                                        <td colspan="6" align="center">抱歉,没有查到您要查的数据!</td>
                                    </tr>
                                </c:if>

                                <c:if test="${!empty requestScope.pageInfo.list}">
                                    <c:forEach items="${requestScope.pageInfo.list}" var="admin" varStatus="myStatus">
                                        <tr>
                                            <%--myStatus.count:循环计数 12345,,,,--%>
                                            <td>${myStatus.count}</td>
                                            <td><input type="checkbox"></td>
                                            <td>${admin.loginAcct}</td>
                                            <td>${admin.userName}</td>
                                            <td>${admin.email}</td>
                                            <td>
                                                <button type="button" class="btn btn-success btn-xs"><i class=" glyphicon glyphicon-check"></i></button>

                                                <%--ton type="button" class="btn btn-primary btn-xs"><i class=" glyphicon glyphicon-pencil"></i></button>--%>
                                                <a href="admin/to/edit/page.html?adminId=${admin.id}&pageNum=${requestScope.pageInfo.pageNum }&keyword=${param.keyword}" class="btn btn-primary btn-xs"><i class=" glyphicon glyphicon-pencil"></i></a>

                                                <%--<button id="btn1" type="button" class="btn btn-danger btn-xs"><i class=" glyphicon glyphicon-remove"></i></button>--%>
                                                <a href="admin/get/delete/${admin.id}/${requestScope.pageInfo.pageNum }/${param.keyword}.html" class="btn btn-danger btn-xs"><i class=" glyphicon glyphicon-remove"></i></a>
                                            </td>
                                        </tr>
                                    </c:forEach>
                                </c:if>
                                
                            </tbody>
                            <tfoot>
                            <tr>
                                <td colspan="6" align="center">

                                    <div id="Pagination" class="pagination"><!-- 这里显示分页 --></div>

                                    <%--<ul class="pagination">
                                        <li class="disabled"><a href="#">上一页</a></li>
                                        <li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li>
                                        <li><a href="#">2</a></li>
                                        <li><a href="#">3</a></li>
                                        <li><a href="#">4</a></li>
                                        <li><a href="#">5</a></li>
                                        <li><a href="#">下一页</a></li>
                                    </ul>--%>
                                </td>
                            </tr>
                            </tfoot>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

</body>
</html>

image.png

image.png

二、单条删除admin数据

1. 目标

点击删除按钮删除,删除后回到删除的页数

image.png

2.思路

image.png

3.代码

3.1 前端删除按钮 image.png 3.2 Controller层

/*-----------------------删除数据-----------------------*/
/**
 * 单击删除方法
 * */
@RequestMapping("/admin/get/delete/{adminId}/{pageNum}/{keyword}.html")
public String adminDelete(@PathVariable("adminId") Integer adminId,
                          @PathVariable("pageNum") Integer pageNum,
                          @PathVariable("keyword") String keyword,
                          HttpSession session
                          ){

    Admin admin = (Admin) session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_ADMIN);
    String userName = admin.getUserName();
    System.out.println("当前登录用户:"+userName);
    System.out.println("adminid="+adminId);
    Integer id = admin.getId();
    if (adminId==id){
        throw new RuntimeException(CrowdConstant.DELETE_FAILED);
    }

    // 执行删除
    int remove = adminService.remove(adminId);

    // 页面跳转:回到分页页面
    // 1.尝试方案一:直接发送到admin-page.jsp会无法显示分页数据
    // return "admin-page"

    // 2.尝试方案二:转发到/admin/get/page.html  一刷新页面会重复执行删除浪费性能

    // 3.尝试方案三:转发到/admin/get/page.html  一刷新页面会重复执行删除浪费性能
    // 为了保持原本所在页面和查询关键词再附加两个参数pageNum,keyword
    return "redirect:/admin/get/page.html?pageNum="+pageNum+"&keyword="+keyword;
}

3.3 Service层

AdminService

int remove(Integer adminId);

AdminServiceImpl

/**
 *  删除方法
 * */
@Override
public int remove(Integer adminId) {
    int i = mapper.deleteByPrimaryKey(adminId);
    return i;
}

三、新增Admin数据

1.目标

将表单提交的Admin数据保存到数据库中

  • 要求1.loginAcct不能重复
  • 要求2.密码加密

2.思路

image.png

3.代码

3.1 前端新增按钮

image.png 3.2 Controller层

image.png

/*-----------------------新增数据-----------------------*/
/**
 * 跳转页面--->新增页面
 * */
@RequestMapping("/admin/toAdd.html")
public String toAdd(){
    return "admin-add";
}

/**
 *  保存页面
 * */
@RequestMapping("/admin/save.html")
public String adminAdd(Admin admin){
    // 将输入进来的密码加密
    String userPswd = admin.getUserPswd();
    String md5 = CrowdUtil.md5(userPswd);

    // 将加密的密码保存
    admin.setUserPswd(md5);

    //生成时间
    Date date = new Date();
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
    String format = dateFormat.format(date);
    admin.setCreateTime(format);

    //插入数据
    try {
        adminService.saveAdmin(admin);
    } catch (Exception e) {
        //e.printStackTrace();
        if (e instanceof DuplicateKeyException){
            throw new LoginAcctAlreadyUseException(CrowdConstant.MESSAGE_ACCT_ALREADY_IN_USE);
        }
    }
    System.out.println("admin="+admin);

    //为了新增之后可以直接跳转到新增的那一页数据
    List<Admin> all = adminService.getAll();
    int size = all.size();
    int YeShu = size/5;
    if (size%5!=0){
        YeShu+=1;
    }
    return "redirect:/admin/get/page.html?pageNum="+YeShu;
}

3.3 Service层 AdminService

public interface AdminService {
    void saveAdmin(Admin admin);

AdminServiceImpl

@Override
public void saveAdmin(Admin admin) {
    mapper.insert(admin);
}

3.4 异常处理

image.png

image.png

image.png

四、更新Admin数据

1.目标

修改现有的Admin数据

  • 要求1.不能修改时间和密码
  • 要求2.不能修改成已有的loginAcct

2.思路

image.png

修改成已有用户时,抛出异常到system.error页面,返回上一步,数据还在,这样可以避免回显数据代码

3.代码

3.1 前端更新按钮

image.png

<a href="admin/to/edit/page.html?adminId=${admin.id}&pageNum=${requestScope.pageInfo.pageNum }&keyword=${param.keyword}"
   class="btn btn-primary btn-xs"><i class=" glyphicon glyphicon-pencil"></i></a>

3.2 Controller层

image.png

/*----------------------更新数据-----------------------*/
/**
 *  跳转到更新页面
 */
@RequestMapping("admin/to/edit/page.html")
public String toAdminEdite(@RequestParam("adminId") Integer adminId,ModelMap modelMap){

    System.out.println("adminId="+adminId);
    // 1.根据adminId查询admin对象
    Admin admin = adminService.getAdminByAdminId(adminId);

    // 2.将admin对象存入模型
    modelMap.addAttribute("admin",admin);
    return "admin-edit";
}

/**
 * 保存更新
 * */
@RequestMapping("admin/update.html")
public String updateAdmin(Admin admin,
                          @RequestParam("pageNum") Integer pageNum,
                          @RequestParam("keyword") String keyword){

    try {
        adminService.update(admin);
    } catch (Exception e) {
        //e.printStackTrace();
            throw new UpdateAcctAlreadyUseException(CrowdConstant.MESSAGE_ACCT_ALREADY_IN_USE);
    }
    return "redirect:/admin/get/page.html?pageNum="+pageNum+"&keyword="+keyword;
}

3.3 service层 AdminService

void update(Admin admin);

AdminServiceImpl

/**
 *  更新方法
 * */
@Override
public void update(Admin admin) {
     //Selective表示由选择的更新,对null字段不更新
     mapper.updateByPrimaryKeySelective(admin);
}

3.4 异常处理

image.png

/**
 *  新增时已存在该用户异常
 * */
public class UpdateAcctAlreadyUseException extends RuntimeException{

    private static final long serialVersionUID = 5L;

    public UpdateAcctAlreadyUseException() {
        super();
    }

    public UpdateAcctAlreadyUseException(String message) {
        super(message);
    }

    public UpdateAcctAlreadyUseException(String message, Throwable cause) {
        super(message, cause);
    }

    public UpdateAcctAlreadyUseException(Throwable cause) {
        super(cause);
    }

    protected UpdateAcctAlreadyUseException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

image.png

/**
 * 更新时该更新的用户已被使用异常
 * */
@ExceptionHandler(value = UpdateAcctAlreadyUseException.class)
public ModelAndView updateFailedException(
        UpdateAcctAlreadyUseException exception,
        HttpServletRequest request,
        HttpServletResponse response
) throws IOException {
    // 只是指定当前异常对应的页面即可
    String viewName = "system-error";
    System.out.println("已完成");
    return commonResolveException(viewName, exception, request, response);
}

image.png