2.5.2.1 可视化项目, 需求分析与ssm环境搭建, 前台页面模块, 用户模块(登入登出, 分页显示, 添加删除)

目录

可视化项目

第1章 需求分析与环境搭建

1.项目分析

1.1 需求分析

1.2 项目技术栈

1.3 数据数据库设计

2.环境搭建

2.1 工程环境

2.2 数据库环境

2.3 项目结构

2.4 项目框架搭建

2.4.1.引入pom.xml

2.4.2.spring配置文件

2.4.3.连接池配置

2.4.4.mybatis 配置文件

2.4.5.springmvc配置文件

2.4.6.log4j.properties 日志

2.4.7.UserMapper.xml mybatis映射文件

2.4.8.配置web.xml

2.5 通用模块编写

2.5.1.封装服务器返回对象ServerResponse

2.5.2.服务器返回状态码

2.5.3.常量对象定义

3.测试后台环境

3.1 测试目标

3.2 测试方式

 

第2章 前台页面模块

1.引入前台静态资源

2.导航栏页面配置

 

第3章 用户模块

1.接口说明

2.用户表设计

3.用户登录

3.1 登录验证接口

3.2 用户登录页面

4.用户分页

4.1 用户列表分页接口设计

4.2 分页前台页面

5. 添加用户

5.1 添加用户接口设计

5.2 添加用户前台页面

6. 删除单个用户

6.1 删除用户接口设计

6.2 删除用户页面

7.用户登出

7.1 接口设计

7.2 前台页面


可视化项目

第1章 需求分析与环境搭建

1.项目分析

1.1 需求分析

用户登录


首页的原型

用户模块

招聘市场图表统计

1.2 项目技术栈

1.3 数据数据库设计

1.用户表user的描述

后台用户表信息

2.职位信息表 position_info_v2

描述职位及公司信息


3.职位类型信息表 position_type_info_v2
描述职位类型及公司信息


4.省份表 Province


5.城市表 City

2.环境搭建

2.1 工程环境

安装配置maven环境

学习资料中提供以下两个文件


解压后文件


配置环境变量

配置仓库

1、找到Maven解压目录\conf\settings.xml
2、在setting.xml 文件中找到 localRepository 标签
3、将 <localRepository>/path/to/local/repo</localRepository>从注释中取出
4、将标签体内容修改为自定义的Maven仓库目录

在maven的安装目录中 apache-maven-3.2.1/conf/settings.xml 配置本地仓库:

配置远程镜像

<mirror>
    <id>alimaven</id>
    <name>aliyun maven</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    <mirrorOf>central</mirrorOf>    
</mirror>

IDEA的jdk环境

lombok插件安装

2.2 数据库环境

数据库节点位于centos7-1 虚拟节点:

连接地址 : 192.168.80.100

修改linux下mysql的配置信息

MySQL根据配置文件会限制Server接受的数据包大小,有时候大的插入和更新会受 max_allowed_packet 参数限制,导致大数据写入或者更新失败。

1.查看目前配置
    mysql> show VARIABLES like 'max_allowed_packet';

    #max_allowed_packet的单位为字节:
    #转化为Mb,就是1024Mb

2.修改mysql配置文件
    可以编辑/etc/my.cnf,在[mysqld]段或者mysql的server配置段进行修改。
    max_allowed_packet = 800M

3.重启mysql

导入数据

数据表较大,首先创建数据库visualization ,然后导入表信息.

2.3 项目结构

公共基础模块common

        存放转换对象
        服务器通用返回对象
        响应码对象
        常量对象

控制层controller

        存放各个业务逻辑的控制器

服务层service

        服务接口
        服务器实现

持久mapper

        映射接口

模型层model

        存放数据模型

视图模型vo

        view object模型对象

工具util

        通用工具类

2.4 项目框架搭建

2.4.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.lagou</groupId>
  <artifactId>lg-visualization</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>


  <dependencies>

    <!-- 单元测试 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>

    <!-- Spring -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>

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

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>


    <!-- Mybatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.2.8</version>
    </dependency>


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

    <!-- MySql -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.46</version>
    </dependency>

    <!--日志包-->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.6.6</version>
    </dependency>

    <!-- 连接池 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.0.14</version>
    </dependency>


    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.2.1</version>
      <scope>provided</scope>
    </dependency>

    <!--json相关-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.9.0</version>
    </dependency>

    <!--lombok插件-->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.12</version>
    </dependency>


    <dependency>
      <groupId>commons-collections</groupId>
      <artifactId>commons-collections</artifactId>
      <version>3.2.1</version>
    </dependency>

    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.5</version>
    </dependency>


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

  </dependencies>

  <build>
    <plugins>
      <!-- 配置Tomcat插件 -->
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
          <path>/</path>
          <port>8080</port>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.2</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

配置文件的思路

整合环境思路:
一.Dao层
   1.配置文件
        1.mybatis-config.xml 
              1)驼峰命名
              2)包扫描别名
              3)分页插件
     2.AccountMapper.xml 暂时为空
     3.applicationContext-dao.xml
          1)加载外部数据库信息 jdbc.properites
          2)数据源的配置 druid
          3)SqlSessionFactoryBean (加载dataSource , 加载mybatis-config.xml)
          4)Mapper包扫描

二.service层
   1.配置
    applicationContext-service.xml
         1)包扫描service包
         2)注解的事务 (创建平台事务管理器, 创建注解驱动,挂载平台事务管理器)
      
 三.controller环境搭建
   1.配置
     springmvc.xml  扫描controller包 配置3大组件

     web.xml
          1.监听器 加载spring的所有配置文件
          2.前端控制器 加载springmvc.xml
          3.处理post中的乱码问题,编写过滤器

2.4.2.spring配置文件

applicationContext-dao.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">

    <!--1)加载外部数据库信息 jdbc.properites-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--2)数据源的配置 druid-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
       <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!--3)SqlSessionFactoryBean  (加载dataSource , 加载mybatis-config.xml)-->
    <bean id="sqlSesionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入连接池  -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 加载mybatis-config.xml  -->
        <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
    </bean>

    <!--4)Mapper包扫描-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 扫描映射文件比如:AccountMapper.xml 加载该文件; 还会扫描接口AccountMapper接口创建代理对象  -->
        <property name="basePackage" value="com.lagou.mapper"/>
    </bean>
</beans>

applicationContext-service.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" 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/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">

    <!--1)包扫描service包, 自动创建该包的对象-->
    <context:component-scan base-package="com.lagou.service"/>

    <!--2)注解的事务 (创建平台事务管理器, 创建注解驱动,挂载平台事务管理器)-->
    <!-- 创建平台事务管理器   -->
    <bean id="transactionMananger" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入连接池对象-->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--  创建注解驱动, 注解式管理事务  -->
    <tx:annotation-driven transaction-manager="transactionMananger"/>
