SpringMVC小白入门案列

发布于:2023-01-28 ⋅ 阅读:(606) ⋅ 点赞:(0)

贵美商城案例仓库(SRC内有所需SQL): https://gitee.com/small-kekeaiai/guimei

目录

一、准备工作

1. 此案例所需 pom.xml-------------------------------------------------

1. 此案例所需pom.xml 结束-------------------------------------------------------

1.1.1 此外还需导入layUI(在仓库)

2. webapp

WEB-INF

3. HTML

index.html

userAdd.html

userList.html

userAddress.html用户位置分布

userGender.html柱状图男女人数

adminLogin.html

3. resources

applicationContext-aop.xml

applicationContext-bean.xml

applicationContext-tx.xml

jdbc.properties

log4j.xml

mybatis-config.xml

springmvc.xml

4. mapper

UserMapper.xml

AdminMapper.xml

二、JAVA

2.1 controller

2.1.1 AdminController

2.1.2 UserController

2.2 dto2.2.1 UserAddress用户地址

2.2.2 UserAddressDto用户位置分布

2.2.3 UserGenderDto柱状图男女人数

2.3 interceptor2.3.1 listener登录拦截器

2.4 mapper2.4.1 AdminMapper 用户登录

2.4.2 UserMapper 数据访问层

2.5 entity2.5.1 User

2.5.2 Admin

2.6 service 业务逻辑层

2.6.1 UserService

2.6.2 AdminService 管理服务层

2.7 impl 接口实现2.7.1 UserServiceImpl

2.7.2 AdminServiceImpl 管理服务实现

3 . utils

JsonResult (json结果 前端异步数据)


一、准备工作

1. 此案例所需 pom.xml-------------------------------------------------

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.xs</groupId>
  <artifactId>guimei</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>guimei Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>


  <dependencies>
    <!-- spring -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.22</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.3.22</version>
    </dependency>

    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.9.1</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.3.22</version>
    </dependency>

    <!-- mybatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.7</version>
    </dependency>

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.9</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.29</version>
    </dependency>

    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.2.9</version>
    </dependency>

    <!-- 其他相关依赖 -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.24</version>
    </dependency>

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.13.3</version>
    </dependency>

    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>

    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1.2</version>
    </dependency>

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

    <!-- 文件上传 -->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.4</version>
    </dependency>

    <!-- easyexcel -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>easyexcel</artifactId>
      <version>3.0.5</version>
    </dependency>

    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>2.0.7</version>
    </dependency>

  </dependencies>


</project>


 

1. 此案例所需pom.xml 结束-------------------------------------------------------

1.1.1 此外还需导入layUI(在仓库)

2. webapp

WEB-INF

web.xml
 

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <!-- 配置多个applicationContext.xml -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:applicationContext-*.xml</param-value>
  </context-param>

  <!-- 该监听器用于加载applicationContext.xml -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- 前端控制器 -->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <!-- 加载springmvc.xml -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>

  </servlet>

  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.css</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.jpg</url-pattern>
  </servlet-mapping>

</web-app>

3. HTML

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <title>layout 管理系统大布局 - Layui</title>
  <link rel="stylesheet" href="/layui/css/layui.css">
</head>
<body>
<div class="layui-layout layui-layout-admin">
  <div class="layui-header">
    <div class="layui-logo layui-hide-xs layui-bg-black">xx商城后台管理</div>
    <!-- 头部区域(可配合layui 已有的水平导航) -->
    <ul class="layui-nav layui-layout-left">
      <!-- 移动端显示 -->
      <li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-header-event="menuLeft">
        <i class="layui-icon layui-icon-spread-left"></i>
      </li>

      <li class="layui-nav-item layui-hide-xs"><a href="">导航一</a></li>
      <li class="layui-nav-item layui-hide-xs"><a href="">导航二</a></li>
      <li class="layui-nav-item layui-hide-xs"><a href="">导航三</a></li>
<!--      <li class="layui-nav-item">-->
<!--        <a href="javascript:;">nav groups</a>-->
<!--        <dl class="layui-nav-child">-->
<!--          <dd><a href="">menu 11</a></dd>-->
<!--          <dd><a href="">menu 22</a></dd>-->
<!--          <dd><a href="">menu 33</a></dd>-->
<!--        </dl>-->
<!--      </li>-->
    </ul>
    <ul class="layui-nav layui-layout-right">
      <li class="layui-nav-item layui-hide layui-show-md-inline-block">
        <a href="javascript:;">
          <img src="https://tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" class="layui-nav-img">
          admin
        </a>
        <dl class="layui-nav-child">
          <dd><a href="">个人资料</a></dd>
          <dd><a href="">设置</a></dd>
<!--            <a href="#" target="_top">退出</a>-->
          <dd><a href="/admin/logout" target="_top">退出</a></dd>
        </dl>
      </li>
      <li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
        <a href="javascript:;">
          <i class="layui-icon layui-icon-more-vertical"></i>
        </a>
      </li>
    </ul>
  </div>

  <div class="layui-side layui-bg-black">
    <div class="layui-side-scroll">
      <!-- 左侧导航区域(可配合layui已有的垂直导航) -->
      <ul class="layui-nav layui-nav-tree" lay-filter="test">
        <li class="layui-nav-item layui-nav-itemed">
          <a class="" href="javascript:;">用户管理</a>
          <dl class="layui-nav-child">
            <!-- 1、   onclick:单击事件 = 跳转页面
                 2、openUrl 用户查询的Js方法 126行实现
                  -->
            <dd><a href="javascript:;" onclick="openUrl('userList.html')">用户查询</a></dd>
            <dd><a href="javascript:;" onclick="openUrl('userAdd.html')">用户新增</a></dd>
            <dd><a href="javascript:;" onclick="openUrl('userGender.html')">用户男女比例</a></dd>
            <dd><a href="javascript:;" onclick="openUrl('userAddress.html')">用户位置分布</a></dd>
          </dl>
        </li>

        <li class="layui-nav-item">
          <a class="" href="javascript:;">公告管理</a>
          <dl class="layui-nav-child">
            <dd><a href="javascript:;">公告查询</a></dd>
            <dd><a href="javascript:;">公告新增</a></dd>
          </dl>
        </li>
      </ul>
    </div>
  </div>
<!-- 3、主页面中间显示内容-->
  <div class="layui-body" id="center">
    <!-- 内容主体区域 -->
    <div style="padding: 15px;">内容主体区域。记得修改 layui.css 和 js 的路径</div>
  </div>

  <div class="layui-footer">
    <!-- 底部固定区域 -->
    底部固定区域
  </div>
</div>
<script src="/layui/layui.js"></script>
<script>
  //JS
  layui.use(['element', 'layer', 'util'], function(){
    var element = layui.element
            ,layer = layui.layer
            ,util = layui.util
            ,$ = layui.$;

    //头部事件
    util.event('lay-header-event', {
      //左侧菜单事件
      menuLeft: function(othis){
        layer.msg('展开左侧菜单的操作', {icon: 0});
      }
      ,menuRight: function(){
        layer.open({
          type: 1
          ,content: '<div style="padding: 15px;">处理右侧面板的操作</div>'
          ,area: ['260px', '100%']
          ,offset: 'rt' //右上角
          ,anim: 5
          ,shadeClose: true
        });
      }
    });

  });
</script>
</body>

<!-- 4、引入jquery.js -->
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.5.1.min.js"></script>