</beans>

2.4.3.连接池配置

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.80.100:3306/visualization?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
jdbc.username=root
jdbc.password=123

2.4.4.mybatis 配置文件

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>
    <!-- 1)驼峰命名-->
    <settings>
        <!-- model中模型对象 userName , 和数据库user_name映射, N 和 _n 对应-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <!-- 2)包扫描别名-->
    <typeAliases>
        <!-- xxxMapper.xml中  要编写类的完全路径名,如果采用别名方式. 以后再映射文件中不用再写类的完全路径名 -->
        <package name="com.lagou.model"/>
        <package name="com.lagou.vo"/>
    </typeAliases>
    <!-- 3)分页插件-->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 分页参数合理化-->
            <property name="reasonable" value="true"/>
        </plugin>
    </plugins>
</configuration>

2.4.5.springmvc配置文件

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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

        <!--扫描controller包  -->
        <context:component-scan base-package="com.lagou.controller"/>

        <!--配置3大组件
            处理器映射器
            处理器适配器
            视图解析器
        -->
        <!--下面一个配置, 直接可以配置前两个-->
        <mvc:annotation-driven />

        <!--视图解析器-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        </bean>
</beans>

2.4.6.log4j.properties 日志

log4j.properties

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE            debug   info   warn error fatal
log4j.rootCategory=INFO, CONSOLE, LOGFILE

# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
#linux启动, 所以注掉下面的语句
#log4j.appender.LOGFILE.File=d:/axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

2.4.7.UserMapper.xml mybatis映射文件

映射文件开始只是一个测空的文件,里面根据业务添加响应的sql

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.lagou.mapper.UserMapper">

</mapper>

2.4.8.配置web.xml

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>

<!-- 1.1 配置context参数, 使用 -* 匹配两个applicationContext配置文件  -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring/applicationContext-*.xml</param-value>
  </context-param>

  <!--3.处理post中的乱码问题,编写过滤器-->
  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <!-- 设置编码为utf-8  -->
    <init-param>
      <param-name>encodingFilter</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

    <!--1.监听器  加载spring的所有配置文件-->
    <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

  <!--2.前端控制器  加载springmvc.xml
        1)tomcat启动的时候就运行该DispatcherServlet , 配置启动加载时机
        2)加载springmvc.xml
    -->
    <servlet>
      <servlet-name>DispatcherServlet</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc/springmvc.xml</param-value>
      </init-param>
      <!--下面的值越小, 加载时机越早-->
      <load-on-startup>2</load-on-startup>
    </servlet>  
    <servlet-mapping>
      <servlet-name>DispatcherServlet</servlet-name>
      <!--后缀是do时, 执行前端控制器-->
      <url-pattern>*.do</url-pattern>
    </servlet-mapping>
  
</web-app>

2.5 通用模块编写

2.5.1.封装服务器返回对象ServerResponse

package com.lagou.common;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.io.Serializable;
// 非空对象进行序列化
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class ServerResponse<T> implements Serializable {

    private int status;
    private String msg;
    private T data;

    // 禁止外部创建本类对象
    private ServerResponse(int status){
        this.status = status;
    }

    private ServerResponse(int status, T data){
        this.status = status;
        this.data = data;
    }

    private ServerResponse(int status,String msg,  T data){
        this.status = status;
        this.msg = msg;
        this.data = data;
    }

    private ServerResponse(int status,String msg){
        this.status = status;
        this.msg = msg;
    }

    //提供get方法, 后期返回json数据
    public int getStatus(){
        return status;
    }

    public T getData(){
        return data;
    }

    public String getMsg(){
        return msg;
    }

    // 针对不同情况分别提供方法, 向外部送出本类对象
    public static <T> ServerResponse<T> createBySucces(){
        return new ServerResponse<T>(ResponseCode.SUCCESS.getCode());
    }

    public static <T> ServerResponse<T> createBySuccessMsg(String msg){
        return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(),msg);
    }

    public static <T> ServerResponse<T> createBySuccessData(T data){
        return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(),data);
    }

    public static <T> ServerResponse<T> createBySuccessMsgData(String msg,T data){
        return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(),msg,data);
    }

    public static <T> ServerResponse<T> createByErrorMsg(String errorMsg){
        return new ServerResponse<>(ResponseCode.ERROR.getCode(),errorMsg);
    }
}

2.5.2.服务器返回状态码

package com.lagou.common;

public enum ResponseCode {

    SUCCESS(0,"SUCCESS"),
    ERROR(1,"ERROR");

    private final  int code;
    private final  String desc;

    ResponseCode(int code ,String desc){
        this.code = code;
        this.desc = desc;
    }

    public int getCode(){
        return code;
    }

    public String getDesc(){
        return desc;
    }
}

2.5.3.常量对象定义

package com.lagou.common;

public class Const {

    public static final  String CURRENT_USER="currentUser";
    public static final String USERNAME = "username";
    public static final String EMAIL ="email";
    public static final String[] INDUSTRY = {"销售","服务业","生产制造"};
    public static final String START_DATE ="2020-06-04 00:00:00";
    public static final String END_DATE ="2020-06-09 23:23:59";
    public static final String[] DATE_TIME = {"2020-06-04","2020-06-05","2020-06-06","2020-06-07","2020-06-08","2020-06-09"};
}

3.测试后台环境

3.1 测试目标

通过转账案例来测试ssm环境及ServerResponse可以正常返回

3.2 测试方式

1)创建account账户表

create table account (
username varchar(32),
 money double
);
insert into account values ('jack',1000);
insert into account values('rose',1000);

2)编写AccountMapper接口

package com.lagou.mapper;

public interface AccountMapper {

    //转入钱
    public void transferIn(@Param("name") String name, @Param("money") double money);

    //转出钱
    public void transferOut(@Param("name") String name, @Param("money") double money);
}

3)编写AccountMapper.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.lagou.mapper.AccountMapper">

    <!--  转入  -->
    <!--下面 #{} 写的是@Param注解的内容 -->
     <update id="transferIn"   >
         update account set money = money + #{money} where username = #{name}
     </update>

    <!--   转出 -->
    <update id="transferOut"   >
         update account set money = money - #{money} where username = #{name}
     </update>
</mapper>

4)编写AccountService

package com.lagou.service;

public interface IAccountService {

    //转账
    public int transfer(String inName, String outName, double money);
}

5)编写AccountServiceImpl

package com.lagou.service.impl;

@Service
@Transactional  //事务控制
public class AccountServiceImpl implements IAccountService {

    @Autowired
    private AccountMapper mapper;

    @Override
    public int transfer(String inName, String outName, double money) {
        try{
            //调用转入
            mapper.transferIn(inName,money);
            //调用转出
            mapper.transferOut(outName,money);
            return 0;
        }catch (Exception e){
            System.out.println(e);
            return 1;
        }
    }
}

6 ) Controller层代码测试类

package com.lagou.controller;

@Controller
@RequestMapping("/account")
public class AccountController {

    @Autowired
    private IAccountService service;

    @RequestMapping("transfer.do")
    @ResponseBody //
    public ServerResponse<String> accountTransfer(String inName, String outName,double money){

        // 调用转账方法, 拿到返回值
        int status = service.transfer(inName, outName, money);
        //如果执行转账成功
        if(ResponseCode.SUCCESS.getCode() == status){
            return ServerResponse.createBySuccessMsg("转账成功");
        }else{
            return  ServerResponse.createByErrorMsg("转账失败");
        }
    }
}

7) 使用postman测试接口
http://localhost:8080//lg_visualization/account/transfer.do?inName=jack&outName=rose&money=300

第2章 前台页面模块

1.引入前台静态资源

本项目已经准备好了前台的静态资源. 请将静态资源复制到web-app/view目录下

2.导航栏页面配置

1.目标:点击左侧导航栏页面在展示栏中展示信息


2.设计思路:
html中超链接添加onclick方法调用指定方法,传递页面名称

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
	<title><拉勾大数据可视化项目></拉勾大数据可视化项目></title>
	<meta name="keywords" content="admin, admin dashboard, admin template, cms, crm, Elmer Admin, Elmeradmin, premium admin templates, responsive admin, sass, panel, software, ui, dwh, web app, application" />
	<meta name="author" content="hencework"/>

	<!-- Data table CSS -->
	<link href="vendors/bower_components/datatables/media/css/jquery.dataTables.min.css" rel="stylesheet" type="text/css"/>
	<link href="vendors/bower_components/jquery-toast-plugin/dist/jquery.toast.min.css" rel="stylesheet" type="text/css">
	<!-- Custom CSS -->
	<link href="dist/css/style.css" rel="stylesheet" type="text/css">

</head>

<body>
<!-- 预加载 -->
<div class="preloader-it">
	<div class="la-anim-1"></div>
</div>
<!-- 预加载区域 -->
<div class="wrapper  theme-1-active pimary-color-blue" id="app">
	<!-- 顶部元素 nav -->
	<nav class="navbar navbar-inverse navbar-fixed-top">
		<div class="mobile-only-brand pull-left">
			<div class="nav-header pull-left">
				<div class="logo-wrap">
					<a href="index.html">
						<img class="brand-img" src="dist/img/logo.png" alt="brand"/>
						<span class="brand-text">拉勾</span>
					</a>
				</div>
			</div>
			<a id="toggle_nav_btn" class="toggle-left-nav-btn inline-block ml-20 pull-left" href="javascript:void(0);"><i class="zmdi zmdi-menu"></i></a>
			<a id="toggle_mobile_search" data-toggle="collapse" data-target="#search_form" class="mobile-only-view" href="javascript:void(0);"><i class="zmdi zmdi-search"></i></a>
			<a id="toggle_mobile_nav" class="mobile-only-view" href="javascript:void(0);"><i class="zmdi zmdi-more"></i></a>
			<form id="search_form" role="search" class="top-nav-search collapse pull-left">
				<div class="input-group">
					<input type="text" name="example-input1-group2" class="form-control" placeholder="Search">
					<span class="input-group-btn">
						<button type="button" class="btn  btn-default"  data-target="#search_form" data-toggle="collapse" aria-label="Close" aria-expanded="true"><i class="zmdi zmdi-search"></i></button>
						</span>
				</div>
			</form>
		</div>
		<div id="mobile_only_nav" class="mobile-only-nav pull-right">
			<ul class="nav navbar-right top-nav pull-right">
				<li class="dropdown auth-drp">
					<a href="#" class="dropdown-toggle pr-0" data-toggle="dropdown"><img src="dist/img/user1.png" alt="user_auth" class="user-auth-img img-circle"/><span class="user-online-status"></span></a>
					<ul class="dropdown-menu user-auth-dropdown" data-dropdown-in="flipInX" data-dropdown-out="flipOutX">
						<li>
							<a href="#"><i class="zmdi zmdi-account"></i><span>个人资料</span></a>
						</li>
						<li>
							<a href="#"><i class="zmdi zmdi-settings"></i><span>设置</span></a>
						</li>

						<li>
							<a href="#" onclick="logout()"><i class="zmdi zmdi-power"></i><span>退出</span></a>
						</li>
					</ul>
				</li>
			</ul>
		</div>
	</nav>
	<!-- /Top Menu Items -->
	<!-- 左侧导航栏 -->
	<div class="fixed-sidebar-left">
		<ul class="nav navbar-nav side-nav nicescroll-bar">
			<li class="navigation-header">
				<span>Main</span>
				<i class="zmdi zmdi-more"></i>
			</li>
			<li>
				<a href="javascript:void(0)" onclick="goPage('bigScreen')">
					<div class="pull-left"><i class="zmdi zmdi-flag mr-20"></i><span class="right-nav-text">
					首页</span></div><div class="pull-right"><span class="label label-warning">8</span>
				</div><div class="clearfix"></div></a>
			</li>
			<li>
				<a class="active" href="javascript:void(0);" data-toggle="collapse" data-target="#dashboard_dr">
					<div class="pull-left">
						<i class="zmdi zmdi-landscape mr-20"></i><span class="right-nav-text">用户信息</span>
					</div>
					<div class="pull-right"><i class="zmdi zmdi-caret-down"></i>
					</div>
					<div class="clearfix"></div>
				</a>
				<ul id="dashboard_dr" class="collapse collapse-level-1">
					<li>
						<!--下面绑定一个click时间, 跳转页面-->
						<a class="active-page" href="#" onclick="goPage('userList')">用户信息</a>
					</li>
				</ul>
			</li>
			<li>
				<a href="javascript:void(0);" data-toggle="collapse" data-target="#ecom_dr"><div class="pull-left"><i class="zmdi zmdi-shopping-basket mr-20"></i><span class="right-nav-text">招聘市场信息统计</span></div><div class="pull-right"><span class="label label-primary">hot</span></div><div class="clearfix"></div></a>
				<ul id="ecom_dr" class="collapse collapse-level-1">
					<!--下面分别绑定一个click时间, 跳转页面-->
					<li>
						<a href="javascript:void(0);"  onclick="goPage('recruitment')">统计各个城市招聘人数</a>
					</li>

					<li>
						<a href="javascript:void(0);"   onclick="goPage('industryTop')">热门行业信息统计</a>
					</li>
					<li>
						<a href="javascript:void(0);"   onclick="goPage('industryCompare')">热门行业对比情况</a>
					</li>
				</ul>
			</li>
			<li>
				<a href="javascript:void(0);" data-toggle="collapse" data-target="#app_dr"><div class="pull-left"><i class="zmdi zmdi-apps mr-20"></i><span class="right-nav-text">应聘者信息统计</span></div><div class="pull-right"><i class="zmdi zmdi-caret-down"></i></div><div class="clearfix"></div></a>
				<ul id="app_dr" class="collapse collapse-level-1">
					<li>
						<!--下面绑定一个click时间, 跳转页面-->
						<a href="javascript:void(0);" onclick="goPage('edu')">从业人员学历统计</a>
					</li>
				</ul>
			</li>
			<li>
				<a href="javascript:void(0);" data-toggle="collapse" data-target="#contact_dr"><div class="pull-left"><i class="zmdi zmdi-apps mr-20"></i><span class="right-nav-text">全国招聘信息</span></div><div class="pull-right"><i class="zmdi zmdi-caret-down"></i></div><div class="clearfix"></div></a>
				<ul id="contact_dr" class="collapse collapse-level-1">
					<li>
						<!--下面绑定一个click时间, 跳转页面-->
						<a href="javascript:void(0);"  onclick="goPage('map')">各省市招聘信息统计</a>
					</li>
				</ul>
			</li>
		</ul>
	</div>
	<!-- Main Content -->
	<div class="page-wrapper">
		<div class="container-fluid pt-25">
			<!--page start-->
				<!--iframe写成单标签是不展示的, scrolling 不显示滚动条-->
				<iframe width="100%" style="min-height: 800px" id="if" src="bigScreen.html" scrolling="no" frameborder="0"></iframe>
			<!--page end-->
		</div>

		<!-- Footer -->
		<footer class="footer container-fluid pl-30 pr-30">
			<div class="row">
				<div class="col-sm-12">
					<p>2020 &copy; Su. Pampered by Lagou</p>
				</div>
			</div>
		</footer>
		<!-- /Footer -->

	</div>
	<!-- /Main Content -->