<script type="application/javascript">

    <!-- 2、js方法 url:地址   -->
  function openUrl(url){
    // 2.1、  点用户查询就是 URL 就是 ArrayList
    // 2.2、  点用户新增就是 URL 就是 UserAdd
    //alert(url);

    // $("#center").load(url) 此方法 就是打开中间页面
    $("#center").load(url);// 加载相关路径
  }

</script>


</html>

userAdd.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/layui/css/layui.css">
</head>

<script src="/layui/layui.js" charset="utf-8"></script>

<body>
<form class="layui-form" action="/user/addUser">
    <div class="layui-form-item">
        <label class="layui-form-label">用户名</label>
        <div class="layui-input-block">
            <!--  lay-verify="required": 必需写 -->
            <input type="text" name="userName" required  lay-verify="required" placeholder="请输入用户名" autocomplete="off" class="layui-input">
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label">密码框</label>
        <div class="layui-input-inline">
            <input type="password" name="userPwd" required lay-verify="required" placeholder="请输入密码" autocomplete="off" class="layui-input">
        </div>
<!--        <div class="layui-form-mid layui-word-aux">密码必须以字母开头</div>-->
        <div class="layui-form-mid layui-word-aux">请不要忘记密码</div>
    </div>

    <div class="layui-form-item">
        <label class="layui-form-label">真实姓名</label>
        <div class="layui-input-block">
            <input type="text" name="userRealname" class="layui-input">
        </div>
    </div>

    <div class="layui-form-item">
        <label class="layui-form-label">性别</label>
        <div class="layui-input-block">
            <input type="radio" name="userGender" value="男" title="男">
            <input type="radio" name="userGender" value="女" title="女" checked>
        </div>
    </div>

    <div class="layui-form-item">
        <label class="layui-form-label">邮箱</label>
        <div class="layui-input-block">
            <input type="text" name="userEmail" class="layui-input">
        </div>
    </div>

    <div class="layui-form-item">
        <label class="layui-form-label">电话</label>
        <div class="layui-input-block">
            <input type="text" name="userPhone" class="layui-input">
        </div>
    </div>

    <div class="layui-form-item">
        <label class="layui-form-label">身份证号</label>
        <div class="layui-input-block">
            <input type="text" name="userId" class="layui-input">
        </div>
    </div>

    <div class="layui-form-item">
        <div class="layui-inline">
            <label class="layui-form-label">日期</label>
            <div class="layui-input-inline">
                <input type="text" name="userBirthdate" class="layui-input" id="userBirthdate" placeholder="yyyy-MM-dd">
            </div>
        </div>
    </div>

    <div class="layui-form-item">
        <label class="layui-form-label">是否锁定</label>
        <div class="layui-input-block">
            <select name="userLock" lay-verify="required">
                <option value=""></option>
                <option value="0">解锁</option>
                <option value="1">锁定</option>
            </select>
        </div>
    </div>

    <div class="layui-form-item">
        <label class="layui-form-label">地址</label>
        <div class="layui-input-block">
            <input type="text" name="userAddress" class="layui-input">
        </div>
    </div>

    <div class="layui-upload-drag" id="test10">
        <i class="layui-icon"></i>
        <p>点击上传,或将文件拖拽到此处</p>
        <div class="layui-hide" id="uploadDemoView">
            <hr>
            <img src="" alt="上传成功后渲染" style="max-width: 196px">
        </div>
    </div>


    <div class="layui-form-item">
        <div class="layui-input-block"><!-- lay-filter="formDemo">立即提交: 118行实现方法 -->
            <button class="layui-btn" lay-submit lay-filter="formDemo">立即提交</button>
            <button type="reset" class="layui-btn layui-btn-primary">重置</button>
        </div>
    </div>
</form>

</body>

<script>
    //Demo
    layui.use('form', function(){
        var form = layui.form;

        //监听提交
        form.on('submit(formDemo)', function(data){
            //layer.msg(JSON.stringify(data.field));
            return true;//true表示走action
        });
    });
</script>

<script>
    layui.use('laydate', function(){
        var laydate = layui.laydate;

        //常规用法
        laydate.render({
            elem: '#userBirthdate'
        });
    });
</script>


<script>
    layui.use(['upload'], function(){
        var $ = layui.jquery,
            upload = layui.upload

        //拖拽上传
        upload.render({
            elem: '#test10'
            ,url: '/user/upload' //此处用的是第三方的 http 请求演示,实际使用时改成您自己的上传接口即可。
            ,done: function(res){
                layer.msg('上传成功');
                layui.$('#uploadDemoView').removeClass('layui-hide').find('img').attr('src', res.data);
                console.log(res)
            }
        });

    });
</script>


</html>

userList.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Layui</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <link rel="stylesheet" href="/layui/css/layui.css" tppabs="http://res.layui.com/layui/dist/css/layui.css"  media="all">
    <!-- 注意:如果你直接复制所有代码到本地,上述css路径需要改成你本地的 -->
</head>
<body>

<table class="layui-hide" id="test" lay-filter="test"></table>

<script type="text/html" id="toolbarDemo">
    <div class="layui-btn-container">
        <button class="layui-btn layui-btn-sm" lay-event="batchDel">批量删除</button><!-- 88行实现方法 -->
        <button class="layui-btn layui-btn-sm" lay-event="writeExcel">导出Excel</button><!-- 111行实现方法 -->
        <button class="layui-btn layui-btn-sm" lay-event="getExcelTemplate">获取Excel模板</button><!-- 126行实现方法 -->
        <!-- 330行实现方法 -->
        <button type="button" class="layui-btn" id="test1">
            <i class="layui-icon">&#xe67c;</i>导入Excel
        </button>

    </div>
</script>

<script type="text/html" id="barDemo">
    <a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a><!-- 162行 实现编辑方法-->
    <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
</script>


<script src="/layui/layui.js" charset="utf-8"></script>
<!-- 注意:如果你直接复制所有代码到本地,上述 JS 路径需要改成你本地的 -->

<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.5.1.min.js"></script>