</div>
<!-- /#wrapper -->


<!-- jQuery -->
<script src="vendors/bower_components/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="vendors/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<!-- Data table JavaScript -->
<script src="vendors/bower_components/datatables/media/js/jquery.dataTables.min.js"></script>
<!-- Slimscroll JavaScript -->
<script src="dist/js/jquery.slimscroll.js"></script>
<!-- Progressbar Animation JavaScript -->
<script src="vendors/bower_components/waypoints/lib/jquery.waypoints.min.js"></script>
<script src="vendors/bower_components/jquery.counterup/jquery.counterup.min.js"></script>
<!-- Fancy Dropdown JS -->
<script src="dist/js/dropdown-bootstrap-extended.js"></script>
<!-- Sparkline JavaScript -->
<script src="vendors/jquery.sparkline/dist/jquery.sparkline.min.js"></script>
<!-- Switchery JavaScript -->
<script src="vendors/bower_components/switchery/dist/switchery.min.js"></script>
<!-- EChartJS JavaScript -->
<script src="dist/js/echarts.min.js"></script>
<script src="vendors/echarts-liquidfill.min.js"></script>
<!-- Toast JavaScript -->
<script src="vendors/bower_components/jquery-toast-plugin/dist/jquery.toast.min.js"></script>
<!-- Init JavaScript -->
<script src="dist/js/init.js"></script>
<script src="dist/js/dashboard-data.js"></script>

<script>
	//跳转页面的函数,
	function goPage(t){
		var url = t+".html";
		// 设置iframe的src属性
		$("#if").attr('src',url);
	}

	//登出的方法
	function logout(){
		//1.直接发送ajax请求,请求后台注销
		$.post("/lg_visualization/user/logout.do",function(data){
			//2.如果注销成功,跳转到登录页面
			if(data.status == 0){
				location.href = "/lg_visualization/login.html";
			}else{
				alert("退出失败");
			}
		},"json")

	}
</script>
</body>
</html>

javascript中编写方法

<script>
	//跳转页面的函数,
	function goPage(t){
		var url = t+".html";
		// 设置iframe的src属性
		$("#if").attr('src',url);
	}

	//登出的方法
	function logout(){
		//1.直接发送ajax请求,请求后台注销
		$.post("/lg_visualization/user/logout.do",function(data){
			//2.如果注销成功,跳转到登录页面
			if(data.status == 0){
				location.href = "/lg_visualization/login.html";
			}else{
				alert("退出失败");
			}
		},"json")
	}
</script>

 

第3章 用户模块

1.接口说明

接口地址: http://localhost:8080/lg_visualization/user/资源.do
数据返回对象统一使用 ServerResponse
返回数据格式为json

2.用户表设计

package com.lagou.model;

import java.util.Date;
@Data                // 本注释添加set get方法和toString
@AllArgsConstructor  // 本注释添加全参构造方法
@NoArgsConstructor   // 本注释添加无参构造方法
public class User {
    private Integer id;
    private String username;
    private String password;
    private String email;
    private String phone;

    // 下面设置日期格式
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date  createTime;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
}


3.用户登录

3.1 登录验证接口

请求路径:login
请求方法:post
请求接口:  localhost:8080/lg_visualization/user/login.do?username=jack&password=jack
请求参数

响应参数

成功响应数据

{
    "status": 0,
    "msg": "登录成功",
    "data": {
        "id": 22,
        "username": "jack",
        "password": "",
        "email": "[email protected]",
        "phone": "13200001111",
        "createTime": 1598874019000,
        "updateTime": 1598874019000
    }
}

失败响应数据

{
    "status": 1,
    "msg": "用户名不存在"
}

3.2 用户登录页面

localhost:8080/lg_visualization/login.html

Controllrer

package com.lagou.controller;

@Controller
@RequestMapping("/user")
@Transactional
public class UserController {

    @Autowired
    private IUserService iUserService;

    /**
     * 1.用户登录
     */
    @RequestMapping(value = "login.do" , method = RequestMethod.POST)
    @ResponseBody
    public ServerResponse<User> login(String username, String password , HttpSession session){
        //1.调用serivce的登录方法 ,会返回一个ServerResponse<User>
        ServerResponse<User> response = iUserService.login(username,password);
        //2.判断是否登录成功,如果登录成功,把当前用户user放到session中
        if(response.getStatus() == ResponseCode.SUCCESS.getCode()){
            // 下面通常不会直接写字符串, 而是定义一个常量CURRENT_USER
            session.setAttribute(Const.CURRENT_USER,response.getData());
        }
        //3.返回ServerResponse
        return  response;
    }
}

 Service

package com.lagou.service;

public interface IUserService {
    /**
     * 用户登录
     * @param username
     * @param password
     * @return
     */
    public ServerResponse<User> login(String username, String password);
}
package com.lagou.service.impl;

@Service("iUserService")
public class UserServiceImpl implements IUserService {

    @Autowired  // 导入代理对象
    private UserMapper userMapper;

    @Override
    public ServerResponse<User> login(String username, String password) {

        //1.检查用户名是否存在  (0 用户不存在 1 用户存在)
       int resultCount =  userMapper.checkUserName(username);
       if(resultCount == 0){
           // 不存在直接结束
           return ServerResponse.createByErrorMsg("用户名不存在");
       }

        //2.使用MD5给密码进行加密
        String md5Password = MD5Util.MD5EncodeUtf8(password);

        //3.调用mapper的登录方法, 返回一个user对象  , user==null 密码错误
        User user = userMapper.selectLogin(username,md5Password);

        //4.如果user对象为null 则登录失败 : 密码错误
        if(user == null){
            return  ServerResponse.createByErrorMsg("密码错误");
        }

        //5.如果user不是null 登录成功,清空密码
        user.setPassword(StringUtils.EMPTY);
        //6.封装一个ServerResponse,返回成功信息

        return ServerResponse.createBySuccessMsgData("登录成功",user);
    }
}

 UserMapper

package com.lagou.mapper;

public interface UserMapper {
    /**
     * 根据用户名查找用户是否存在
     * @param username
     * @return
     */
    int checkUserName(String username);

    /**
     * 用户登录
     * @param username
     * @param md5Password
     * @return
     */
    // 下面的@Param可以直接关联传入参数
    User selectLogin(@Param("username") String username, @Param("password") String md5Password);
}
<?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.lagou.mapper.UserMapper">

    <!-- 1.封装一个返回类型为resultMap -->
    <resultMap id="resultMap" type="user">
        <constructor>
            <idArg column="id" jdbcType="INTEGER" javaType="java.lang.Integer" />
            <arg column="username" jdbcType="VARCHAR" javaType="string"/>
            <arg column="password" jdbcType="VARCHAR" javaType="string"/>
            <arg column="email" jdbcType="VARCHAR" javaType="string"/>
            <arg column="phone" jdbcType="VARCHAR" javaType="string"/>
            <arg column="create_time" jdbcType="TIMESTAMP" javaType="java.util.Date"/>
            <arg column="update_time" jdbcType="TIMESTAMP" javaType="java.util.Date"/>
        </constructor>
    </resultMap>

    <!-- 2.抽取一个sql片段   -->
    <sql id="field">
        id , username,password ,email ,phone ,create_time,update_time
    </sql>

    <!-- 3.根据name查询用户名是否存在   -->
    <select id="checkUserName" resultType="int" parameterType="String">
        select count(1) from user where username = #{username}
    </select>

    <!-- 4.使用用户名和密码登录   -->
    <!--下面引用sql片段-->
    <select id="selectLogin" resultMap="resultMap">
        select <include refid="field"/>
        from user
        where username = #{username}
        and password = #{password}
    </select>
</mapper>

 Const

package com.lagou.common;

public class Const {

    public static final  String CURRENT_USER="currentUser";
}

MD5Util

package com.lagou.util;

public class MD5Util {

    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++)
            resultSb.append(byteToHexString(b[i]));

        return resultSb.toString();
    }

    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n += 256;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }

    /**
     * 返回加密后密码
     */
    private static String MD5Encode(String origin, String charsetname) {
        String resultString = null;
        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            if (charsetname == null || "".equals(charsetname))
                resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
            else
                resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
        } catch (Exception exception) {
        }
        return resultString;
    }

    public static String MD5EncodeUtf8(String origin) {
       // origin = origin + PropertiesUtil.getProperty("password.salt", "");
        return MD5Encode(origin, "utf-8");
    }

    private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

}

异步登录请求

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
		<title>Elmer I Fast build Admin dashboard for any platform</title>
		<meta name="description" content="Elmer is a Dashboard & Admin Site Responsive Template by hencework." />
		<meta name="keywords" content="admin, admin dashboard, admin template, cms, crm, Elmer Admin, Elmeradmin, premium admin templates, responsive admin, sass, panel, software, ui, visualization, web app, application" />
		<meta name="author" content="hencework"/>
		
		<!-- Favicon -->
		<link rel="shortcut icon" href="favicon.ico">
		<link rel="icon" href="favicon.ico" type="image/x-icon">
		<!-- vector map CSS -->
		<link href="view/vendors/bower_components/jasny-bootstrap/dist/css/jasny-bootstrap.min.css" rel="stylesheet" type="text/css"/>
		<!-- Custom CSS -->
		<link href="view/dist/css/style.css" rel="stylesheet" type="text/css">
	</head>
	<body>
		<!--Preloader-->
		<div class="preloader-it">
			<div class="la-anim-1"></div>
		</div>
		<!--/Preloader-->
		<div class="wrapper  pa-0">
			<header class="sp-header">
				<div class="sp-logo-wrap pull-left">
					<a href="index.html">
						<img class="brand-img mr-10" src="view/dist/img/logo.png" alt="brand"/>
						<span class="brand-text">LaGou</span>
					</a>
				</div>
				<div class="clearfix"></div>
			</header>
			
			<!-- Main Content -->
			<div class="page-wrapper pa-0 ma-0 auth-page" id="app">
				<div class="container-fluid">
					<!-- Row -->
					<div class="table-struct full-width full-height">
						<div class="table-cell vertical-align-middle auth-form-wrap">
							<div class="auth-form  ml-auto mr-auto no-float">
								<div class="row">
									<div class="col-sm-12 col-xs-12">
										<div class="mb-30">
											<h3 class="text-center txt-dark mb-10">Sign in to LaGou</h3>
											<h6 class="text-center nonecase-font txt-grey">Enter your details below</h6>
										</div>	
										<div class="form-wrap">
											<form action="#">
												<div class="form-group">
													<label class="control-label mb-10" for="uname">User Account</label>
													<input type="text" class="form-control" required="" id="uname" name="username"  placeholder="Enter username">
												</div>
												<div class="form-group">
													<label class="pull-left control-label mb-10" for="pwd">Password</label>
													<input type="password" class="form-control" required="" id="pwd" name="password"  placeholder="Enter pwd">
												</div>
												<div class="form-group">
														<span id="errMsg">111</span>
												</div>

												<div class="form-group text-center">
													<button type="button"  id="btn" class="btn btn-primary  btn-rounded">sign in</button>
												</div>
											</form>
										</div>
									</div>	
								</div>
							</div>
						</div>
					</div>
					<!-- /Row -->	
				</div>
				
			</div>
			<!-- /Main Content -->
		
		</div>
		<!-- /#wrapper -->
		
		<!-- jQuery -->
		<script src="view/vendors/bower_components/jquery/dist/jquery.min.js"></script>
		<!-- Bootstrap Core JavaScript -->
		<script src="view/vendors/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
		<script src="view/vendors/bower_components/jasny-bootstrap/dist/js/jasny-bootstrap.min.js"></script>
		<!-- Slimscroll JavaScript -->
		<script src="view/dist/js/jquery.slimscroll.js"></script>
		<!-- Init JavaScript -->
		<script src="view/dist/js/init.js"></script>

		<script>
			//发送异步请求,完成登录
			$(function(){
				//1.给btn按钮派发一个单击事件
				$("#btn").click(function(){

					//2.获取用户名
					var username = $("#uname").val();
					//3.获取密码
					var pwd = $("#pwd").val();
					//4.发送post方式的ajax请求
					$.post("/lg_visualization/user/login.do","username="+username+"&password="+pwd,function(data){
						//5.判断用户是否登录成功
						if(data.status ==0){
							location.href = "view/index.html";
						}else{
							$("#errMsg").html(data.msg)
						}
					},"json")
				})

				//清除每次用户输入的用户名和密码
				$("#uname").val("");
				$("#pwd").val("");
			})

		</script>
	</body>