<script>
    layui.use('table', function(){
        var table = layui.table;

        table.render({
            elem: '#test'
            ,url:'/user/findByPage'/*tpa=https://www.layuiweb.com/test/table/demo1.json*/
            ,toolbar: '#toolbarDemo' //开启头部工具栏,并为其绑定左侧模板
            ,defaultToolbar: ['filter', 'exports', 'print', { //自定义头部工具栏右侧图标。如无需自定义,去除该参数即可
                title: '提示'
                ,layEvent: 'LAYTABLE_TIPS'
                ,icon: 'layui-icon-tips'
            }]
            ,title: '用户数据表'
            ,cols: [[
                {type: 'checkbox', fixed: 'left'}
                ,{field:'id', title:'ID', width:100, fixed: 'left', sort: true}
                ,{field:'userName', title:'用户名', width:100}
                ,{field:'userPwd', title:'密码', width:100}
                ,{field:'userRealname', title:'真实名称', width:100}
                ,{field:'userGender', title:'性别', width:100}
                ,{field:'userEmail', title:'邮箱', width:100}
                ,{field:'userId', title:'身份证', width:100}
                ,{field:'userBirthdate', title:'生日', width:100,
                    templet:"<div>{{ layui.util.toDateString(d.userBirthdate,'yyyy-MM-dd') }}</div>"
                 }
                ,{field:'userLock', title:'锁定状态', width:100}
                ,{field:'userAddress', title:'地址', width:100}
                ,{field:'userImage', title:'头像', width:100,
                    templet:"<div><img src='{{ d.userImage }}' width='50' height='50'></div>"
                 }

                ,{fixed: 'right', title:'操作', toolbar: '#barDemo', width:150}
            ]]
            //,page: true
            ,page: { //支持传入 laypage 组件的所有参数(某些参数除外,如:jump/elem) - 详见文档
                layout: ['limit', 'count', 'prev', 'page', 'next', 'skip'] //自定义分页布局
                ,curr: 1 //设定初始在第 1 页
                ,groups: 3 //只显示 3 个连续页码
                ,first: "首页" //不显示首页
                ,last: "尾页" //不显示尾页
                ,limit:3
                ,limits:[3,7,10]

            }
        });

        //头工具栏事件
        table.on('toolbar(test)', function(obj){
            var checkStatus = table.checkStatus(obj.config.id);
            switch(obj.event){
                case 'batchDel':
                    var data = checkStatus.data;
                    //layer.alert(JSON.stringify(data));
                    //获取选中数据的id
                    var ids = "";
                    //遍历
                    for(let i = 0; i < data.length; i++){
                        ids += "&ids=" + data[i].id;
                    }
                    alert("批量删除的ids:" + ids)

                    //发送ajax,调用后台接口
                    $.get("/user/deleteByIds", ids,
                        function(data){
                            if("success" == data){
                                table.reload("test",{});//重载当前表格
                            }
                    });

                    break;
                case 'writeExcel':<!-- 实现方法导出Excel -->
                    var data = checkStatus.data;
                    //layer.msg('选中了:'+ data.length + ' 个');

                    //获取选中数据的id
                    var ids = "";
                    //遍历
                    for(let i = 0; i < data.length; i++){
                        ids += "&ids=" + data[i].id;
                    }
                    alert("要查询的ids:" + ids)

                    location.href = "/user/findByIds?ids="+ids;

                    break;
                case 'getExcelTemplate':
                    //layer.msg(checkStatus.isAll ? '全选': '未全选');

                    location.href = "/excel/user.xlsx"

                    break;

                //自定义头工具栏右侧图标 - 提示
                case 'LAYTABLE_TIPS':
                    layer.alert('这是工具栏右侧自定义的一个图标按钮');
                    break;
            };
        });

        //监听行工具事件
        table.on('tool(test)', function(obj){
            var data = obj.data;
            //console.log(obj)
            if(obj.event === 'del'){
                layer.confirm('真的删除行么', function(index){
                    obj.del();//删除结构,没有调用后台接口
                    layer.close(index);

                    //获取id,删除
                    var deleteId = data.id;

                    //发送ajax,调用后台接口
                    $.get("/user/deleteById", { "id": deleteId },
                        function(data){
                            if("success" == data){
                                table.reload("test",{});//重载当前表格
                            }
                    });

            // 编辑方法
                });
            } else if(obj.event === 'edit'){
                // layer.prompt({
                //     formType: 2
                //     ,value: data.email
                // }, function(value, index){
                //     obj.update({
                //         email: value
                //     });
                //     layer.close(index);
                // });

                //编辑之前需要查询单个
                //layer.alert(JSON.stringify(data));
                findById(data);
            }
        });
    });
</script>
</body>

<script>

    function findById(data) {
        //弹框
        layer.open({
            type: 1,
            content: $("#updateForm").html(),
            title: ['修改页面', 'font-size:18px;'],
            area: ['600px', '600px'],

            //弹出后回调
            success: function(){
                $("#id").val(data.id);
                $("#userName").val(data.userName);
                $("#userPwd").val(data.userPwd);
                $("#userRealname").val(data.userRealname);

                if('男' == data.userGender){
                    $("#userGender").append("<input type='radio' name='userGender' value='男' checked />"+'男'+"<input type='radio' name='userGender' value='女'/>"+'女'+"")
                }else{
                    $("#userGender").append("<input type='radio' name='userGender' value='男' />"+'男'+"<input type='radio' name='userGender' value='女' checked />"+'女'+"")
                }

                $("#userEmail").val(data.userEmail);
                $("#userPhone").val(data.userPhone);
                $("#userId").val(data.userId);
                $("#userBirthdate").val(layui.util.toDateString(data.userBirthdate,'yyyy-MM-dd'));

                if("0" == data.userLock){
                    $("#userLock").append("<option value='0' selected>"+'解锁'+"</option> <option value='1'>"+'锁定'+"</option>");
                }else{
                    $("#userLock").append("<option value='0' >"+'解锁'+"</option> <option value='1' selected>"+'锁定'+"</option>");
                }

                $("#userAddress").val(data.userAddress);

                //渲染页面
                layui.form.render();
            },

            btn: ['提交', '取消']
            ,yes: function(index, layero){
                alert("-----")

                //修改操作
                $.get("/user/updateUser", $("#updateUser").serialize(),
                    function(data){
                        if("success" == data){
                            location.reload();//刷新当前页面
                        }
                    });

            }
            ,btn2: function(index, layero){
                alert("取消")
            }
        });


    }

</script>

<script type="text/html" id="updateForm">

    <form class="layui-form" id="updateUser">

        <!-- 把id 作为隐藏域传过去 -->
        <input type="hidden" name="id" id="id">

        <div class="layui-form-item">
            <label class="layui-form-label">用户名</label>
            <div class="layui-input-block">
                <input type="text" name="userName" id="userName" required  lay-verify="required" placeholder="请输入用户名" autocomplete="off" class="layui-input">
            </div>
        </div>
        <div class="layui-form-item">
            <label class="layui-form-label">密码框</label>
            <div class="layui-input-inline">
                <input type="password" name="userPwd" id="userPwd" required lay-verify="required" placeholder="请输入密码" autocomplete="off" class="layui-input">
            </div>
            <div class="layui-form-mid layui-word-aux">密码必须以字母开头</div>
        </div>

        <div class="layui-form-item">
            <label class="layui-form-label">真实姓名</label>
            <div class="layui-input-block">
                <input type="text" name="userRealname" id="userRealname" class="layui-input">
            </div>
        </div>

        <div class="layui-form-item">
            <label class="layui-form-label">性别</label>
            <div class="layui-input-block" id="userGender">


            </div>
        </div>

        <div class="layui-form-item">
            <label class="layui-form-label">邮箱</label>
            <div class="layui-input-block">
                <input type="text" name="userEmail" id="userEmail" class="layui-input">
            </div>
        </div>

        <div class="layui-form-item">
            <label class="layui-form-label">电话</label>
            <div class="layui-input-block">
                <input type="text" name="userPhone" id="userPhone" class="layui-input">
            </div>
        </div>

        <div class="layui-form-item">
            <label class="layui-form-label">身份证号</label>
            <div class="layui-input-block">
                <input type="text" name="userId" id="userId" class="layui-input">
            </div>
        </div>

        <div class="layui-form-item">
            <div class="layui-inline">
                <label class="layui-form-label">日期</label>
                <div class="layui-input-inline">
                    <input type="date" name="userBirthdate" id="userBirthdate" class="layui-input" id="userBirthdate" placeholder="yyyy-MM-dd">
                </div>
            </div>
        </div>

        <div class="layui-form-item">
            <label class="layui-form-label">是否锁定</label>
            <div class="layui-input-block">
                <select name="userLock" id="userLock" lay-verify="required">

                </select>
            </div>
        </div>

        <div class="layui-form-item">
            <label class="layui-form-label">地址</label>
            <div class="layui-input-block">
                <input type="text" name="userAddress" id="userAddress" class="layui-input">
            </div>
        </div>

    </form>