</html>

登录成功跳转到index.html首页面

4.用户分页

4.1 用户列表分页接口设计

请求路径:list
请求方法:post
请求接口: localhost:8080/lg_visualization/user/list.do?pageNum=1&pageSize=5
请求参数


响应参数


响应数据

{
    "status": 0,
    "data": {
        "total": 17,
        "list": [
            {
                "id": 39,
                "username": "jack7",
                "password": "F6EE935ED8D6FDB4EFA97C6B8F347DE2",
                "email": "[email protected]",
                "phone": "13200001112",
                "createTime": "2020-09-01 13:35:25",
                "updateTime": "2020-09-01 13:35:25"
            },
            {
                "id": 40,
                "username": "jack8",
                 ...
            },
            {
                "id": 41,
                 ...
            },
            {
                "id": 42,
                 ...
            },
            {
                "id": 43,
                 ...
            }
        ],
        "pageNum": 1,              # 当前页
        "pageSize": 5,             # 每页的数量
        "size": 5,                 # 当前页的数量
        "startRow": 1,             # 当前页面第一个元素在数据库中的行号
        "endRow": 5,               # 前页面最后一个元素在数据库中的行号
        "pages": 4,                # 总页数
        "prePage": 0,              # 前一页
        "nextPage": 2,             # 下一页
        "isFirstPage": true,       # 是否为第一页
        "isLastPage": false,       # 是否为最后一页
        "hasPreviousPage": false,  # 是否有前一页
        "hasNextPage": true,       # 是否有下一页
        "navigatePages": 8,        # 导航页码数
        "navigatepageNums": [      # 所有导航页号
            1,
            2,
            3,
            4
        ],
        "navigateFirstPage": 1,   # 导航第一页
        "navigateLastPage": 4,    # 导航最后一页
        "firstPage": 1,           # 第一页
        "lastPage": 4             # 最后一页
    }
}

分页后台逻辑

Controller

package com.lagou.controller;

@Controller
@RequestMapping("/user")
@Transactional
public class UserController {

    @Autowired
    private IUserService iUserService;

    /**
     * 2.分页查找
     */
    @RequestMapping(value = "list.do",method = RequestMethod.POST)
    @ResponseBody
    // 下面的参数, 默认值保证参数传递不为空
    public ServerResponse<PageInfo>  list(@RequestParam(value = "pageNum",defaultValue = "1") int pageNum,
                                          @RequestParam(value = "pageSize",defaultValue = "10") int pageSize){
       ServerResponse<PageInfo> users =  iUserService.getUsers(pageNum,pageSize);
       return users;
    }
}

Service

package com.lagou.service;

public interface IUserService {

    ServerResponse<PageInfo> getUsers(int pageNum, int pageSize);
}
package com.lagou.service.impl;

@Service("iUserService")
public class UserServiceImpl implements IUserService {

    @Autowired  // 导入代理对象
    private UserMapper userMapper;