</script>
<!-- 导入Excel -->
<script>
    layui.use('upload', function(){
        var upload = layui.upload;

        //执行实例
        var uploadInst = upload.render({
            elem: '#test1' //绑定元素
            ,accept: 'file'
            ,url: '/user/readExcel' //上传接口
            ,done: function(res){
                if("success" == res.msg){
                    alert("导入数据成功");
                    location.reload();
                }
            }
            ,error: function(){
                //请求异常回调
                alert("导入数据失败")
            }
        });
    });
</script>

</html>

userAddress.html用户位置分布

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户位置分布</title>
</head>

<!-- 引入刚刚下载的 ECharts 文件 -->
<script src="/js/echarts.min.js"></script>
<!-- jquery.js -->
<script src="https://s3.pstatp.com/cdn/expire-1-M/jquery/3.3.1/jquery.min.js"></script>

<body>
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="main" style="width: 600px;height:400px;"></div>
</body>

<script>

    var chartDom = document.getElementById('main');
    var myChart = echarts.init(chartDom);

    option = {
        tooltip: {
            trigger: 'item'
        },
        legend: {
            top: '5%',
            left: 'center'
        },
        series: [
            {
                name: 'Access From',
                type: 'pie',
                radius: ['40%', '70%'],
                avoidLabelOverlap: false,
                itemStyle: {
                    borderRadius: 10,
                    borderColor: '#fff',
                    borderWidth: 2
                },
                label: {
                    show: false,
                    position: 'center'
                },
                emphasis: {
                    label: {
                        show: true,
                        fontSize: '40',
                        fontWeight: 'bold'
                    }
                },
                labelLine: {
                    show: false
                },
                data: [
                    // { value: 1048, name: 'Search Engine' },
                    // { value: 735, name: 'Direct' },
                    // { value: 580, name: 'Email' },
                    // { value: 484, name: 'Union Ads' },
                    // { value: 300, name: 'Video Ads' }
                ]
            }
        ]
    };

    //myChart.setOption(option);
    //发送ajax
    $.get("/user/getUserAddressDto",
        function(userAddressDto){
            alert("userAddressDto:" + userAddressDto)
            //赋值
            option.series[0].data = userAddressDto;

            //配置
            myChart.setOption(option);
        });

</script>

</html>

userGender.html柱状图男女人数

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>柱状图男女人数</title>
</head>

<!-- 导入本地echarts.js -->
<script src="/js/echarts.min.js"></script>
<!-- 导入官方jquery.js -->
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.5.1.min.js"></script>

<body>
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
    // 基于准备好的dom,初始化echarts实例
    var myChart = echarts.init(document.getElementById('main'));

    // 指定图表的配置项和数据
    var option = {
        title: {
            text: '用户性别比例'
        },
        tooltip: {},
        legend: {
            data: ['性别']
        },
        xAxis: {
            //data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
        },
        yAxis: {},
        series: [
            // {
            //   name: '性别',
            //   type: 'bar',
            //   data: [5, 20, 36, 10, 10, 20]
            // }
        ]
    };

    // 使用刚指定的配置项和数据显示图表。
    //myChart.setOption(option);

    //发送ajax
    $.get("/user/getUserGenderDto",
        function(userGenderDto){
            //赋值
            option.xAxis.data = userGenderDto.genderData;
            option.series = userGenderDto;

            //配置
            myChart.setOption(option);
        });

</script>
</body>




</html>

adminLogin.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>无标题文档</title>
    <link rel="stylesheet" type="text/css" href="css/htstart.css"/>
    <link rel="stylesheet" type="text/css" href="css/htenter.css"/>
</head>

<body onload="showTime()">
<div align="center" style="height:150px;">
    <div id="gmsctp">
        <img src="image/logo.jpg"/>
    </div>

    <div id="daohang">
        <ul>
            <li>
                <a href="#">首页</a></li>
            <li>
                <a href="#">用户</a></li>
            <li style="width:100px; background-size:100px 33px;">
                <a href="#">商品分类</a></li>
            <li>
                <a href="#">订单</a></li>
            <li style="width:100px; background-size:100px 33px;">
                <a href="#">商品详情</a></li>
            <li>
                <a href="#">公告</a></li>
        </ul>
    </div>

    <div id="time" >
        <font>管理员您好,今天是<span id="currentTime">2015-11-26</span>,欢迎回到管理后台。</font>
    </div>

    <div id="weizi">
        <font>您现在的位置: <a href="#">贵美商城</a> > 管理后台</font>
    </div>
</div>
<br />

<div align="center">
    <div id="denglu" >
        <div align="left">
            &nbsp;<img src="image/redarrows.jpg"/>&nbsp;<b>管理首页</b>
        </div>

        <hr color="#FF5F11" />
        <br /><br /><br /><br />

        <div id="hydl">欢迎登录贵美商城系统</div>
        <br /><br />

        <form action="/admin/login">
            <div id="xinxi">
                &nbsp;用户名:&nbsp;<input type="text" name="adminName"/><br /><br />
                登录密码:&nbsp;<input type="password" name="adminPwd" style="width:160px;"/>
            </div><br />

            <input name="submit" type="submit" id="submit" value="立即登录" />
        </form>
    </div>
</div>

<br /><br /><br />
<div id="xia">
    Copyright &copy; yangl ALL Rights Reserved.京ICP证1000001号
</div>
</body>

<script>

    function showTime(){
        let spanNode = document.getElementById("currentTime");
        spanNode.innerHTML = new Date().toLocaleTimeString();
    }

    //每隔多久调用一次该函数,1000毫秒
    setInterval("showTime()",1000)

</script>

</html>

3. resources

applicationContext-aop.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->

        <!-- 配置springmvc三大组件 -->
        <mvc:annotation-driven></mvc:annotation-driven>

        <!-- 扫描包下的注解,springmvc只扫描controller层
         切记:只对web层扫描,否则可能出现问题,比如:AOP不生效
         -->
        <context:component-scan base-package="com.qf.controller"></context:component-scan>

        <!-- 放行静态资源 -->
        <mvc:default-servlet-handler></mvc:default-servlet-handler>

        <!-- 配置文件 -->
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        </bean>

        <!-- 配置拦截器 -->
        <mvc:interceptors>
                <mvc:interceptor>
                        <mvc:mapping path="/**"/>
                        <bean class="com.qf.interceptor.LoginIntercetor"></bean>
                </mvc:interceptor>
        </mvc:interceptors>
</beans>

applicationContext-bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->

    <!-- 扫描对应包下的注解 -->
    <context:component-scan base-package="com.qf">
        <!-- 排除要扫描的注解 -->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!-- 导入jdbc.properties -->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

    <!-- dataSource连接数据库 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="username" value="${jdbc.username}"></property>
            <property name="password" value="${jdbc.password}"></property>
            <property name="url" value="${jdbc.url}"></property>
            <property name="driverClassName" value="${jdbc.driverClassName}"></property>
    </bean>

    <!-- sqlSessionFactoryBean -->
    <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 必选属性 -->
        <property name="dataSource" ref="dataSource"></property>
        <!-- 加载Mapper.xml文件 -->
        <property name="mapperLocations" value="classpath:mapper/*.xml"></property>
        <!-- 加载mybatis-config.xml -->
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>

        <!-- 配置分页 -->
        <property name="plugins">
            <array>
                <bean class="com.github.pagehelper.PageInterceptor">
                    <property name="properties">
                        <!--使用下面的方式配置参数,一行配置一个 -->
                        <value>
                            helperDialect=mysql
                            reasonable=true
                            supportMethodsArguments=true
                        </value>
                    </property>
                </bean>
            </array>
        </property>


    </bean>

    <!-- 扫描Mapper接口,生成代理对象 -->
    <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.qf.mapper"></property>
    </bean>

    <!-- AOP的配置 -->
    <!-- TX的配置 -->

</beans>

applicationContext-tx.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->


    <!-- dataSource连接数据库 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="driverClassName" value="${jdbc.driverClassName}"></property>
    </bean>


    <!-- 配置事务(使用xml方式配置) -->
    <!-- 事务平台管理器,封装了所有的事务操作,依赖数据源 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 配置事务通知 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!-- 对那些方法配置事务
                isolation:用于指定事务的隔离级别。默认值是DEFAULT,表示使用数据库的默认隔离级别。
                propagation:用于指定事务的传播行为。默认值是REQUIRED,表示一定会有事务,增删改的选择。查询方法可以选择SUPPORTS。
                read-only:用于指定事务是否只读。只有查询方法才能设置为true。默认值是false,表示读写。
                timeout:用于指定事务的超时时间,默认值是-1,表示永不超时。如果指定了数值,以秒为单位。
                rollback-for:用于指定一个异常,当产生该异常时,事务回滚,产生其他异常时,事务不回滚。没有默认值。表示任何异常都回滚。
                no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时事务回滚。没有默认值。表示任何异常都回滚。
        -->
        <tx:attributes>
            <tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
        </tx:attributes>
    </tx:advice>

    <!-- 配置织入 -->
    <aop:config>
        <!-- 配置切点 -->
        <aop:pointcut id="txPc" expression="execution( * com.qf.service.impl.*ServiceImpl.*(..))"/>
        <!-- 配置切面 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"></aop:advisor>
    </aop:config>

</beans>

jdbc.properties

jdbc.username=root(自己的账号)
jdbc.password=自己的密码
jdbc.url=jdbc:mysql://localhost:3306/guimeiuseUnicode=true&characterEncoding=utf8&useSSL=false```(自己的数据库)
jdbc.driver=com.mysql.cj.jdbc.Driver(注意版本是否添加.cj)

log4j.xml

<?xml version="1.0"  encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration PUBLIC "-//LOGGER"
        "http://org/apache/log4j/xml/log4j.dtd">
<log4j:configuration>

    <!-- org.apache.log4j.ConsoleAppender 输出到控制台 -->
    <appender name="myConsole" class="org.apache.log4j.ConsoleAppender">
        <!--输出格式-->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                   value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n"/>
        </layout>
    </appender>

    <!-- 输出到文件 -->
    <appender name="myFile1" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="d:/logs/mylog1.log"/><!--文件位置-->
        <param name="Append" value="true"/><!--是否选择追加-->
        <param name="MaxFileSize" value="1kb"/><!--文件最大字节数-->
        <param name="MaxBackupIndex" value="2" /><!--新文件数量-->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n" />
        </layout>
    </appender>

    <!-- 输出到文件(每天生成一个新的日志文件) -->
    <appender name="myFile2" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="d:/logs/mylog2.log"/><!--文件位置-->
        <param name="Append" value="true"/><!--是否选择追加-->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                   value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n"/>
        </layout>
    </appender>

    <!-- 根logger的设置-->
    <root>
        <!--优先级设置,all < trace < debug < info < warn < error < fatal < off -->
        <!-- 配置info,则info级别以上的信息都显示出来-->
        <priority value="all"/>
        <appender-ref ref="myConsole"/>
<!--        <appender-ref ref="myFile1"/>-->
<!--        <appender-ref ref="myFile2"/>-->
    </root>
</log4j:configuration>

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
   
    <!-- 配置日志 -->
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>

</configuration>

springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->

        <!-- 配置springmvc三大组件 -->
        <mvc:annotation-driven></mvc:annotation-driven>

        <!-- 扫描包下的注解,springmvc只扫描controller层
         切记:只对web层扫描,否则可能出现问题,比如:AOP不生效
         -->
        <context:component-scan base-package="com.qf.controller"></context:component-scan>

        <!-- 放行静态资源 -->
        <mvc:default-servlet-handler></mvc:default-servlet-handler>

        <!-- 配置文件 -->
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        </bean>

        <!-- 配置拦截器 -->
        <mvc:interceptors>
                <mvc:interceptor>
                        <mvc:mapping path="/**"/>
                        <bean class="com.qf.interceptor.LoginIntercetor"></bean>
                </mvc:interceptor>
        </mvc:interceptors>
</beans>

4. mapper

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