    /**
     * 分页查询user
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public ServerResponse<PageInfo> getUsers(int pageNum, int pageSize) {

        //1.给PageHelper分页助手设置 pageNum  pageSize
        PageHelper.startPage(pageNum,pageSize);
        //2.查询所有用户信息
        List<User> list =  userMapper.userList();
        //3.创建pgeInfo对象,把查询到的用户list放到pageInfo中
        PageInfo pageInfo = new PageInfo(list);
        //4.返回serverResponse,添加pgeInfo
        return ServerResponse.createBySuccessData(pageInfo);
    }
}

Mapper

package com.lagou.mapper;

public interface UserMapper {

    List<User> userList();
}
<?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.lagou.mapper.UserMapper">

    <!-- 2.抽取一个sql片段   -->
    <sql id="field">
        id , username,password ,email ,phone ,create_time,update_time
    </sql>

    <!-- 5.查询所有用户信息并排序   -->
    <!--下面引用sql片段-->
    <select id="userList" resultType="user">
        select <include refid="field"/> from user order by id asc
    </select>
</mapper>

4.2 分页前台页面

1)点击员工信息分页展示查询到的用户数据

2) userList.html 引入bootstrap前台分页插件

<!--分页插件-->
<nav>
    <ul class="pagination">
        <li>
            <a href="#" aria-label="Previous" onclick="left()">
                <span aria-hidden="true">&laquo;</span>
            </a>
        </li>
        <!-- <li class="active"><a href="#">1</a></li>-->
         <!--<li><a href="#">2</a></li>-->
         <!--<li><a href="#">3</a></li>-->
        <li>
            <a href="#" aria-label="Next" onclick="right()">
                <span aria-hidden="true">&raquo;</span>
            </a>
        </li>
    </ul>
</nav>
<!-- 分页插件结束 -->

userList页面  操作按钮 参考代码

<a href='javascript:void(0)' class='text-inverse pr-10' title='Edit' data-toggle='tooltip'><i class=\"zmdi zmdi-edit txt-warning\"></i></a>" +
"<a href='javascript:void(0)' class='text-inverse' title='Delete' data-toggle='tooltip' onclick='deleteById("+list[i].id+")'><i class='zmdi zmdi-delete txt-danger'></i></a>

3)编写分页前端代码

<script>
    
    // 用来接返回data中的各种数据
    var prePage=  0; //当前页的前一页
    var nextPage = 0; //当前页的后一页
    var isFirstPage=false; //是否为首页
    var isLastPage=false; //是否为尾页

    //1.页面加载,调用一个分页查询一页数据的方法
    $(function(){
        findByPage(1);  //页面初始化查询第一页数据.
    })

    //2.查询后台的数据,动态展示的方法
    function findByPage(pageNum){

        // 由于每次查询的时候都会生成新的tr li 并添加在之前的后面,所以方法之前要清空这两项
        $("tbody tr").remove();
        $("li[name='myli']").remove();

        //2.1 发送ajax请求,查询后台的数据
        $.post("/lg_visualization/user/list.do","pageNum="+pageNum+"&pageSize=10", function(data){
            //初始化成员
            prePage = data.data.prePage;
            nextPage = data.data.nextPage;
            isFirstPage = data.data.isFirstPage;
            isLastPage = data.data.isLastPage;

            //2.2 获取到查询到的一页数据list,循环生成  tr td ,把数据嵌套到tr td, 放到tbody
            var list = data.data.list;
            //2.3循环查到的一页用户数据
            for(var i=0; i<list.length; i++){
                var $tr = $("<tr>\n" +
                    "   <th>"+list[i].id+"</th>\n" +
                    "    <th>"+list[i].username+"</th>\n" +
                    "    <th>"+list[i].email+"</th>\n" +
                    "    <th>"+list[i].phone+"</th>\n" +
                    "    <th>"+list[i].createTime+"</th>\n" +
                    "    <th>"+list[i].updateTime+"</th>\n" +
                    "    <th><a href='javascript:void(0)' class='text-inverse pr-10' title='Edit' data-toggle='tooltip'><i class=\"zmdi zmdi-edit txt-warning\"></i></a>" +
                    "<a href='javascript:void(0)' class='text-inverse' title='Delete' data-toggle='tooltip' onclick='deleteById("+list[i].id+")'><i class='zmdi zmdi-delete txt-danger'></i></a></th>\n" +
                    "    </tr>");
                $("tbody").append($tr);
            }

            //3.动态生成页码
            // 从data中获取总页码
           var totalPage =  data.data.pages;
            for(var i = 0 ; i < totalPage ; i++){
                var $li = $("<li name='myli'><a href='#' onclick='findByPage("+(i+1)+")'>"+(i+1)+"</a></li>");
                //所以要把li标签添加到页面, 在最后一个标签的前面添加新的标签
                $("li:last").before($li);
                //判断当前页是哪一页
                if(data.data.pageNum == (i+1)){
                    // 下面的class=active ,功能为默认被选中
                    $li.prop("class","active");
                }
            }

        } ,"json")
    }

    //点击向左的方法
    function left(){
        //1.判断当前页是否为首页,如果是首页,return停止方法
        if(isFirstPage){
            return;
        }
        //2.如果不是首页,调用findByPage(前一页)
        findByPage(prePage)
    }

    //点击向右的方法
    function right(){
        //1.判断当前页是否为尾页,如果是首页,return停止方法
        if(isLastPage){
            return;
        }

        //2.如果不是尾页,调用findByPage(后一页)
        findByPage(nextPage)
    }
</script>

5. 添加用户

5.1 添加用户接口设计

请求方法:post
请求接口: localhost:8080/lg_visualization/user/add.do?phone=13200001112&username=jack23&password=jack23&[email protected]
请求参数


响应数据

{
    "status": 0,
    "msg": "添加成功"
}

Controller

package com.lagou.controller;

@Controller
@RequestMapping("/user")
@Transactional
public class UserController {

    @Autowired
    private IUserService iUserService;

    /**
     * 3.添加用户
     */
    @RequestMapping(value = "add.do",method = RequestMethod.POST)
    @ResponseBody
    public ServerResponse<String> add(User user){
        return iUserService.add(user);
    }
}

Service

package com.lagou.service;

public interface IUserService {

    ServerResponse<String> add(User user);
}
package com.lagou.service.impl;

@Service("iUserService")
public class UserServiceImpl implements IUserService {

    @Autowired  // 导入代理对象
    private UserMapper userMapper;

    /**
     * 添加用户
     * @param user
     * @return
     */
    @Override
    public ServerResponse<String> add(User user) {

        //1.调用本类方法, 校验用户名是否存在
        ServerResponse<String> validResponse = this.checkValid(user.getUsername(), Const.USERNAME);
        if(validResponse.getStatus() != ResponseCode.SUCCESS.getCode()){
            return validResponse;
        }
        //2.校验邮箱是否已经存在
        validResponse = this.checkValid(user.getEmail(), Const.EMAIL);
        if(validResponse.getStatus() != ResponseCode.SUCCESS.getCode()){
            return validResponse;
        }

        //3.使用md5对密码进行加密
        user.setPassword(MD5Util.MD5EncodeUtf8(user.getPassword()));

        //4.添加数据入库   resultCount==1 插入成功, 如果为0,添加失败
        int resultCount = userMapper.insert(user);
        if(resultCount ==0 ){
            return ServerResponse.createByErrorMsg("添加失败");
        }

        return ServerResponse.createBySuccessMsg("添加成功");
    }

    /**
     * 校验用户名和邮箱是否存在
     * @param str   有可能是用户名,也有可能是邮箱
     * @param type   类型可以是用户名 ,也可以是邮箱
     * @return
     */
    public ServerResponse<String> checkValid(String str,String type){

        if(StringUtils.isNotBlank(type)){
            //类型是用户名, 校验用户名
            if(Const.USERNAME.equals(type)){
                //查询用户名是否存在
                int resultCount = userMapper.checkUserName(str);
                if(resultCount > 0){
                    return ServerResponse.createByErrorMsg("用户名已经存在");
                }
            }

            //校验邮箱
            if(Const.EMAIL.equals(type)){
               int resultCount  =  userMapper.checkEmail(str);
               if(resultCount > 0 ){
                   return ServerResponse.createByErrorMsg("Email已经存在");
               }
            }
        }
        return ServerResponse.createBySuccessMsg("校验成功");
    }
}

Const 

javapackage com.lagou.common;

public class Const {

    public static final String USERNAME = "username";
    public static final String EMAIL ="email";
}

Mapper

package com.lagou.mapper;

public interface UserMapper {
  
    int checkEmail(String str);