<mapper namespace="com.xs.mapper.UserMapper">
    <resultMap id="userMap" type="com.xs.entity.User">
        <id column="ID" property="id" jdbcType="INTEGER"/>
        <result column="USER_NAME" property="userName" jdbcType="VARCHAR"/>
        <result column="USER_PWD" property="userPwd" jdbcType="VARCHAR"/>
        <result column="USER_REALNAME" property="userRealname" jdbcType="VARCHAR"/>
        <result column="USER_GENDER" property="userGender" jdbcType="CHAR"/>
        <result column="USER_EMAIL" property="userEmail" jdbcType="VARCHAR"/>
        <result column="USER_PHONE" property="userPhone" jdbcType="CHAR"/>
        <result column="USER_ID" property="userId" jdbcType="CHAR"/>
        <result column="USER_BIRTHDATE" property="userBirthdate" jdbcType="DATE"/>
        <result column="USER_LOCK" property="userLock" jdbcType="INTEGER"/>
        <result column="USER_ADDRESS" property="userAddress" jdbcType="VARCHAR"/>
        <result column="USER_IMAGE" property="userImage" jdbcType="VARCHAR"/>
    </resultMap>

    <sql id="baseSql">
        select ID,
               USER_NAME,
               USER_PWD,
               USER_REALNAME,
               USER_GENDER,
               USER_EMAIL,
               USER_PHONE,
               USER_ID,
               USER_BIRTHDATE,
               USER_LOCK,
               USER_ADDRESS,
               USER_IMAGE
        from t_user
    </sql>


    <!-- 1、查询所有用户 -->
    <select id="findAll" resultMap="userMap">
        <include refid="baseSql"></include>
    </select>

    <!-- 2、添加用户 -->
    <insert id="addUser" parameterType="com.xs.entity.User">
        insert into t_user
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="userName != null">
                USER_NAME,
            </if>
            <if test="userPwd != null">
                USER_PWD,
            </if>
            <if test="userRealname != null">
                USER_REALNAME,
            </if>
            <if test="userGender != null">
                USER_GENDER,
            </if>
            <if test="userEmail != null">
                USER_EMAIL,
            </if>
            <if test="userPhone != null">
                USER_PHONE,
            </if>
            <if test="userId != null">
                USER_ID,
            </if>
            <if test="userBirthdate != null">
                USER_BIRTHDATE,
            </if>
            <if test="userLock != null">
                USER_LOCK,
            </if>
            <if test="userAddress != null">
                USER_ADDRESS,
            </if>
            <if test="userImage != null">
                USER_IMAGE,
            </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="userName != null">
                #{userName,jdbcType=VARCHAR},
            </if>
            <if test="userPwd != null">
                #{userPwd,jdbcType=VARCHAR},
            </if>
            <if test="userRealname != null">
                #{userRealname,jdbcType=VARCHAR},
            </if>
            <if test="userGender != null">
                #{userGender,jdbcType=CHAR},
            </if>
            <if test="userEmail != null">
                #{userEmail,jdbcType=VARCHAR},
            </if>
            <if test="userPhone != null">
                #{userPhone,jdbcType=CHAR},
            </if>
            <if test="userId != null">
                #{userId,jdbcType=CHAR},
            </if>
            <if test="userBirthdate != null">
                #{userBirthdate,jdbcType=DATE},
            </if>
            <if test="userLock != null">
                #{userLock,jdbcType=INTEGER},
            </if>
            <if test="userAddress != null">
                #{userAddress,jdbcType=VARCHAR},
            </if>
            <if test="userImage != null">
                #{userImage,jdbcType=VARCHAR},
            </if>
        </trim>
    </insert>

    <!-- 3、修改用户 -->
    <update id="updateUser" parameterType="com.xs.entity.User">
        update t_user
        <set>
            <if test="userName != null">
                USER_NAME = #{userName,jdbcType=VARCHAR},
            </if>
            <if test="userPwd != null">
                USER_PWD = #{userPwd,jdbcType=VARCHAR},
            </if>
            <if test="userRealname != null">
                USER_REALNAME = #{userRealname,jdbcType=VARCHAR},
            </if>
            <if test="userGender != null">
                USER_GENDER = #{userGender,jdbcType=CHAR},
            </if>
            <if test="userEmail != null">
                USER_EMAIL = #{userEmail,jdbcType=VARCHAR},
            </if>
            <if test="userPhone != null">
                USER_PHONE = #{userPhone,jdbcType=CHAR},
            </if>
            <if test="userId != null">
                USER_ID = #{userId,jdbcType=CHAR},
            </if>
            <if test="userBirthdate != null">
                USER_BIRTHDATE = #{userBirthdate,jdbcType=DATE},
            </if>
            <if test="userLock != null">
                USER_LOCK = #{userLock,jdbcType=INTEGER},
            </if>
            <if test="userAddress != null">
                USER_ADDRESS = #{userAddress,jdbcType=VARCHAR},
            </if>
            <if test="userImage != null">
                USER_IMAGE = #{userImage,jdbcType=VARCHAR},
            </if>
        </set>
        where ID = #{id,jdbcType=INTEGER}
    </update>

    <!-- 4、删除单个用户 -->
    <delete id="deleteById">
        delete from t_user
        <where>
            <if test="id != null">
                ID = #{id}
            </if>
        </where>
    </delete>

    <!-- 5、批量删除用户 -->
    <delete id="deleteByIds">
        delete from t_user
        <where>
            id in
            <foreach collection="array" open="(" close=")" separator="," item="id">
                #{id}
            </foreach>
        </where>
    </delete>
</mapper>

AdminMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

<mapper namespace="com.xs.mapper.AdminMapper">
    <resultMap id="adminMap" type="com.xs.entity.Admin">
        <id column="ADMIN_ID" property="adminId" jdbcType="INTEGER"/>
        <result column="ADMIN_NAME" property="adminName" jdbcType="VARCHAR"/>
        <result column="ADMIN_PWD" property="adminPwd" jdbcType="VARCHAR"/>
        <result column="ADMIN_REALNAME" property="adminRealname" jdbcType="VARCHAR"/>
        <result column="ADMIN_EMAIL" property="adminEmail" jdbcType="VARCHAR"/>
    </resultMap>

    <sql id="baseSql">
        select ADMIN_ID, ADMIN_NAME, ADMIN_PWD, ADMIN_REALNAME, ADMIN_EMAIL
        from t_admin
    </sql>

    <!-- 登录 -->
    <select id="login" resultMap="adminMap">
        <include refid="baseSql"></include>
        <where>
            ADMIN_NAME = #{adminName} and ADMIN_PWD = #{adminPwd}
        </where>
    </select>

</mapper>

二、JAVA

2.1 controller

2.1.1 AdminController

package com.xs.controller;

import com.xs.entity.Admin;
import com.xs.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@Controller
@RequestMapping("admin")
public class AdminController {

    @Autowired
    private AdminService adminService;

    /**
     * 登录
     * @param admin
     * @param httpSession
     * @return
     */
    @RequestMapping("login")
    public String login(Admin admin, HttpSession httpSession) {

        // 查询数据库
        Admin db_admin = adminService.login(admin);
        // 判断
        if (db_admin != null && db_admin.getAdminName() != null) {
            // 登录成功,放到session中
            httpSession.setAttribute("admin", db_admin);
            // 调用记录的方法(未写)

            return "redirect:/index.html";
        } else {
            return "redirect:/adminLogin.html";
        }
    }

    /**
     * 退出登录
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping("logout")
    public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
    // session(false)
        HttpSession session = request.getSession(false);
        session.removeAttribute("admin");//移除数据
//         销毁session invalidate: 无效 使session失效
//        session.invalidate();

        response.sendRedirect(request.getContextPath() + "/adminLogin.html");
    }
}

2.1.2 UserController

package com.xs.controller;

import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xs.dto.UserAddress;
import com.xs.dto.UserAddressDto;
import com.xs.dto.UserGenderDto;
import com.xs.entity.User;
import com.xs.service.UserService;
import com.xs.utils.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

@RestController// 1、控制器
@RequestMapping("user") // 2、请求映射:用在类上表示是一级路径
public class UserController {

    @Autowired// 3、自动接线---业务层
    private UserService userService;

    // 3.1 添加---用于接收上路径
    String userImagePath = null;

    @RequestMapping("findAll") // 4、请求映射:用在方法上表示是二级路径
    public List<User> fidAll() { // 5、查询所有方法
        return userService.findAll();
    }

    /**
     * 1、分页
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    @RequestMapping("findByPage")
    public JsonResult<User> findByPage(
            @RequestParam(value = "page", required = false, defaultValue = "1") Integer pageNum,
            @RequestParam(value = "limit", required = false, defaultValue = "3") Integer pageSize
    ) {

        // 设置分页参数
        PageHelper.startPage(pageNum, pageSize);
        // 只对紧跟startPage后面的方法才会进行分页
        List<User> userList = userService.findAll();
        // 封装到PageInfo对象中
        PageInfo<User> userPageInfo = new PageInfo<>(userList);
        // 判断
        if (userList != null) {
            // 返回分页数据
            JsonResult jsonResult = JsonResult.ok();
            // 返回分页数据
            jsonResult.setData(userPageInfo.getList());
            // 返回总记录数
            jsonResult.setCount(userPageInfo.getTotal());

            return jsonResult;
        }

        return JsonResult.error();
    }

    /**
     * 2、layUI上传封装对象的名称使用file
     */
    @RequestMapping("upload")
    public JsonResult upload(MultipartFile file) {

        // 2.1 获取上传路径
        String uploadPath = "D:\\tomcat-two\\apache-tomcat-9.0.33\\webapps\\guimei\\";

        // 2.2 获取上传的文件名
        String filename = file.getOriginalFilename();
        System.out.println(filename);
        // 2.3 如果图片名称是中文,需要转换
        try {
            filename = new String(filename.getBytes("iso-8859-1"), "utf-8");
            System.out.println("转换后的中文图片名称:" + filename);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        // 2.4 在上传之前我们要考虑文件名的唯一性
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        // 拼接后的文件名
        String uploadFileName = uuid + filename;
        System.out.println("上传的文件名:" + uploadFileName);

        // 2.5 创建上传的文件对象
        File uploadFile = new File(uploadPath, uploadFileName);

        // 2.6 上传
        try {
            file.transferTo(uploadFile);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 2.7 保存到数据库的路径
        userImagePath = "http://localhost:8083/guimei/" + uploadFileName;

        JsonResult jsonResult = JsonResult.ok();
        jsonResult.setData(userImagePath);

        return jsonResult;
    }

    /**
     * 3、添加
     */
    @RequestMapping("addUser")
    public void addUser(User user, HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println(user);
        // 设置上传路径
        if (user != null) {
            user.setUserImage(userImagePath);
            // 添加
            userService.addUser(user);
            // 跳转页面
            response.sendRedirect(request.getContextPath() + "/index.html");

        } else {
            throw new RuntimeException("user为空");
        }
    }

    /**
     * 4、修改
     */
    @RequestMapping("updateUser")
    public String updateUser(User user) {
        if (user != null) {
            userService.updateUser(user);
            return "success";
        } else {
            throw new RuntimeException("user为空");
        }
    }

    /**
     * 5、删除用户
     */
    @RequestMapping("deleteById")
    public String deleteById(Integer id) {
        userService.deleteById(id);
        return "success";
    }

    /**
     * 6、批量删除用户
     */
    @RequestMapping("deleteByIds")
    public String deleteByIds(Integer[] ids) {
        System.out.println("deleteByIds: " + Arrays.toString(ids));
        userService.deleteByIds(ids);
        return "success";
    }

    /**
     * 7、导出Excel
     */
    @RequestMapping("findByIds")
    public void findByIds(Integer[] ids, HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println(Arrays.toString(ids));

        // 7.1 判断ids不为空,确保导出数据存在数值
        if (ids != null && ids.length > 0) {
            List<User> userList = userService.findByIds(ids);// 返回7.2 User List集合
            System.out.println("userList: " + userList);

            // 7.3 第一种方式: 写入Excel System.currentTimeMillis() : 系统当前时间(选中对象的当前毫秒值)
//            String fileName = "D:/" + System.currentTimeMillis() + ".xlsx";
//            EasyExcel.write(fileName,User.class).sheet("模板").doWrite(userList);

            // 7.4 第二种方式: 以下载的方式导出Excel
            String fileName = System.currentTimeMillis() + ".xlsx";
            // 7.5 设置响应头,Content-Disposition: attachment; filename=aaa.zip --告诉浏览器以下载方式打开资源(文件下载)
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            // 7.6 获取流对象    = 响应.获取输出流
            ServletOutputStream outputStream = response.getOutputStream();
            // 7.7 写入Excel
            EasyExcel.write(outputStream, User.class).sheet("用户列表").doWrite(userList);
        } else {
            throw new RuntimeException("ids为空");
        }
    }

    /**
     * 8、导入Excel
     */
    @RequestMapping("readExcel")
    public JsonResult readExcel(MultipartFile file) {
        if (file != null) {
            userService.readExcel(file);
            return JsonResult.ok();
        }
        throw new RuntimeException("上传文件异常");
    }

    /**
     * 9、男女用户比例(柱状图)
     */
    @RequestMapping("getUserGenderDto")
    public UserGenderDto getUserGenderDto() {
        // 先去数据库查询男女人数(用户性别 Dto 列表)
        List<UserGenderDto> userGenderDtoList = userService.findGender();
        System.out.println(userGenderDtoList);

        // 存储: 男, 女
        String [] genders = new String[userGenderDtoList.size()];
        // 存储:7, 5
        Integer [] genderNums = new Integer[userGenderDtoList.size()];
        
        // 遍历并赋值 (用户性别 Dto 列表.size())
        for (int i = 0; i < userGenderDtoList.size(); i++) {
            genders[i] = userGenderDtoList.get(i).getGender();// 女
            genderNums[i] = userGenderDtoList.get(i).getGenderNum();// 5
        }

        // 赋值 用户性别 Dto
        UserGenderDto userGenderDto = new UserGenderDto();
        userGenderDto.setGendersDate(genders);

        userGenderDto.setName("性别");
        userGenderDto.setType("bar");
        userGenderDto.setData(genderNums);

        return userGenderDto;
    }

    /**
     * 10、获取用户位置以及人数
     */
    @RequestMapping("getUserAddressDto")
    public List<UserAddressDto> getUserAddressDto() {

        // 查询数据
        List<UserAddress> userAddressList = userService.findAddress();

        // 赋值
        List<UserAddressDto> userAddressDtoList = new ArrayList<>();

        // 遍历
        for (int i = 0; i < userAddressList.size(); i++) {
            UserAddressDto userAddressDto = new UserAddressDto();
            // 赋值
            userAddressDto.setName(userAddressList.get(i).getAddress());
            userAddressDto.setValue(BigDecimal.valueOf(userAddressList.get(i).getAddressNum()));
            // 添加到集合
            userAddressDtoList.add(userAddressDto);
        }
        return userAddressDtoList;
    }
}

2.2 dto
2.2.1 UserAddress用户地址

package com.xs.dto;

import lombok.Data;

@Data//用户地址
public class UserAddress {

    private String address;
    private Integer addressNum;
}


2.2.2 UserAddressDto用户位置分布

package com.xs.dto;

import lombok.Data;

import java.math.BigDecimal;

// 用户位置分布
@Data
public class UserAddressDto {

    private BigDecimal value;
    private String name;


}


2.2.3 UserGenderDto柱状图男女人数

package com.xs.dto;

import lombok.Data;

// 柱状图男女人数
@Data
public class UserGenderDto {

    // 性别数据内容
    private String [] gendersDate;

    private String name;
    private String type;
    // 数量
    private Integer [] data;

    // 另外声明两个属性,用于映射数据库中的数据
    private String gender;
    private Integer genderNum;
}


2.3 interceptor
2.3.1 listener登录拦截器

package com.xs.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.HashSet;
import java.util.Set;

// 登录拦截器
public class LoginInterceptor implements HandlerInterceptor {

    // 设置白名单
    private Set<String> whiteUrls = new HashSet<>();

    public LoginInterceptor() {
        // 自定义放行路径
        whiteUrls.add("/login");
        whiteUrls.add("/adminLogin.html");
        // 。。。。。
    }


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("登录拦截器preHandel");

        // 获取当前正在访问的路径
        String requestURL = request.getRequestURL().toString();// http://localhost:8080/index.html
        String requestURI = request.getRequestURI();// index.html

        System.out.println("requestURL:" + requestURL);
        System.out.println("requestURI:" + requestURI);

        // 遍历白名单
        for (String url : whiteUrls) {
            // 判断
            if (requestURL.endsWith(url)) {
            return true;
            }
        }

        // 如若已有登录,将放行
        HttpSession session = request.getSession(false);
        // 判断 登录状态是否存在
        if (session != null) {
            // 判断
            if (session.getAttribute("admin") != null) {
                return true;
            }
        }

        // 未登录去登录页面
        // 请求.获取请求调度程序
//        request.getRequestDispatcher("adminLogin.html").forward(request,response);
        response.sendRedirect("adminLogin.html");
        return false;
    }
}

2.4 mapper
2.4.1 AdminMapper 用户登录

package com.xs.mapper;

import com.xs.entity.Admin;
import org.springframework.stereotype.Repository;

@Repository //存储库
public interface AdminMapper {