    int insert(User user);
}
    <!-- 6.校验邮箱是否存在   -->
    <select id="checkEmail" resultType="int" parameterType="string">
        select count(1) from user where email = #{email}
    </select>

    <!-- 7.添加用户   -->
    <insert id="insert" parameterType="user">
        insert into user (id,username,password,email ,phone ,create_time,update_time)
        values (#{id},#{username},#{password},#{email},#{phone},now(),now())
    </insert>

5.2 添加用户前台页面

点击添加用户按钮

在userList页面编写aside标签,引入dialog弹出框

<aside class="col-lg-2 col-md-4 pr-0">
    <div class="mt-20 mb-20 ml-15 mr-15">
        <a href="#myModal" data-toggle="modal" title="Compose"
           class="btn btn-success btn-block">
            添加用户
        </a>
        <!-- Modal -->
        <div aria-hidden="true" role="dialog" tabindex="-1" id="myModal"
             class="modal fade" style="display: none;">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal"
                                aria-hidden="true">×
                        </button>
                        <h4 class="modal-title" >添加用户</h4>
                    </div>
                    <div class="modal-body">
                        <form class="form-horizontal form-material" >
                            <div class="form-group">
                                <div class="col-md-12 mb-20">
                                    <input type="text" class="form-control"
                                           placeholder="请输入用户名" id="addName" name="username">
                                </div>
                                <div class="col-md-12 mb-20">
                                    <input type="password" class="form-control"
                                           placeholder="请输入密码" id="addPwd" name="password">
                                </div>
                                <div class="col-md-12 mb-20">
                                    <input type="password" class="form-control"
                                           placeholder="请确认密码" id="addPwd2" >
                                </div>
                                <div class="col-md-12 mb-20">
                                    <input type="text" class="form-control"
                                           placeholder="请填写邮箱" id="addEmail" name="email">
                                </div>
                                <div class="col-md-12 mb-20">
                                    <input type="text" class="form-control"
                                           placeholder="请填写手机号码" id="addPhone" name="phone">
                                </div>
                                <div class="form-group">
                                    <span id="errMsg"></span>
                                </div>

                            </div>
                        </form>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-info waves-effect"
                                data-dismiss="modal" onclick="save()">保存
                        </button>
                        <button type="button" class="btn btn-default waves-effect"
                                data-dismiss="modal" >取消
                        </button>
                    </div>
                </div>
                <!-- /.modal-content -->
            </div>
            <!-- /.modal-dialog -->
        </div>
        <!-- /.modal -->
    </div>
</aside>

编写异步请求发送添加用户的ajax请求 

    //添加用户的方法
    function save(){
        //获取数据
        var name = $("#addName").val();
        var pwd = $("#addPwd").val();
        var pwd2 = $("#addPwd2").val();
        var email = $("#addEmail").val();
        var phone = $("#addPhone").val();

        if(pwd != pwd2){
            $("#errMsg").html("两次密码不一致");
        }

        $.post("/lg_visualization/user/add.do",{"username":name,"password":pwd,"email":email,"phone":phone},function(data){
            if(data.status == 0){
                alert("添加成功");
                location.reload();
            }else{
                alert("添加失败 "+data.msg)
            }
        })
    }

6. 删除单个用户

6.1 删除用户接口设计

请求路径: localhost:8080/lg_visualization/user/deleteUser.do?id=24
请求方式: post
请求方法:deleteUser
请求参数


响应数据

响应数据

{
    "status": 0,
    "msg": "删除成功"
}

Controller

package com.lagou.controller;

@Controller
@RequestMapping("/user")
@Transactional
public class UserController {

    @Autowired
    private IUserService iUserService;

    /**
     * 4.删除用户
     */
    @RequestMapping(value = "deleteUser.do",method = RequestMethod.POST)
    @ResponseBody
    public ServerResponse<String> delete(int id){
        return iUserService.deleteByPrimary(id);
    }
}

Service

package com.lagou.service;

public interface IUserService {

    ServerResponse<String> add(User user);
}
package com.lagou.service.impl;

@Service("iUserService")
public class UserServiceImpl implements IUserService {

    @Autowired  // 导入代理对象
    private UserMapper userMapper;

    /**
     * 删除用户的方法
     * @param id
     * @return
     */
    @Override
    public ServerResponse<String> deleteByPrimary(int id) {
        //1.判断该用户是否存在,获取用户信息
        ServerResponse<User> information = this.getInformation(id);
        User user = information.getData();
        if(user ==null){
            //2.如果用户不存在,返回失败的ServerResources
            return ServerResponse.createByErrorMsg("删除的用户不存在");
        }
        //3.如果用户存在,调用mapper 中的方法进行删除 ,得到返回值  count ==1 删除成功  count==0 ,删除失败
        int count = userMapper.deleteByPrimaryKey(id);
        if(count > 0){
            return ServerResponse.createBySuccessMsg("删除成功");
        }

        return ServerResponse.createByErrorMsg("删除失败");
    }

    /**
     * 根据用户的id获取用户信息
     */
    public ServerResponse<User> getInformation(int userId){
       User user =  userMapper.selectByPrimaryKey(userId);
       //根据id查到了用户
       if(user != null){
           return ServerResponse.createBySuccessData(user);
       }
       return ServerResponse.createByErrorMsg("用户不存在");
    }
}

Mapper

package com.lagou.mapper;

public interface UserMapper {
  
    int deleteByPrimaryKey(int id);

    User selectByPrimaryKey(int userId);
}
    <!-- 8.根据主键查询用户   -->
    <select id="selectByPrimaryKey" parameterType="int" resultType="user">
        select <include refid="field"/> from user
        where id = #{id}
    </select>

    <!-- 9.根据主键删除用户   -->
    <delete id="deleteByPrimaryKey" parameterType="int">
        delete from user
        where id = #{id}
    </delete>

6.2 删除用户页面

在userList.html点击删除按钮,删除用户

前台发送ajax异步请求

    //删除用户
    function deleteById(id){
        //1.询问用户是否确认删除
       var flag =  window.confirm("您是否确认删除?");
       if(!flag){
           return;
       }
       //2.发送ajax请求删除后台数据,参数id
        $.post("/lg_visualization/user/deleteUser.do","id="+id,function(data){
            
            // 状态码为0, 说明成功
            if(data.status == 0){
                location.reload();
            }
        },"json")
    }

7.用户登出

7.1 接口设计

请求路径: localhost:8080/lg_visualization/user/logout.do
请求方法:logout
请求参数 : 无
响应数据

{
    "status": 0,
    "msg": "注销成功"
}
{
    "status": 1,
    "msg": "注销失败"
}

Controller

package com.lagou.controller;

@Controller
@RequestMapping("/user")
@Transactional
public class UserController {

    @Autowired
    private IUserService iUserService;

    /**
     * 5.用户登出
     */
    @RequestMapping(value = "logout.do",method = RequestMethod.POST)
    @ResponseBody
    public ServerResponse<String> logout(HttpSession session){
        try{
            session.removeAttribute(Const.CURRENT_USER);
            return ServerResponse.createBySuccessMsg("注销成功");
        }catch (Exception e){
            return ServerResponse.createByErrorMsg("注销失败");
        }
    }
}

7.2 前台页面

在index.html页面点击登出


发送异步的ajax请求

	//登出的方法
	function logout(){
		//1.直接发送ajax请求,请求后台注销
		$.post("/lg_visualization/user/logout.do",function(data){
			//2.如果注销成功,跳转到登录页面
			if(data.status == 0){
				location.href = "/lg_visualization/login.html";
			}else{
				alert("退出失败");
			}
		},"json")

	}

猜你喜欢

转载自blog.csdn.net/chengh1993/article/details/111357180
今日推荐