    /**
     * 用户登录
     * @param admin
     * @return
     */
    Admin login(Admin admin);
}


2.4.2 UserMapper 数据访问层

package com.xs.mapper;

import com.xs.dto.UserAddress;
import com.xs.dto.UserGenderDto;
import com.xs.entity.User;
import org.springframework.stereotype.Repository;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

@Repository// 1、存储库
public interface UserMapper {

    /**
     * 查询所有用户
     * Mapper.xml实现查询所有方法
     * @return
     */
    List<User> findAll();

    /**
     * 添加用户
     * @param user
     */
    void addUser(User user);

    /**
     * 修改用户
     * @param user
     */
    void updateUser(User user);

    /**
     * 删除单个用户
     * @param id
     */
    void deleteById(Integer id);

    /**
     * 批量删除
     * @param ids
     */
    void deleteByIds(Integer[] ids);

    /**
     * 导出Excel
     * @param ids
     * @return
     */
    List<User> findByIds(Integer[] ids);

    /**
     * 批量插入
     * @param cachedDataList
     */
    void save(List<User> cachedDataList);

    /**
     * 获取男女人数
     * @return
     */
    List<UserGenderDto> findGender();

    /**
     * 用户地址以及人数
     * @return
     */
    List<UserAddress> findAddress();
}

2.5 entity
2.5.1 User

package com.xs.entity;

import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;
/**
 * 用户表t_user
 *CREATE TABLE t_user(
 *ID INT(10)PRIMARY KEY NOT NULL AUTO_INCREMENT,
 *USER_NAME VARCHAR(40),
 *USER_PWD VARCHAR(60),
 *USER_REALNAME VARCHAR(40),
 *USER_GENDER CHAR(2),
 *USER_EMAIL VARCHAR(60)UNIQUE,
 *USER_PHONE CHAR(11)UNIQUE,
 *USER_ID CHAR(18)UNIQUE,
 *USER_BIRTHDATE DATE,
 *USER_LOCK INT(1),
 *USER_ADDRESS VARCHAR(255),
 *USER_IMAGE VARCHAR(255)
 *)ENGINE=INNODB DEFAULT CHARSET=utf8;
 */

@Data
public class User {
    //@ExcelProperty("编号")//给导出的属性起别名
    private Integer id;
    //@ExcelProperty("姓名")
    private String userName;
    private String userPwd;
    private String userRealname;
    private String userGender;
    private String userEmail;
    private String userPhone;
    private String userId;
    // @DateTimeFormat: 日期时间格式((pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date userBirthdate;
    private Integer userLock;
    private String userAddress;
    //@ExcelIgnore//不导出该属性
    private String userImage;
}


2.5.2 Admin

package com.xs.entity;

import lombok.Data;

import java.io.Serializable;

@Data
public class Admin implements Serializable {

    private Integer adminId;
    private String adminName;
    private String adminPwd;
    private String adminRealname;
    private String adminEmail;
}


2.6 service 业务逻辑层

2.6.1 UserService

package com.xs.service;

import com.xs.dto.UserAddress;
import com.xs.dto.UserGenderDto;
import com.xs.entity.User;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * 业务逻辑层
 */
public interface UserService {

    /**
     * 查看所有用户
     * @return
     */
    List<User> findAll();

    /**
     * 添加用户
     * @param user
     */
    void addUser(User user);

    /**
     * 修改用户
     * @param user
     */
    void updateUser(User user);

    /**
     * 删除单个用户
     * @param id
     */
    void deleteById(Integer id);

    /**
     * 批量删除
     * @param ids
     */
    void deleteByIds(Integer[] ids);

    /**
     * 导出Excel
     * @param ids
     * @return
     */
    List<User> findByIds(Integer[] ids);

    /**
     * 导入Excel
     * @param file
     */
    void readExcel(MultipartFile file);

    /**
     * 获取男女人数
     * @return
     */
    List<UserGenderDto> findGender();

    /**
     * 获取用户地址以及人数
     * @return
     */
    List<UserAddress> findAddress();
}


2.6.2 AdminService 管理服务层

package com.xs.service;

import com.xs.entity.Admin;
import org.springframework.stereotype.Service;

@Service
public interface AdminService {

    /**
     * 用户登录
     * @param admin
     * @return
     */
    Admin login(Admin admin);
}

2.7 impl 接口实现
2.7.1 UserServiceImpl

package com.xs.service.impl;

import com.alibaba.excel.EasyExcel;
import com.xs.dto.UserAddress;
import com.xs.dto.UserGenderDto;
import com.xs.entity.User;
import com.xs.listener.UserListener;
import com.xs.mapper.UserMapper;
import com.xs.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

@Service // 1、业务逻辑接口实现类
public class UserServiceImpl implements UserService {

    @Autowired // 2、自动接线数据访问层
    private UserMapper userMapper;

    @Override // 3、重写业务逻辑层的查询所有用户方法
    public List<User> findAll() {
        return userMapper.findAll();
    }

    @Override // 4、添加用户
    public void addUser(User user) {
        userMapper.addUser(user);
    }

    @Override // 5、修改用户
    public void updateUser(User user) {
        userMapper.updateUser(user);
    }

    @Override // 6、删除用户
    public void deleteById(Integer id) {
        userMapper.deleteById(id);
    }

    @Override // 7、批量删除
    public void deleteByIds(Integer[] ids) {
        userMapper.deleteByIds(ids);
    }

    @Override // 8、导出Excel
    public List<User> findByIds(Integer[] ids) {
        return userMapper.findByIds(ids);
    }

    @Override // 9、导入Excel
    public void readExcel(MultipartFile file) {
        // 9.1 获取输入流对象
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 9.2 读取、导入 用流读取
        EasyExcel.read(inputStream, User.class, new UserListener(userMapper)).sheet().doRead();
    }

    @Override // 10、获取男女人数
    public List<UserGenderDto> findGender() {
        return userMapper.findGender();
    }

    @Override // 11、获取用户地址以及人数
    public List<UserAddress> findAddress() {
        return userMapper.findAddress();
    }
}


2.7.2 AdminServiceImpl 管理服务实现

package com.xs.service.impl;

import com.xs.entity.Admin;
import com.xs.mapper.AdminMapper;
import com.xs.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class AdminServiceImpl implements AdminService {

    @Autowired
    private AdminMapper adminMapper;

    /**
     * 用户登录
     * @param admin
     * @return
     */
    @Override
    public Admin login(Admin admin) {
        return adminMapper.login(admin);
    }
}


3 . utils

JsonResult (json结果 前端异步数据)

package com.xs.utils;

import lombok.Data;

@Data // 数据
public class JsonResult<T> {

    private Integer code;
    private String msg;
    private T data;
    private Long count; // 以layui默认规定的数据格式要求 声明

    // 成功返回
    public static JsonResult ok(){
        JsonResult jsonResult = new JsonResult<>();
        jsonResult.setCode(0);//layui中数据表格返回成功的code值,必须是0
        jsonResult.setMsg("success");

        return jsonResult;
    }

    // 失败返回
    public static JsonResult error(){
        JsonResult jsonResult = new JsonResult<>();
        jsonResult.setCode(-200);
        jsonResult.setMsg("fail");

        return jsonResult;
    }
}

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到