运用Maven 搭建SSM框架,并用shiro控制登录授权

一.准备工作

  • jdk1.8环境,maven3.x安装(指定本地仓库地址),Tomcat7以上安装
  • 本次使用Eclipse搭建项目
  • Eclipse 的编译环境设置一下,utf-8

二.新建Maven工程

  1. 选择建立Maven Project 选择File -> New -> Other,在New窗口中选择 Maven -> Maven Project;点击next,如下图
    这里写图片描述
    选择项目路径,如下图,然后next
    这里写图片描述
    选择项目类型 选择Artifact Id为maven-archetype-webapp那一项,如下图
    这里写图片描述
     输入Group ID和 Artifact ID,以及Package,具体Group ID和 Artifact ID代表什么,可以去阅读《Maven 实战》,Group ID相当于一个组织,而Artifact ID相当于这个组织下的一个具体项目,Packege的话会根据你的Group ID和Artifact ID生成一个默认的名称,就用默认的就可以,如下图
    这里写图片描述

三. maven项目的排错处理以及工程环境设置

  1. 工程出现错误,需要指定一下
    这里写图片描述
    右键项目点击properties,出现如下界面
    设置jdk 版本,tomcat 自己的 apply–>finish
    这里写图片描述

    在project facets中选择如下并且点击apply(设置版本3.0以上)
    这里写图片描述
    修改后:更改版本后,可能会报错:
    解决思路: 先修改版本为3.0, Dynamic web Module不勾选, java版本改为1,8 点击apply

然后勾选上Dynamic 点击apply –>finish

这里写图片描述

完成以上操作后, 右键项目–>Maven–>Maven Update,此时可以看到ssm-shiro1的目录结构改变:
这里写图片描述
此时报错,是因为maven 自动检查是否存在web.xml ,我们现在只需这样:
这里写图片描述
pom.xml 问题解决,此时项目还在报错,我们之前已经设置了Dynamic web Module 的版本为3.0 与当前jdk 版本匹配,这时引起的原因是,我们的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>
</web-app>

修改之后:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
  <display-name>Archetype Created Web Application</display-name>
  </web-app>

保存后,Maven Update 错误解决
因为我们使用的是jdk1.8版本所以需要在pom.xml中指定maven的编译版本,在build中加入以下:

<plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.5</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
             <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>

设置部署程序集(Web Deployment Assembly)
上面步骤设置完成后,点击OK,再右键项目,选择properties –》Deployment Assembly,如下图
这里写图片描述
此处列表是,部署项目时,文件发布的路径。
(1)我们删除test的两项,因为test是测试使用,并不需要部署。
(2)设置将Maven的jar包发布到lib下。
Add -> JavaBuild Path Entries -> Maven Dependencies -> Finish

四. 构建框架

  1.  在pom.xml中添加所需要的jar包,内容如下图

    <spring.version>4.0.0.RELEASE</spring.version>
    <slf4j.version>1.7.7</slf4j.version>
    <commons-io.version>2.4</commons-io.version>
    <commons-fileupload.version>1.3.1</commons-fileupload.version>
    
    <shiro.version>1.2.3</shiro.version>
    <commons-lang3.version>3.3.2</commons-lang3.version>
    <commons-beanutils.version>1.9.1</commons-beanutils.version>
    

    <!-- SECURITY  Shiro begin -->
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>${shiro.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>${shiro.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-cas</artifactId>
        <version>${shiro.version}</version>
        <exclusions>
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-web</artifactId>
        <version>${shiro.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-ehcache</artifactId>
        <version>${shiro.version}</version>
    </dependency>
    <!-- SECURITY end -->
    
    <!-- AOP begin -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.7.4</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.7.4</version>
    </dependency>
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.1</version>
    </dependency>
    <!-- AOP end -->
    
    <!-- 连接池 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.0.7</version>
    </dependency>
    
    <dependency>
        <groupId>net.sf.json-lib</groupId>
        <artifactId>json-lib</artifactId>
        <version>2.4</version>
        <classifier>jdk15</classifier>
    </dependency>
    
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
        <type>jar</type>
    </dependency>
    
    <!-- SPRING begin -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
        <exclusions>
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring.version}</version>
        <exclusions>
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring.version}</version>
    </dependency>
    
    <!-- spring orm -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-oxm</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!-- spring end -->
    
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>${slf4j.version}</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jul-to-slf4j</artifactId>
        <version>${slf4j.version}</version>
    </dependency>
    
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>${commons-io.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>${commons-lang3.version}</version>
    </dependency>
    
    
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>${commons-fileupload.version}</version>
    </dependency>
    
    <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils</artifactId>
        <version>${commons-beanutils.version}</version>
        <exclusions>
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
    
    <!-- Mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.3.0</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.2.3</version>
    </dependency>
    
    <!-- Servlet -->        
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.1</version>
        <scope>provided</scope>
    </dependency>
    
    <!-- Mysql -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.10</version>
    </dependency>
    

保存pom.xml,maven就会帮我们下载我们配置的所有jar包了,jar包依赖的jar包也会自动下载,是不是很方便!当然,这个下载可能需要较长的时间,不要急,当eclipse右下角的百分比进度没有了,就下载好了。jar包下载完成后,项目结构图如下
这里写图片描述

我们这里不涉及到模块分割,都是在同一个项目中使用, 需要准备以下几个配置文件
需要放在/src/main/resource下
applicationContext.xml
log4j.properties
mybatis_config.xml
mysqldb.properties
springmvc.xml
springShiro.xml

applicationContext.xml 用来启动spring容器和mybatis的整合(如果你想细分,dao/service/tx 你可以多做几个配置文件)
log4j.properties : 监听启动日志,有几个级别,可配置
mybatis_config.xml : 使用mybatis必须有的文件, 整合后,基本没有什么内容,但是这个头文件必须要有
mysqldb.properties 链接数据库的信息配置文件, 这里使用了alibaba的Druid链接吃,并可以通过dbPasswordCallback 自定义加密数据库密码, 提高数据库访问的安全性
springmvc.xml : web层访问,有设置视图解析器/上传/下载/ 拦截器/等功能.
springShirl.xml : spring与shiro的整合,并设定securityManager 安全管理配置,设置访问过滤器/ 登录页面/缓存等

通过以上介绍: 下面我们来配置这些文件:
1. web.xml 配置文件内容如下

    <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">

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

  <!-- post 乱码 -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 浏览器不支持put,delete等method,由该filter将/blog?_method=delete转换为标准的http delete方法 -->
    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>

    <!-- 配置文件所在位置 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:/applicationContext.xml,classpath*:/springShiro.xml</param-value>
    </context-param>
    <!-- Spring配置(监听器) -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- SpringMVC配置 -->
   <!-- Spring MVC servlet -->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <!--<init-param>表示启动时初始化的配置文件-->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <!--<servlet-mapping>中的</servlet-name>必须与<servlet>里面的<servlet-name>保持一致-->
        <servlet-name>SpringMVC</servlet-name>
        <!-- 一般定义为 / ,表示所有请求都通过DispatcherServlet来处理-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- Apache Shiro -->
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>



    <welcome-file-list>
        <welcome-file>/login</welcome-file>
    </welcome-file-list>
</web-app>
  1. mysqldb.properties

    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8
    jdbc.username=root      
    jdbc.password=fj+b7t/QmQxnMY2udJ5Xp9McGgh1uwLxLSZV5Gp78dtLMu6ceVLRshQE8b1c/ggHTTECurtlwXvsJh2apriT0bytqMXJDVP1kKY8wlrQepI4vEYiQyevWFqwn3LWCsMKcOE9OEVAwCHsrn9DreZ9rYg4Kv/Z7hrNgCgtcMzsFIc=
    #jdbc.password=root
    

其中我的是本地数据库,test测试库,用户名root,密码root, 需要修改为自己的
这个地方的jdbc.password : 是使用druid的passwordCallback 回调, 获取到这里的password 去通过对应的公钥解密的
password 为: ConfigTools.encrypt(privateKey,password); 运用私钥+密码加密后的密码; 后面我会把相应代码copy出来
相应的链接的时候,需要公钥+加密后的密码 去解密

  1. log4j.properties

    log4j.rootLogger=DEBUG, Console
    #Console
    log4j.appender.Console=org.apache.log4j.ConsoleAppender
    log4j.appender.Console.layout=org.apache.log4j.PatternLayout
    log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
    log4j.logger.java.sql.ResultSet=INFO
    log4j.logger.org.apache=INFO
    log4j.logger.java.sql.Connection=DEBUG
    log4j.logger.java.sql.Statement=DEBUG
    log4j.logger.java.sql.PreparedStatement=DEBUG
    

5.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>
   <!--  <typeAliases>
        <typeAlias type="com.lvlhome.vo.Info" alias="Info" />
    </typeAliases> -->

</configuration>
  1. applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:util="http://www.springframework.org/schema/util"
        xmlns:context="http://www.springframework.org/schema/context" xmlns:task="http://www.springframework.org/schema/task"
        xsi:schemaLocation="
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
                http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
                http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd">
    
        <!-- spring配置文件:排除controller注解 -->
        <context:component-scan base-package="com.zhihuizhengan.ssm" annotation-config="true">
            <context:exclude-filter type="annotation"  expression= "org.springframework.stereotype.Controller" />
        </context:component-scan>
        <!-- 加载properties文件  -->
     <!--   <bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
            <property name="locations">
                <list>
                    <value>classpath:mysqldb.properties</value>
                </list>
            </property>
        </bean>  -->
         <context:property-placeholder location="classpath:mysqldb.properties" />
        <!-- 数据库连接池 -->
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
            destroy-method="close">
    <!--        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
            <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=utf-8" />
            <property name="username" value="root" />
            <property name="password" value="root" /> -->
            <property name="driverClassName" value="${jdbc.driver}" />
            <property name="url" value="${jdbc.url}" />
            <property name="username" value="${jdbc.username}" />
            <!-- <property name="password" value="${jdbc.password}" /> -->
            <property name="maxActive" value="10" />
            <property name="minIdle" value="5" />       
            <property name="connectionProperties" value="password=${jdbc.password}"/>
            <property name="passwordCallback" ref="dbPasswordCallback"/>
        </bean>
        <bean id="dbPasswordCallback" class="com.zhihuizhengan.ssm.db.DBPasswordCallback" lazy-init="true" />
    
        <!-- 整合mybatis -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="configLocation" value="classpath:mybatis_config.xml"></property>
            <property name="mapperLocations" value="classpath:/com/zhihuizhengan/ssm/shiro/mapper/*.xml"/>
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="com.zhihuizhengan.ssm.shiro.mapper" />
            <!-- <property name="annotationClass" value="com.ai.trial.ct.annotation.MyBatisDao"/> -->
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
        </bean>
    
        <!-- 事务管理器 -->
        <bean id="transactionManager"
            class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource" />
        </bean>
        <tx:annotation-driven transaction-manager="transactionManager" />
    
        <!-- 支持Shiro对Controller的方法级AOP安全控制 begin-->
        <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
            <property name="proxyTargetClass" value="true" />
        </bean>
    
        <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
            <property name="exceptionMappings">
                <props>
                    <prop key="org.apache.shiro.authz.UnauthorizedException">error/403</prop>
                    <prop key="java.lang.Throwable">error/500</prop>
                </props>
                </property>
        </bean>
        <!-- 支持Shiro对Controller的方法级AOP安全控制 end -->
    </beans>
    
    1. springmvc.xml

          <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:mvc="http://www.springframework.org/schema/mvc" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:p="http://www.springframework.org/schema/p" 
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:aop="http://www.springframework.org/schema/aop"
          xsi:schemaLocation=" 
              http://www.springframework.org/schema/beans 
              http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
              http://www.springframework.org/schema/mvc 
              http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd 
              http://www.springframework.org/schema/context 
              http://www.springframework.org/schema/context/spring-context-4.0.xsd
              http://www.springframework.org/schema/aop 
              http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
      
          <!-- springMVC配置文件:关闭默认扫描,只扫描controller注解 -->   
          <context:component-scan base-package="com.zhihuizhengan.ssm.shiro.controller" />
          <mvc:annotation-driven/>
      
          <!-- 注入自定义Controller类 ,/hello 会把请求交给BeanNameUrlHandlerMapping进行处理-->
          <bean name="/hello" class="com.zhihuizhengan.ssm.shiro.controller.SysUserController2" />
      
      
          <mvc:default-servlet-handler />
          <mvc:resources mapping="/js/**" location="/js/" />
          <mvc:resources mapping="/css/**" location="/css/" />
          <mvc:resources mapping="/images/**" location="/images/" />
      
      <mvc:interceptors>
              <mvc:interceptor>
                  <mvc:mapping path="/*/**" />
                  <mvc:mapping path="/" />
                  <mvc:exclude-mapping path="/js/**" />
                  <mvc:exclude-mapping path="/css/**" />
                  <mvc:exclude-mapping path="/images/**" />
                  <bean class="com.zhihuizhengan.ssm.interceptor.LoginCheckInterceptor">
                  </bean>
              </mvc:interceptor>
          </mvc:interceptors>
      
          <!-- view配置 -->
          <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
              <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
              <property name="prefix" value="/WEB-INF/views/" />
              <property name="suffix" value=".jsp" />
          </bean>
      </beans>
      
  2. springShiro.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-4.0.xsd
                http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-4.0.xsd"
            default-lazy-init="true">
    
            <description>Shiro Configuration</description>
    
            <!-- AOP式方法级权限检查  -->
            <!-- <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
                <property name="proxyTargetClass" value="true" />
            </bean> -->
            <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
                <property name="securityManager" ref="securityManager"/>
            </bean>
    
            <bean id="customRealm" class="com.zhihuizhengan.ssm.shiro.security.SystemAuthorizingRealm" depends-on="sysUserService"></bean>
    
            <!-- 定义Shiro安全管理配置 -->
            <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
                <property name="realm" ref="customRealm" />
            </bean>
    
            <!-- 安全认证过滤器 -->
            <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
                <property name="securityManager" ref="securityManager" />
                <!--登入页面,进入登录页面get请求走login,若表单登录验证,则会走该方法的post请求-->
                <property name="loginUrl" value="/login"></property>
                <property name="successUrl" value="/index" />
    
                <property name="filters">
                    <map>
                        <entry key="cas" value-ref="casFilter"/>
                        <entry key="authc" value-ref="formAuthenticationFilter"/>
                    </map>
                </property>
                <property name="filterChainDefinitions">
                    <ref bean="shiroFilterChainDefinitions"/>
                </property>
            </bean>
    
    
            <!-- Shiro权限过滤过滤器定义 -->
            <bean name="shiroFilterChainDefinitions" class="java.lang.String">
                <constructor-arg>
                    <value>
                    <!-- 用户角色访问 -->
                        <!-- /index = user -->
                        <!-- 匿名访问 -->
                        /build/** = anon
                        /css/** = anon
                        /images/** = anon
                        /js/** = anon
                        /pdf/** = anon
                        /loginVerify = anon
                        <!--login post请求表单 -->
                        /login = authc
                        /loginOut = logout
                        /** = user  
                    </value>
                </constructor-arg>
            </bean>
    
            <!-- CAS认证过滤器 -->  
            <bean id="casFilter" class="org.apache.shiro.cas.CasFilter">  
                <property name="failureUrl" value="/login"/>
            </bean>
    
    
            <!-- 指定本系统SESSIONID, 默认为: JSESSIONID 问题: 与SERVLET容器名冲突, 如JETTY, TOMCAT 等默认JSESSIONID,
                当跳出SHIRO SERVLET时如ERROR-PAGE容器会为JSESSIONID重新分配值导致登录会话丢失! -->
            <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
                <constructor-arg name="name" value="jeesite.session.id"/>
            </bean>
            <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
            <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
        </beans>
    

五. 运用 mybatis 自动代码生成器, 生成相应的代码

网盘地址: [https://pan.baidu.com/s/1nRuMJj8O1OD09TLENjf95g]
密码:a88f
这里写图片描述

eg: 配置信息

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE generatorConfiguration
      PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
      "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

    <generatorConfiguration>
        <context id="testTables" targetRuntime="MyBatis3">
            <commentGenerator>
                <!-- 是否去除自动生成的注释 true:是 : false:否 -->
                <property name="suppressAllComments" value="true" />
            </commentGenerator>
            <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
            <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                connectionURL="jdbc:mysql://localhost:3306/test" userId="root"
                password="root">
            </jdbcConnection>
            <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 
                NUMERIC 类型解析为java.math.BigDecimal -->
            <javaTypeResolver>
                <property name="forceBigDecimals" value="false" />
            </javaTypeResolver>

            <!-- targetProject:生成PO类的位置 -->
            <javaModelGenerator targetPackage="com.zhihuizhengan.ssm.pojo"
                targetProject=".\src">
                <!-- enableSubPackages:是否让schema作为包的后缀 -->
                <property name="enableSubPackages" value="false" />
                <!-- 从数据库返回的值被清理前后的空格 -->
                <property name="trimStrings" value="true" />
            </javaModelGenerator>
            <!-- targetProject:mapper映射文件生成的位置 -->
            <sqlMapGenerator targetPackage="com.zhihuizhengan.ssm.mapper" 
                targetProject=".\src">
                <!-- enableSubPackages:是否让schema作为包的后缀 -->
                <property name="enableSubPackages" value="false" />
            </sqlMapGenerator>
            <!-- targetPackage:mapper接口生成的位置 -->
            <javaClientGenerator type="XMLMAPPER"
                targetPackage="com.zhihuizhengan.ssm.mapper" 
                targetProject=".\src">
                <!-- enableSubPackages:是否让schema作为包的后缀 -->
                <property name="enableSubPackages" value="false" />
            </javaClientGenerator>
            <!-- 指定数据库表 -->
            <table schema="" tableName="sys_user"></table>

        </context>
    </generatorConfiguration>

目录结构
这里写图片描述

[注意] : 数据库sys_user 表中村粗的password 用户密码 和生成token时密码的一致性

在自己测试的时候, 第一次进入了表单验证, 如果需要再次进入, 需要先退出一下, 调用一下 /loginOut 方法,清除session中之前的用户信息,否则不会重新创建token *!!!!!!!

以下是工作相应完成文件, 如果不想copy, 可以直接到网盘下载[https://pan.baidu.com/s/1cSGq43hbnnY298whYuORgw] 密码:jc92

七.相应文件

##### 1. db 加密文件

package com.zhihuizhengan.ssm.db;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;

import com.alibaba.druid.filter.config.ConfigTools;
import com.alibaba.druid.util.Base64;

public class KeyPairGenUtil {
    //指定加密算法为RSA
    private static final String ALGORITHM = "RSA";
    //密钥长度,用来初始化
    private static final int KEYSIZE = 1024;
    //指定公钥存放文件
    private static String PUBLIC_KEY_FILE = "d:/pub.k";
    //指定私钥存放文件
    private static String PRIVATE_KEY_FILE = "d:/pri.k";


    public static void main(String[] args) throws Exception {
        generateKeyPair();
        encrypt("root");
    }

    /**
     * 生成密钥对,druid中的ConfigTools类中也有生成方法可以直接调用
     * @throws Exception
     */
    private static void generateKeyPair() throws Exception {

        // 为RSA算法创建一个KeyPairGenerator对象
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);

        keyPairGenerator.initialize(KEYSIZE);

        //生成密匙对
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        // 得到公钥
        Key publicKey = keyPair.getPublic();

        // 得到私钥
        Key privateKey = keyPair.getPrivate();

        FileOutputStream fos1 = null;
        FileOutputStream fos2 = null;
        try {
            //用文件流将生成的密钥写入文件
            fos1 = new FileOutputStream(new File(PUBLIC_KEY_FILE));
            fos2 = new FileOutputStream(new File(PRIVATE_KEY_FILE));
            fos1.write(Base64.byteArrayToBase64(publicKey.getEncoded()).getBytes());
            fos2.write(Base64.byteArrayToBase64(privateKey.getEncoded()).getBytes());
        } catch (Exception e) {
            throw e;
        } finally {
            //清空缓存,关闭文件输出流
            fos1.close();
            fos2.close();
        }
    }

 private static String encrypt(String text) throws Exception {
         //读取私钥
        FileInputStream in2 = new FileInputStream(new File(PRIVATE_KEY_FILE));
        //如果改变key的长度这里需要适当调整
        byte[] buffer = new byte[2048];

        int count = in2.read(buffer);
        String privateKey = new String(buffer,0,count);

        //加密
        String code = ConfigTools.encrypt(privateKey,text);
        System.out.println(code);
        return code;
    }
}

回调数据库密码:

package com.zhihuizhengan.ssm.db;

import java.util.Properties;

import com.alibaba.druid.filter.config.ConfigTools;
import com.alibaba.druid.util.DruidPasswordCallback;

/**
*需要继承DruidPasswordCallback  并重写setProperties 方法
**/
public class DBPasswordCallback extends DruidPasswordCallback {
    // 加密后的密码


    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    //我使用的是RSA加密算法,所以讲公钥放在这的
    private final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwEIg0iiw0giw5kdzuSLQEjSWoTTP1YFOE0hGKKq7OtkWP/0YJkiAz0AYnaI07Cz3wGYskzYq5TmoX8Rg6ihFb+VvKNkIZ1QrwkK9LzVtvk+bOxgJaqHIN7ZBu12NA3OseKycw6r0znLKwrf884ZJQtIgFbe6+4Umo5qmVY9R1iQIDAQAB";
    @Override
    public void setProperties(Properties properties) {
        super.setProperties(properties);
        //获取配置文件中加密后的密码,和xml中的connectionProperties属性配置相关
        String password = (String) properties.get("password");
        try {
            //解密过程,ConfigTools为druid自带,提供一些好用的函数
            String dbpassword= ConfigTools.decrypt(publicKey,password);
            //设置密码
            setPassword(dbpassword.toCharArray());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  1. 拦截器 ,暂时都是放过

    3.pojo

    package com.zhihuizhengan.ssm.shiro.pojo;
    
    import java.io.Serializable;
    import java.util.Date;
    
    public class SysUser  implements Serializable {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
    
        private String id;
    
        private String companyId;
    
        private String officeId;
    
        private String loginName;
    
        private String password;
    
        private String no;
    
        private String name;
    
        private String email;
    
        private String phone;
    
        private String mobile;
    
        private String userType;
    
        private String photo;
    
        private String loginIp;
    
        private Date loginDate;
    
        private String loginFlag;
    
        private String createBy;
    
        private Date createDate;
    
        private String updateBy;
    
        private Date updateDate;
    
        private String remarks;
    
        private String delFlag;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id == null ? null : id.trim();
        }
    
        public String getCompanyId() {
            return companyId;
        }
    
        public void setCompanyId(String companyId) {
            this.companyId = companyId == null ? null : companyId.trim();
        }
    
        public String getOfficeId() {
            return officeId;
        }
    
        public void setOfficeId(String officeId) {
            this.officeId = officeId == null ? null : officeId.trim();
        }
    
        public String getLoginName() {
            return loginName;
        }
    
        public void setLoginName(String loginName) {
            this.loginName = loginName == null ? null : loginName.trim();
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password == null ? null : password.trim();
        }
    
        public String getNo() {
            return no;
        }
    
        public void setNo(String no) {
            this.no = no == null ? null : no.trim();
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name == null ? null : name.trim();
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email == null ? null : email.trim();
        }
    
        public String getPhone() {
            return phone;
        }
    
        public void setPhone(String phone) {
            this.phone = phone == null ? null : phone.trim();
        }
    
        public String getMobile() {
            return mobile;
        }
    
        public void setMobile(String mobile) {
            this.mobile = mobile == null ? null : mobile.trim();
        }
    
        public String getUserType() {
            return userType;
        }
    
        public void setUserType(String userType) {
            this.userType = userType == null ? null : userType.trim();
        }
    
        public String getPhoto() {
            return photo;
        }
    
        public void setPhoto(String photo) {
            this.photo = photo == null ? null : photo.trim();
        }
    
        public String getLoginIp() {
            return loginIp;
        }
    
        public void setLoginIp(String loginIp) {
            this.loginIp = loginIp == null ? null : loginIp.trim();
        }
    
        public Date getLoginDate() {
            return loginDate;
        }
    
        public void setLoginDate(Date loginDate) {
            this.loginDate = loginDate;
        }
    
        public String getLoginFlag() {
            return loginFlag;
        }
    
        public void setLoginFlag(String loginFlag) {
            this.loginFlag = loginFlag == null ? null : loginFlag.trim();
        }
    
        public String getCreateBy() {
            return createBy;
        }
    
        public void setCreateBy(String createBy) {
            this.createBy = createBy == null ? null : createBy.trim();
        }
    
        public Date getCreateDate() {
            return createDate;
        }
    
        public void setCreateDate(Date createDate) {
            this.createDate = createDate;
        }
    
        public String getUpdateBy() {
            return updateBy;
        }
    
        public void setUpdateBy(String updateBy) {
            this.updateBy = updateBy == null ? null : updateBy.trim();
        }
    
        public Date getUpdateDate() {
            return updateDate;
        }
    
        public void setUpdateDate(Date updateDate) {
            this.updateDate = updateDate;
        }
    
        public String getRemarks() {
            return remarks;
        }
    
        public void setRemarks(String remarks) {
            this.remarks = remarks == null ? null : remarks.trim();
        }
    
        public String getDelFlag() {
            return delFlag;
        }
    
        public void setDelFlag(String delFlag) {
            this.delFlag = delFlag == null ? null : delFlag.trim();
        }
    }
    

用户查询对象, 这里没有做封装,可自己封装:

    package com.zhihuizhengan.ssm.shiro.pojo;

    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;

    public class SysUserExample {
        protected String orderByClause;

        protected boolean distinct;

        protected List<Criteria> oredCriteria;

        public SysUserExample() {
            oredCriteria = new ArrayList<Criteria>();
        }

        public void setOrderByClause(String orderByClause) {
            this.orderByClause = orderByClause;
        }

        public String getOrderByClause() {
            return orderByClause;
        }

        public void setDistinct(boolean distinct) {
            this.distinct = distinct;
        }

        public boolean isDistinct() {
            return distinct;
        }

        public List<Criteria> getOredCriteria() {
            return oredCriteria;
        }

        public void or(Criteria criteria) {
            oredCriteria.add(criteria);
        }

        public Criteria or() {
            Criteria criteria = createCriteriaInternal();
            oredCriteria.add(criteria);
            return criteria;
        }

        public Criteria createCriteria() {
            Criteria criteria = createCriteriaInternal();
            if (oredCriteria.size() == 0) {
                oredCriteria.add(criteria);
            }
            return criteria;
        }

        protected Criteria createCriteriaInternal() {
            Criteria criteria = new Criteria();
            return criteria;
        }

        public void clear() {
            oredCriteria.clear();
            orderByClause = null;
            distinct = false;
        }

        protected abstract static class GeneratedCriteria {
            protected List<Criterion> criteria;

            protected GeneratedCriteria() {
                super();
                criteria = new ArrayList<Criterion>();
            }

            public boolean isValid() {
                return criteria.size() > 0;
            }

            public List<Criterion> getAllCriteria() {
                return criteria;
            }

            public List<Criterion> getCriteria() {
                return criteria;
            }

            protected void addCriterion(String condition) {
                if (condition == null) {
                    throw new RuntimeException("Value for condition cannot be null");
                }
                criteria.add(new Criterion(condition));
            }

            protected void addCriterion(String condition, Object value, String property) {
                if (value == null) {
                    throw new RuntimeException("Value for " + property + " cannot be null");
                }
                criteria.add(new Criterion(condition, value));
            }

            protected void addCriterion(String condition, Object value1, Object value2, String property) {
                if (value1 == null || value2 == null) {
                    throw new RuntimeException("Between values for " + property + " cannot be null");
                }
                criteria.add(new Criterion(condition, value1, value2));
            }

            public Criteria andIdIsNull() {
                addCriterion("id is null");
                return (Criteria) this;
            }

            public Criteria andIdIsNotNull() {
                addCriterion("id is not null");
                return (Criteria) this;
            }

            public Criteria andIdEqualTo(String value) {
                addCriterion("id =", value, "id");
                return (Criteria) this;
            }

            public Criteria andIdNotEqualTo(String value) {
                addCriterion("id <>", value, "id");
                return (Criteria) this;
            }

            public Criteria andIdGreaterThan(String value) {
                addCriterion("id >", value, "id");
                return (Criteria) this;
            }

            public Criteria andIdGreaterThanOrEqualTo(String value) {
                addCriterion("id >=", value, "id");
                return (Criteria) this;
            }

            public Criteria andIdLessThan(String value) {
                addCriterion("id <", value, "id");
                return (Criteria) this;
            }

            public Criteria andIdLessThanOrEqualTo(String value) {
                addCriterion("id <=", value, "id");
                return (Criteria) this;
            }

            public Criteria andIdLike(String value) {
                addCriterion("id like", value, "id");
                return (Criteria) this;
            }

            public Criteria andIdNotLike(String value) {
                addCriterion("id not like", value, "id");
                return (Criteria) this;
            }

            public Criteria andIdIn(List<String> values) {
                addCriterion("id in", values, "id");
                return (Criteria) this;
            }

            public Criteria andIdNotIn(List<String> values) {
                addCriterion("id not in", values, "id");
                return (Criteria) this;
            }

            public Criteria andIdBetween(String value1, String value2) {
                addCriterion("id between", value1, value2, "id");
                return (Criteria) this;
            }

            public Criteria andIdNotBetween(String value1, String value2) {
                addCriterion("id not between", value1, value2, "id");
                return (Criteria) this;
            }

            public Criteria andCompanyIdIsNull() {
                addCriterion("company_id is null");
                return (Criteria) this;
            }

            public Criteria andCompanyIdIsNotNull() {
                addCriterion("company_id is not null");
                return (Criteria) this;
            }

            public Criteria andCompanyIdEqualTo(String value) {
                addCriterion("company_id =", value, "companyId");
                return (Criteria) this;
            }

            public Criteria andCompanyIdNotEqualTo(String value) {
                addCriterion("company_id <>", value, "companyId");
                return (Criteria) this;
            }

            public Criteria andCompanyIdGreaterThan(String value) {
                addCriterion("company_id >", value, "companyId");
                return (Criteria) this;
            }

            public Criteria andCompanyIdGreaterThanOrEqualTo(String value) {
                addCriterion("company_id >=", value, "companyId");
                return (Criteria) this;
            }

            public Criteria andCompanyIdLessThan(String value) {
                addCriterion("company_id <", value, "companyId");
                return (Criteria) this;
            }

            public Criteria andCompanyIdLessThanOrEqualTo(String value) {
                addCriterion("company_id <=", value, "companyId");
                return (Criteria) this;
            }

            public Criteria andCompanyIdLike(String value) {
                addCriterion("company_id like", value, "companyId");
                return (Criteria) this;
            }

            public Criteria andCompanyIdNotLike(String value) {
                addCriterion("company_id not like", value, "companyId");
                return (Criteria) this;
            }

            public Criteria andCompanyIdIn(List<String> values) {
                addCriterion("company_id in", values, "companyId");
                return (Criteria) this;
            }

            public Criteria andCompanyIdNotIn(List<String> values) {
                addCriterion("company_id not in", values, "companyId");
                return (Criteria) this;
            }

            public Criteria andCompanyIdBetween(String value1, String value2) {
                addCriterion("company_id between", value1, value2, "companyId");
                return (Criteria) this;
            }

            public Criteria andCompanyIdNotBetween(String value1, String value2) {
                addCriterion("company_id not between", value1, value2, "companyId");
                return (Criteria) this;
            }

            public Criteria andOfficeIdIsNull() {
                addCriterion("office_id is null");
                return (Criteria) this;
            }

            public Criteria andOfficeIdIsNotNull() {
                addCriterion("office_id is not null");
                return (Criteria) this;
            }

            public Criteria andOfficeIdEqualTo(String value) {
                addCriterion("office_id =", value, "officeId");
                return (Criteria) this;
            }

            public Criteria andOfficeIdNotEqualTo(String value) {
                addCriterion("office_id <>", value, "officeId");
                return (Criteria) this;
            }

            public Criteria andOfficeIdGreaterThan(String value) {
                addCriterion("office_id >", value, "officeId");
                return (Criteria) this;
            }

            public Criteria andOfficeIdGreaterThanOrEqualTo(String value) {
                addCriterion("office_id >=", value, "officeId");
                return (Criteria) this;
            }

            public Criteria andOfficeIdLessThan(String value) {
                addCriterion("office_id <", value, "officeId");
                return (Criteria) this;
            }

            public Criteria andOfficeIdLessThanOrEqualTo(String value) {
                addCriterion("office_id <=", value, "officeId");
                return (Criteria) this;
            }

            public Criteria andOfficeIdLike(String value) {
                addCriterion("office_id like", value, "officeId");
                return (Criteria) this;
            }

            public Criteria andOfficeIdNotLike(String value) {
                addCriterion("office_id not like", value, "officeId");
                return (Criteria) this;
            }

            public Criteria andOfficeIdIn(List<String> values) {
                addCriterion("office_id in", values, "officeId");
                return (Criteria) this;
            }

            public Criteria andOfficeIdNotIn(List<String> values) {
                addCriterion("office_id not in", values, "officeId");
                return (Criteria) this;
            }

            public Criteria andOfficeIdBetween(String value1, String value2) {
                addCriterion("office_id between", value1, value2, "officeId");
                return (Criteria) this;
            }

            public Criteria andOfficeIdNotBetween(String value1, String value2) {
                addCriterion("office_id not between", value1, value2, "officeId");
                return (Criteria) this;
            }

            public Criteria andLoginNameIsNull() {
                addCriterion("login_name is null");
                return (Criteria) this;
            }

            public Criteria andLoginNameIsNotNull() {
                addCriterion("login_name is not null");
                return (Criteria) this;
            }

            public Criteria andLoginNameEqualTo(String value) {
                addCriterion("login_name =", value, "loginName");
                return (Criteria) this;
            }

            public Criteria andLoginNameNotEqualTo(String value) {
                addCriterion("login_name <>", value, "loginName");
                return (Criteria) this;
            }

            public Criteria andLoginNameGreaterThan(String value) {
                addCriterion("login_name >", value, "loginName");
                return (Criteria) this;
            }

            public Criteria andLoginNameGreaterThanOrEqualTo(String value) {
                addCriterion("login_name >=", value, "loginName");
                return (Criteria) this;
            }

            public Criteria andLoginNameLessThan(String value) {
                addCriterion("login_name <", value, "loginName");
                return (Criteria) this;
            }

            public Criteria andLoginNameLessThanOrEqualTo(String value) {
                addCriterion("login_name <=", value, "loginName");
                return (Criteria) this;
            }

            public Criteria andLoginNameLike(String value) {
                addCriterion("login_name like", value, "loginName");
                return (Criteria) this;
            }

            public Criteria andLoginNameNotLike(String value) {
                addCriterion("login_name not like", value, "loginName");
                return (Criteria) this;
            }

            public Criteria andLoginNameIn(List<String> values) {
                addCriterion("login_name in", values, "loginName");
                return (Criteria) this;
            }

            public Criteria andLoginNameNotIn(List<String> values) {
                addCriterion("login_name not in", values, "loginName");
                return (Criteria) this;
            }

            public Criteria andLoginNameBetween(String value1, String value2) {
                addCriterion("login_name between", value1, value2, "loginName");
                return (Criteria) this;
            }

            public Criteria andLoginNameNotBetween(String value1, String value2) {
                addCriterion("login_name not between", value1, value2, "loginName");
                return (Criteria) this;
            }

            public Criteria andPasswordIsNull() {
                addCriterion("password is null");
                return (Criteria) this;
            }

            public Criteria andPasswordIsNotNull() {
                addCriterion("password is not null");
                return (Criteria) this;
            }

            public Criteria andPasswordEqualTo(String value) {
                addCriterion("password =", value, "password");
                return (Criteria) this;
            }

            public Criteria andPasswordNotEqualTo(String value) {
                addCriterion("password <>", value, "password");
                return (Criteria) this;
            }

            public Criteria andPasswordGreaterThan(String value) {
                addCriterion("password >", value, "password");
                return (Criteria) this;
            }

            public Criteria andPasswordGreaterThanOrEqualTo(String value) {
                addCriterion("password >=", value, "password");
                return (Criteria) this;
            }

            public Criteria andPasswordLessThan(String value) {
                addCriterion("password <", value, "password");
                return (Criteria) this;
            }

            public Criteria andPasswordLessThanOrEqualTo(String value) {
                addCriterion("password <=", value, "password");
                return (Criteria) this;
            }

            public Criteria andPasswordLike(String value) {
                addCriterion("password like", value, "password");
                return (Criteria) this;
            }

            public Criteria andPasswordNotLike(String value) {
                addCriterion("password not like", value, "password");
                return (Criteria) this;
            }

            public Criteria andPasswordIn(List<String> values) {
                addCriterion("password in", values, "password");
                return (Criteria) this;
            }

            public Criteria andPasswordNotIn(List<String> values) {
                addCriterion("password not in", values, "password");
                return (Criteria) this;
            }

            public Criteria andPasswordBetween(String value1, String value2) {
                addCriterion("password between", value1, value2, "password");
                return (Criteria) this;
            }

            public Criteria andPasswordNotBetween(String value1, String value2) {
                addCriterion("password not between", value1, value2, "password");
                return (Criteria) this;
            }

            public Criteria andNoIsNull() {
                addCriterion("no is null");
                return (Criteria) this;
            }

            public Criteria andNoIsNotNull() {
                addCriterion("no is not null");
                return (Criteria) this;
            }

            public Criteria andNoEqualTo(String value) {
                addCriterion("no =", value, "no");
                return (Criteria) this;
            }

            public Criteria andNoNotEqualTo(String value) {
                addCriterion("no <>", value, "no");
                return (Criteria) this;
            }

            public Criteria andNoGreaterThan(String value) {
                addCriterion("no >", value, "no");
                return (Criteria) this;
            }

            public Criteria andNoGreaterThanOrEqualTo(String value) {
                addCriterion("no >=", value, "no");
                return (Criteria) this;
            }

            public Criteria andNoLessThan(String value) {
                addCriterion("no <", value, "no");
                return (Criteria) this;
            }

            public Criteria andNoLessThanOrEqualTo(String value) {
                addCriterion("no <=", value, "no");
                return (Criteria) this;
            }

            public Criteria andNoLike(String value) {
                addCriterion("no like", value, "no");
                return (Criteria) this;
            }

            public Criteria andNoNotLike(String value) {
                addCriterion("no not like", value, "no");
                return (Criteria) this;
            }

            public Criteria andNoIn(List<String> values) {
                addCriterion("no in", values, "no");
                return (Criteria) this;
            }

            public Criteria andNoNotIn(List<String> values) {
                addCriterion("no not in", values, "no");
                return (Criteria) this;
            }

            public Criteria andNoBetween(String value1, String value2) {
                addCriterion("no between", value1, value2, "no");
                return (Criteria) this;
            }

            public Criteria andNoNotBetween(String value1, String value2) {
                addCriterion("no not between", value1, value2, "no");
                return (Criteria) this;
            }

            public Criteria andNameIsNull() {
                addCriterion("name is null");
                return (Criteria) this;
            }

            public Criteria andNameIsNotNull() {
                addCriterion("name is not null");
                return (Criteria) this;
            }

            public Criteria andNameEqualTo(String value) {
                addCriterion("name =", value, "name");
                return (Criteria) this;
            }

            public Criteria andNameNotEqualTo(String value) {
                addCriterion("name <>", value, "name");
                return (Criteria) this;
            }

            public Criteria andNameGreaterThan(String value) {
                addCriterion("name >", value, "name");
                return (Criteria) this;
            }

            public Criteria andNameGreaterThanOrEqualTo(String value) {
                addCriterion("name >=", value, "name");
                return (Criteria) this;
            }

            public Criteria andNameLessThan(String value) {
                addCriterion("name <", value, "name");
                return (Criteria) this;
            }

            public Criteria andNameLessThanOrEqualTo(String value) {
                addCriterion("name <=", value, "name");
                return (Criteria) this;
            }

            public Criteria andNameLike(String value) {
                addCriterion("name like", value, "name");
                return (Criteria) this;
            }

            public Criteria andNameNotLike(String value) {
                addCriterion("name not like", value, "name");
                return (Criteria) this;
            }

            public Criteria andNameIn(List<String> values) {
                addCriterion("name in", values, "name");
                return (Criteria) this;
            }

            public Criteria andNameNotIn(List<String> values) {
                addCriterion("name not in", values, "name");
                return (Criteria) this;
            }

            public Criteria andNameBetween(String value1, String value2) {
                addCriterion("name between", value1, value2, "name");
                return (Criteria) this;
            }

            public Criteria andNameNotBetween(String value1, String value2) {
                addCriterion("name not between", value1, value2, "name");
                return (Criteria) this;
            }

            public Criteria andEmailIsNull() {
                addCriterion("email is null");
                return (Criteria) this;
            }

            public Criteria andEmailIsNotNull() {
                addCriterion("email is not null");
                return (Criteria) this;
            }

            public Criteria andEmailEqualTo(String value) {
                addCriterion("email =", value, "email");
                return (Criteria) this;
            }

            public Criteria andEmailNotEqualTo(String value) {
                addCriterion("email <>", value, "email");
                return (Criteria) this;
            }

            public Criteria andEmailGreaterThan(String value) {
                addCriterion("email >", value, "email");
                return (Criteria) this;
            }

            public Criteria andEmailGreaterThanOrEqualTo(String value) {
                addCriterion("email >=", value, "email");
                return (Criteria) this;
            }

            public Criteria andEmailLessThan(String value) {
                addCriterion("email <", value, "email");
                return (Criteria) this;
            }

            public Criteria andEmailLessThanOrEqualTo(String value) {
                addCriterion("email <=", value, "email");
                return (Criteria) this;
            }

            public Criteria andEmailLike(String value) {
                addCriterion("email like", value, "email");
                return (Criteria) this;
            }

            public Criteria andEmailNotLike(String value) {
                addCriterion("email not like", value, "email");
                return (Criteria) this;
            }

            public Criteria andEmailIn(List<String> values) {
                addCriterion("email in", values, "email");
                return (Criteria) this;
            }

            public Criteria andEmailNotIn(List<String> values) {
                addCriterion("email not in", values, "email");
                return (Criteria) this;
            }

            public Criteria andEmailBetween(String value1, String value2) {
                addCriterion("email between", value1, value2, "email");
                return (Criteria) this;
            }

            public Criteria andEmailNotBetween(String value1, String value2) {
                addCriterion("email not between", value1, value2, "email");
                return (Criteria) this;
            }

            public Criteria andPhoneIsNull() {
                addCriterion("phone is null");
                return (Criteria) this;
            }

            public Criteria andPhoneIsNotNull() {
                addCriterion("phone is not null");
                return (Criteria) this;
            }

            public Criteria andPhoneEqualTo(String value) {
                addCriterion("phone =", value, "phone");
                return (Criteria) this;
            }

            public Criteria andPhoneNotEqualTo(String value) {
                addCriterion("phone <>", value, "phone");
                return (Criteria) this;
            }

            public Criteria andPhoneGreaterThan(String value) {
                addCriterion("phone >", value, "phone");
                return (Criteria) this;
            }

            public Criteria andPhoneGreaterThanOrEqualTo(String value) {
                addCriterion("phone >=", value, "phone");
                return (Criteria) this;
            }

            public Criteria andPhoneLessThan(String value) {
                addCriterion("phone <", value, "phone");
                return (Criteria) this;
            }

            public Criteria andPhoneLessThanOrEqualTo(String value) {
                addCriterion("phone <=", value, "phone");
                return (Criteria) this;
            }

            public Criteria andPhoneLike(String value) {
                addCriterion("phone like", value, "phone");
                return (Criteria) this;
            }

            public Criteria andPhoneNotLike(String value) {
                addCriterion("phone not like", value, "phone");
                return (Criteria) this;
            }

            public Criteria andPhoneIn(List<String> values) {
                addCriterion("phone in", values, "phone");
                return (Criteria) this;
            }

            public Criteria andPhoneNotIn(List<String> values) {
                addCriterion("phone not in", values, "phone");
                return (Criteria) this;
            }

            public Criteria andPhoneBetween(String value1, String value2) {
                addCriterion("phone between", value1, value2, "phone");
                return (Criteria) this;
            }

            public Criteria andPhoneNotBetween(String value1, String value2) {
                addCriterion("phone not between", value1, value2, "phone");
                return (Criteria) this;
            }

            public Criteria andMobileIsNull() {
                addCriterion("mobile is null");
                return (Criteria) this;
            }

            public Criteria andMobileIsNotNull() {
                addCriterion("mobile is not null");
                return (Criteria) this;
            }

            public Criteria andMobileEqualTo(String value) {
                addCriterion("mobile =", value, "mobile");
                return (Criteria) this;
            }

            public Criteria andMobileNotEqualTo(String value) {
                addCriterion("mobile <>", value, "mobile");
                return (Criteria) this;
            }

            public Criteria andMobileGreaterThan(String value) {
                addCriterion("mobile >", value, "mobile");
                return (Criteria) this;
            }

            public Criteria andMobileGreaterThanOrEqualTo(String value) {
                addCriterion("mobile >=", value, "mobile");
                return (Criteria) this;
            }

            public Criteria andMobileLessThan(String value) {
                addCriterion("mobile <", value, "mobile");
                return (Criteria) this;
            }

            public Criteria andMobileLessThanOrEqualTo(String value) {
                addCriterion("mobile <=", value, "mobile");
                return (Criteria) this;
            }

            public Criteria andMobileLike(String value) {
                addCriterion("mobile like", value, "mobile");
                return (Criteria) this;
            }

            public Criteria andMobileNotLike(String value) {
                addCriterion("mobile not like", value, "mobile");
                return (Criteria) this;
            }

            public Criteria andMobileIn(List<String> values) {
                addCriterion("mobile in", values, "mobile");
                return (Criteria) this;
            }

            public Criteria andMobileNotIn(List<String> values) {
                addCriterion("mobile not in", values, "mobile");
                return (Criteria) this;
            }

            public Criteria andMobileBetween(String value1, String value2) {
                addCriterion("mobile between", value1, value2, "mobile");
                return (Criteria) this;
            }

            public Criteria andMobileNotBetween(String value1, String value2) {
                addCriterion("mobile not between", value1, value2, "mobile");
                return (Criteria) this;
            }

            public Criteria andUserTypeIsNull() {
                addCriterion("user_type is null");
                return (Criteria) this;
            }

            public Criteria andUserTypeIsNotNull() {
                addCriterion("user_type is not null");
                return (Criteria) this;
            }

            public Criteria andUserTypeEqualTo(String value) {
                addCriterion("user_type =", value, "userType");
                return (Criteria) this;
            }

            public Criteria andUserTypeNotEqualTo(String value) {
                addCriterion("user_type <>", value, "userType");
                return (Criteria) this;
            }

            public Criteria andUserTypeGreaterThan(String value) {
                addCriterion("user_type >", value, "userType");
                return (Criteria) this;
            }

            public Criteria andUserTypeGreaterThanOrEqualTo(String value) {
                addCriterion("user_type >=", value, "userType");
                return (Criteria) this;
            }

            public Criteria andUserTypeLessThan(String value) {
                addCriterion("user_type <", value, "userType");
                return (Criteria) this;
            }

            public Criteria andUserTypeLessThanOrEqualTo(String value) {
                addCriterion("user_type <=", value, "userType");
                return (Criteria) this;
            }

            public Criteria andUserTypeLike(String value) {
                addCriterion("user_type like", value, "userType");
                return (Criteria) this;
            }

            public Criteria andUserTypeNotLike(String value) {
                addCriterion("user_type not like", value, "userType");
                return (Criteria) this;
            }

            public Criteria andUserTypeIn(List<String> values) {
                addCriterion("user_type in", values, "userType");
                return (Criteria) this;
            }

            public Criteria andUserTypeNotIn(List<String> values) {
                addCriterion("user_type not in", values, "userType");
                return (Criteria) this;
            }

            public Criteria andUserTypeBetween(String value1, String value2) {
                addCriterion("user_type between", value1, value2, "userType");
                return (Criteria) this;
            }

            public Criteria andUserTypeNotBetween(String value1, String value2) {
                addCriterion("user_type not between", value1, value2, "userType");
                return (Criteria) this;
            }

            public Criteria andPhotoIsNull() {
                addCriterion("photo is null");
                return (Criteria) this;
            }

            public Criteria andPhotoIsNotNull() {
                addCriterion("photo is not null");
                return (Criteria) this;
            }

            public Criteria andPhotoEqualTo(String value) {
                addCriterion("photo =", value, "photo");
                return (Criteria) this;
            }

            public Criteria andPhotoNotEqualTo(String value) {
                addCriterion("photo <>", value, "photo");
                return (Criteria) this;
            }

            public Criteria andPhotoGreaterThan(String value) {
                addCriterion("photo >", value, "photo");
                return (Criteria) this;
            }

            public Criteria andPhotoGreaterThanOrEqualTo(String value) {
                addCriterion("photo >=", value, "photo");
                return (Criteria) this;
            }

            public Criteria andPhotoLessThan(String value) {
                addCriterion("photo <", value, "photo");
                return (Criteria) this;
            }

            public Criteria andPhotoLessThanOrEqualTo(String value) {
                addCriterion("photo <=", value, "photo");
                return (Criteria) this;
            }

            public Criteria andPhotoLike(String value) {
                addCriterion("photo like", value, "photo");
                return (Criteria) this;
            }

            public Criteria andPhotoNotLike(String value) {
                addCriterion("photo not like", value, "photo");
                return (Criteria) this;
            }

            public Criteria andPhotoIn(List<String> values) {
                addCriterion("photo in", values, "photo");
                return (Criteria) this;
            }

            public Criteria andPhotoNotIn(List<String> values) {
                addCriterion("photo not in", values, "photo");
                return (Criteria) this;
            }

            public Criteria andPhotoBetween(String value1, String value2) {
                addCriterion("photo between", value1, value2, "photo");
                return (Criteria) this;
            }

            public Criteria andPhotoNotBetween(String value1, String value2) {
                addCriterion("photo not between", value1, value2, "photo");
                return (Criteria) this;
            }

            public Criteria andLoginIpIsNull() {
                addCriterion("login_ip is null");
                return (Criteria) this;
            }

            public Criteria andLoginIpIsNotNull() {
                addCriterion("login_ip is not null");
                return (Criteria) this;
            }

            public Criteria andLoginIpEqualTo(String value) {
                addCriterion("login_ip =", value, "loginIp");
                return (Criteria) this;
            }

            public Criteria andLoginIpNotEqualTo(String value) {
                addCriterion("login_ip <>", value, "loginIp");
                return (Criteria) this;
            }

            public Criteria andLoginIpGreaterThan(String value) {
                addCriterion("login_ip >", value, "loginIp");
                return (Criteria) this;
            }

            public Criteria andLoginIpGreaterThanOrEqualTo(String value) {
                addCriterion("login_ip >=", value, "loginIp");
                return (Criteria) this;
            }

            public Criteria andLoginIpLessThan(String value) {
                addCriterion("login_ip <", value, "loginIp");
                return (Criteria) this;
            }

            public Criteria andLoginIpLessThanOrEqualTo(String value) {
                addCriterion("login_ip <=", value, "loginIp");
                return (Criteria) this;
            }

            public Criteria andLoginIpLike(String value) {
                addCriterion("login_ip like", value, "loginIp");
                return (Criteria) this;
            }

            public Criteria andLoginIpNotLike(String value) {
                addCriterion("login_ip not like", value, "loginIp");
                return (Criteria) this;
            }

            public Criteria andLoginIpIn(List<String> values) {
                addCriterion("login_ip in", values, "loginIp");
                return (Criteria) this;
            }

            public Criteria andLoginIpNotIn(List<String> values) {
                addCriterion("login_ip not in", values, "loginIp");
                return (Criteria) this;
            }

            public Criteria andLoginIpBetween(String value1, String value2) {
                addCriterion("login_ip between", value1, value2, "loginIp");
                return (Criteria) this;
            }

            public Criteria andLoginIpNotBetween(String value1, String value2) {
                addCriterion("login_ip not between", value1, value2, "loginIp");
                return (Criteria) this;
            }

            public Criteria andLoginDateIsNull() {
                addCriterion("login_date is null");
                return (Criteria) this;
            }

            public Criteria andLoginDateIsNotNull() {
                addCriterion("login_date is not null");
                return (Criteria) this;
            }

            public Criteria andLoginDateEqualTo(Date value) {
                addCriterion("login_date =", value, "loginDate");
                return (Criteria) this;
            }

            public Criteria andLoginDateNotEqualTo(Date value) {
                addCriterion("login_date <>", value, "loginDate");
                return (Criteria) this;
            }

            public Criteria andLoginDateGreaterThan(Date value) {
                addCriterion("login_date >", value, "loginDate");
                return (Criteria) this;
            }

            public Criteria andLoginDateGreaterThanOrEqualTo(Date value) {
                addCriterion("login_date >=", value, "loginDate");
                return (Criteria) this;
            }

            public Criteria andLoginDateLessThan(Date value) {
                addCriterion("login_date <", value, "loginDate");
                return (Criteria) this;
            }

            public Criteria andLoginDateLessThanOrEqualTo(Date value) {
                addCriterion("login_date <=", value, "loginDate");
                return (Criteria) this;
            }

            public Criteria andLoginDateIn(List<Date> values) {
                addCriterion("login_date in", values, "loginDate");
                return (Criteria) this;
            }

            public Criteria andLoginDateNotIn(List<Date> values) {
                addCriterion("login_date not in", values, "loginDate");
                return (Criteria) this;
            }

            public Criteria andLoginDateBetween(Date value1, Date value2) {
                addCriterion("login_date between", value1, value2, "loginDate");
                return (Criteria) this;
            }

            public Criteria andLoginDateNotBetween(Date value1, Date value2) {
                addCriterion("login_date not between", value1, value2, "loginDate");
                return (Criteria) this;
            }

            public Criteria andLoginFlagIsNull() {
                addCriterion("login_flag is null");
                return (Criteria) this;
            }

            public Criteria andLoginFlagIsNotNull() {
                addCriterion("login_flag is not null");
                return (Criteria) this;
            }

            public Criteria andLoginFlagEqualTo(String value) {
                addCriterion("login_flag =", value, "loginFlag");
                return (Criteria) this;
            }

            public Criteria andLoginFlagNotEqualTo(String value) {
                addCriterion("login_flag <>", value, "loginFlag");
                return (Criteria) this;
            }

            public Criteria andLoginFlagGreaterThan(String value) {
                addCriterion("login_flag >", value, "loginFlag");
                return (Criteria) this;
            }

            public Criteria andLoginFlagGreaterThanOrEqualTo(String value) {
                addCriterion("login_flag >=", value, "loginFlag");
                return (Criteria) this;
            }

            public Criteria andLoginFlagLessThan(String value) {
                addCriterion("login_flag <", value, "loginFlag");
                return (Criteria) this;
            }

            public Criteria andLoginFlagLessThanOrEqualTo(String value) {
                addCriterion("login_flag <=", value, "loginFlag");
                return (Criteria) this;
            }

            public Criteria andLoginFlagLike(String value) {
                addCriterion("login_flag like", value, "loginFlag");
                return (Criteria) this;
            }

            public Criteria andLoginFlagNotLike(String value) {
                addCriterion("login_flag not like", value, "loginFlag");
                return (Criteria) this;
            }

            public Criteria andLoginFlagIn(List<String> values) {
                addCriterion("login_flag in", values, "loginFlag");
                return (Criteria) this;
            }

            public Criteria andLoginFlagNotIn(List<String> values) {
                addCriterion("login_flag not in", values, "loginFlag");
                return (Criteria) this;
            }

            public Criteria andLoginFlagBetween(String value1, String value2) {
                addCriterion("login_flag between", value1, value2, "loginFlag");
                return (Criteria) this;
            }

            public Criteria andLoginFlagNotBetween(String value1, String value2) {
                addCriterion("login_flag not between", value1, value2, "loginFlag");
                return (Criteria) this;
            }

            public Criteria andCreateByIsNull() {
                addCriterion("create_by is null");
                return (Criteria) this;
            }

            public Criteria andCreateByIsNotNull() {
                addCriterion("create_by is not null");
                return (Criteria) this;
            }

            public Criteria andCreateByEqualTo(String value) {
                addCriterion("create_by =", value, "createBy");
                return (Criteria) this;
            }

            public Criteria andCreateByNotEqualTo(String value) {
                addCriterion("create_by <>", value, "createBy");
                return (Criteria) this;
            }

            public Criteria andCreateByGreaterThan(String value) {
                addCriterion("create_by >", value, "createBy");
                return (Criteria) this;
            }

            public Criteria andCreateByGreaterThanOrEqualTo(String value) {
                addCriterion("create_by >=", value, "createBy");
                return (Criteria) this;
            }

            public Criteria andCreateByLessThan(String value) {
                addCriterion("create_by <", value, "createBy");
                return (Criteria) this;
            }

            public Criteria andCreateByLessThanOrEqualTo(String value) {
                addCriterion("create_by <=", value, "createBy");
                return (Criteria) this;
            }

            public Criteria andCreateByLike(String value) {
                addCriterion("create_by like", value, "createBy");
                return (Criteria) this;
            }

            public Criteria andCreateByNotLike(String value) {
                addCriterion("create_by not like", value, "createBy");
                return (Criteria) this;
            }

            public Criteria andCreateByIn(List<String> values) {
                addCriterion("create_by in", values, "createBy");
                return (Criteria) this;
            }

            public Criteria andCreateByNotIn(List<String> values) {
                addCriterion("create_by not in", values, "createBy");
                return (Criteria) this;
            }

            public Criteria andCreateByBetween(String value1, String value2) {
                addCriterion("create_by between", value1, value2, "createBy");
                return (Criteria) this;
            }

            public Criteria andCreateByNotBetween(String value1, String value2) {
                addCriterion("create_by not between", value1, value2, "createBy");
                return (Criteria) this;
            }

            public Criteria andCreateDateIsNull() {
                addCriterion("create_date is null");
                return (Criteria) this;
            }

            public Criteria andCreateDateIsNotNull() {
                addCriterion("create_date is not null");
                return (Criteria) this;
            }

            public Criteria andCreateDateEqualTo(Date value) {
                addCriterion("create_date =", value, "createDate");
                return (Criteria) this;
            }

            public Criteria andCreateDateNotEqualTo(Date value) {
                addCriterion("create_date <>", value, "createDate");
                return (Criteria) this;
            }

            public Criteria andCreateDateGreaterThan(Date value) {
                addCriterion("create_date >", value, "createDate");
                return (Criteria) this;
            }

            public Criteria andCreateDateGreaterThanOrEqualTo(Date value) {
                addCriterion("create_date >=", value, "createDate");
                return (Criteria) this;
            }

            public Criteria andCreateDateLessThan(Date value) {
                addCriterion("create_date <", value, "createDate");
                return (Criteria) this;
            }

            public Criteria andCreateDateLessThanOrEqualTo(Date value) {
                addCriterion("create_date <=", value, "createDate");
                return (Criteria) this;
            }

            public Criteria andCreateDateIn(List<Date> values) {
                addCriterion("create_date in", values, "createDate");
                return (Criteria) this;
            }

            public Criteria andCreateDateNotIn(List<Date> values) {
                addCriterion("create_date not in", values, "createDate");
                return (Criteria) this;
            }

            public Criteria andCreateDateBetween(Date value1, Date value2) {
                addCriterion("create_date between", value1, value2, "createDate");
                return (Criteria) this;
            }

            public Criteria andCreateDateNotBetween(Date value1, Date value2) {
                addCriterion("create_date not between", value1, value2, "createDate");
                return (Criteria) this;
            }

            public Criteria andUpdateByIsNull() {
                addCriterion("update_by is null");
                return (Criteria) this;
            }

            public Criteria andUpdateByIsNotNull() {
                addCriterion("update_by is not null");
                return (Criteria) this;
            }

            public Criteria andUpdateByEqualTo(String value) {
                addCriterion("update_by =", value, "updateBy");
                return (Criteria) this;
            }

            public Criteria andUpdateByNotEqualTo(String value) {
                addCriterion("update_by <>", value, "updateBy");
                return (Criteria) this;
            }

            public Criteria andUpdateByGreaterThan(String value) {
                addCriterion("update_by >", value, "updateBy");
                return (Criteria) this;
            }

            public Criteria andUpdateByGreaterThanOrEqualTo(String value) {
                addCriterion("update_by >=", value, "updateBy");
                return (Criteria) this;
            }

            public Criteria andUpdateByLessThan(String value) {
                addCriterion("update_by <", value, "updateBy");
                return (Criteria) this;
            }

            public Criteria andUpdateByLessThanOrEqualTo(String value) {
                addCriterion("update_by <=", value, "updateBy");
                return (Criteria) this;
            }

            public Criteria andUpdateByLike(String value) {
                addCriterion("update_by like", value, "updateBy");
                return (Criteria) this;
            }

            public Criteria andUpdateByNotLike(String value) {
                addCriterion("update_by not like", value, "updateBy");
                return (Criteria) this;
            }

            public Criteria andUpdateByIn(List<String> values) {
                addCriterion("update_by in", values, "updateBy");
                return (Criteria) this;
            }

            public Criteria andUpdateByNotIn(List<String> values) {
                addCriterion("update_by not in", values, "updateBy");
                return (Criteria) this;
            }

            public Criteria andUpdateByBetween(String value1, String value2) {
                addCriterion("update_by between", value1, value2, "updateBy");
                return (Criteria) this;
            }

            public Criteria andUpdateByNotBetween(String value1, String value2) {
                addCriterion("update_by not between", value1, value2, "updateBy");
                return (Criteria) this;
            }

            public Criteria andUpdateDateIsNull() {
                addCriterion("update_date is null");
                return (Criteria) this;
            }

            public Criteria andUpdateDateIsNotNull() {
                addCriterion("update_date is not null");
                return (Criteria) this;
            }

            public Criteria andUpdateDateEqualTo(Date value) {
                addCriterion("update_date =", value, "updateDate");
                return (Criteria) this;
            }

            public Criteria andUpdateDateNotEqualTo(Date value) {
                addCriterion("update_date <>", value, "updateDate");
                return (Criteria) this;
            }

            public Criteria andUpdateDateGreaterThan(Date value) {
                addCriterion("update_date >", value, "updateDate");
                return (Criteria) this;
            }

            public Criteria andUpdateDateGreaterThanOrEqualTo(Date value) {
                addCriterion("update_date >=", value, "updateDate");
                return (Criteria) this;
            }

            public Criteria andUpdateDateLessThan(Date value) {
                addCriterion("update_date <", value, "updateDate");
                return (Criteria) this;
            }

            public Criteria andUpdateDateLessThanOrEqualTo(Date value) {
                addCriterion("update_date <=", value, "updateDate");
                return (Criteria) this;
            }

            public Criteria andUpdateDateIn(List<Date> values) {
                addCriterion("update_date in", values, "updateDate");
                return (Criteria) this;
            }

            public Criteria andUpdateDateNotIn(List<Date> values) {
                addCriterion("update_date not in", values, "updateDate");
                return (Criteria) this;
            }

            public Criteria andUpdateDateBetween(Date value1, Date value2) {
                addCriterion("update_date between", value1, value2, "updateDate");
                return (Criteria) this;
            }

            public Criteria andUpdateDateNotBetween(Date value1, Date value2) {
                addCriterion("update_date not between", value1, value2, "updateDate");
                return (Criteria) this;
            }

            public Criteria andRemarksIsNull() {
                addCriterion("remarks is null");
                return (Criteria) this;
            }

            public Criteria andRemarksIsNotNull() {
                addCriterion("remarks is not null");
                return (Criteria) this;
            }

            public Criteria andRemarksEqualTo(String value) {
                addCriterion("remarks =", value, "remarks");
                return (Criteria) this;
            }

            public Criteria andRemarksNotEqualTo(String value) {
                addCriterion("remarks <>", value, "remarks");
                return (Criteria) this;
            }

            public Criteria andRemarksGreaterThan(String value) {
                addCriterion("remarks >", value, "remarks");
                return (Criteria) this;
            }

            public Criteria andRemarksGreaterThanOrEqualTo(String value) {
                addCriterion("remarks >=", value, "remarks");
                return (Criteria) this;
            }

            public Criteria andRemarksLessThan(String value) {
                addCriterion("remarks <", value, "remarks");
                return (Criteria) this;
            }

            public Criteria andRemarksLessThanOrEqualTo(String value) {
                addCriterion("remarks <=", value, "remarks");
                return (Criteria) this;
            }

            public Criteria andRemarksLike(String value) {
                addCriterion("remarks like", value, "remarks");
                return (Criteria) this;
            }

            public Criteria andRemarksNotLike(String value) {
                addCriterion("remarks not like", value, "remarks");
                return (Criteria) this;
            }

            public Criteria andRemarksIn(List<String> values) {
                addCriterion("remarks in", values, "remarks");
                return (Criteria) this;
            }

            public Criteria andRemarksNotIn(List<String> values) {
                addCriterion("remarks not in", values, "remarks");
                return (Criteria) this;
            }

            public Criteria andRemarksBetween(String value1, String value2) {
                addCriterion("remarks between", value1, value2, "remarks");
                return (Criteria) this;
            }

            public Criteria andRemarksNotBetween(String value1, String value2) {
                addCriterion("remarks not between", value1, value2, "remarks");
                return (Criteria) this;
            }

            public Criteria andDelFlagIsNull() {
                addCriterion("del_flag is null");
                return (Criteria) this;
            }

            public Criteria andDelFlagIsNotNull() {
                addCriterion("del_flag is not null");
                return (Criteria) this;
            }

            public Criteria andDelFlagEqualTo(String value) {
                addCriterion("del_flag =", value, "delFlag");
                return (Criteria) this;
            }

            public Criteria andDelFlagNotEqualTo(String value) {
                addCriterion("del_flag <>", value, "delFlag");
                return (Criteria) this;
            }

            public Criteria andDelFlagGreaterThan(String value) {
                addCriterion("del_flag >", value, "delFlag");
                return (Criteria) this;
            }

            public Criteria andDelFlagGreaterThanOrEqualTo(String value) {
                addCriterion("del_flag >=", value, "delFlag");
                return (Criteria) this;
            }

            public Criteria andDelFlagLessThan(String value) {
                addCriterion("del_flag <", value, "delFlag");
                return (Criteria) this;
            }

            public Criteria andDelFlagLessThanOrEqualTo(String value) {
                addCriterion("del_flag <=", value, "delFlag");
                return (Criteria) this;
            }

            public Criteria andDelFlagLike(String value) {
                addCriterion("del_flag like", value, "delFlag");
                return (Criteria) this;
            }

            public Criteria andDelFlagNotLike(String value) {
                addCriterion("del_flag not like", value, "delFlag");
                return (Criteria) this;
            }

            public Criteria andDelFlagIn(List<String> values) {
                addCriterion("del_flag in", values, "delFlag");
                return (Criteria) this;
            }

            public Criteria andDelFlagNotIn(List<String> values) {
                addCriterion("del_flag not in", values, "delFlag");
                return (Criteria) this;
            }

            public Criteria andDelFlagBetween(String value1, String value2) {
                addCriterion("del_flag between", value1, value2, "delFlag");
                return (Criteria) this;
            }

            public Criteria andDelFlagNotBetween(String value1, String value2) {
                addCriterion("del_flag not between", value1, value2, "delFlag");
                return (Criteria) this;
            }
        }

        public static class Criteria extends GeneratedCriteria {

            protected Criteria() {
                super();
            }
        }

        public static class Criterion {
            private String condition;

            private Object value;

            private Object secondValue;

            private boolean noValue;

            private boolean singleValue;

            private boolean betweenValue;

            private boolean listValue;

            private String typeHandler;

            public String getCondition() {
                return condition;
            }

            public Object getValue() {
                return value;
            }

            public Object getSecondValue() {
                return secondValue;
            }

            public boolean isNoValue() {
                return noValue;
            }

            public boolean isSingleValue() {
                return singleValue;
            }

            public boolean isBetweenValue() {
                return betweenValue;
            }

            public boolean isListValue() {
                return listValue;
            }

            public String getTypeHandler() {
                return typeHandler;
            }

            protected Criterion(String condition) {
                super();
                this.condition = condition;
                this.typeHandler = null;
                this.noValue = true;
            }

            protected Criterion(String condition, Object value, String typeHandler) {
                super();
                this.condition = condition;
                this.value = value;
                this.typeHandler = typeHandler;
                if (value instanceof List<?>) {
                    this.listValue = true;
                } else {
                    this.singleValue = true;
                }
            }

            protected Criterion(String condition, Object value) {
                this(condition, value, null);
            }

            protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
                super();
                this.condition = condition;
                this.value = value;
                this.secondValue = secondValue;
                this.typeHandler = typeHandler;
                this.betweenValue = true;
            }

            protected Criterion(String condition, Object value, Object secondValue) {
                this(condition, value, secondValue, null);
            }
        }
    }
2. mapper:

SysUserMapper.java

package com.zhihuizhengan.ssm.shiro.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Param;

import com.zhihuizhengan.ssm.shiro.pojo.SysUser;
import com.zhihuizhengan.ssm.shiro.pojo.SysUserExample;

public interface SysUserMapper {
    int countByExample(SysUserExample example);

    int deleteByExample(SysUserExample example);

    int insert(SysUser record);

    int insertSelective(SysUser record);

    List<SysUser> selectByExample(SysUserExample example);

    int updateByExampleSelective(@Param("record") SysUser record, @Param("example") SysUserExample example);

    int updateByExample(@Param("record") SysUser record, @Param("example") SysUserExample example);

    SysUser selectSysUser(@Param("loginName") String loginName);
}

SysUserMapper.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.zhihuizhengan.ssm.shiro.mapper.SysUserMapper" >
      <resultMap id="BaseResultMap" type="com.zhihuizhengan.ssm.shiro.pojo.SysUser" >
        <result column="id" property="id" jdbcType="VARCHAR" />
        <result column="company_id" property="companyId" jdbcType="VARCHAR" />
        <result column="office_id" property="officeId" jdbcType="VARCHAR" />
        <result column="login_name" property="loginName" jdbcType="VARCHAR" />
        <result column="password" property="password" jdbcType="VARCHAR" />
        <result column="no" property="no" jdbcType="VARCHAR" />
        <result column="name" property="name" jdbcType="VARCHAR" />
        <result column="email" property="email" jdbcType="VARCHAR" />
        <result column="phone" property="phone" jdbcType="VARCHAR" />
        <result column="mobile" property="mobile" jdbcType="VARCHAR" />
        <result column="user_type" property="userType" jdbcType="CHAR" />
        <result column="photo" property="photo" jdbcType="VARCHAR" />
        <result column="login_ip" property="loginIp" jdbcType="VARCHAR" />
        <result column="login_date" property="loginDate" jdbcType="TIMESTAMP" />
        <result column="login_flag" property="loginFlag" jdbcType="VARCHAR" />
        <result column="create_by" property="createBy" jdbcType="VARCHAR" />
        <result column="create_date" property="createDate" jdbcType="TIMESTAMP" />
        <result column="update_by" property="updateBy" jdbcType="VARCHAR" />
        <result column="update_date" property="updateDate" jdbcType="TIMESTAMP" />
        <result column="remarks" property="remarks" jdbcType="VARCHAR" />
        <result column="del_flag" property="delFlag" jdbcType="CHAR" />
      </resultMap>
      <sql id="Example_Where_Clause" >
        <where >
          <foreach collection="oredCriteria" item="criteria" separator="or" >
            <if test="criteria.valid" >
              <trim prefix="(" suffix=")" prefixOverrides="and" >
                <foreach collection="criteria.criteria" item="criterion" >
                  <choose >
                    <when test="criterion.noValue" >
                      and ${criterion.condition}
                    </when>
                    <when test="criterion.singleValue" >
                      and ${criterion.condition} #{criterion.value}
                    </when>
                    <when test="criterion.betweenValue" >
                      and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                    </when>
                    <when test="criterion.listValue" >
                      and ${criterion.condition}
                      <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
                        #{listItem}
                      </foreach>
                    </when>
                  </choose>
                </foreach>
              </trim>
            </if>
          </foreach>
        </where>
      </sql>
      <sql id="Update_By_Example_Where_Clause" >
        <where >
          <foreach collection="example.oredCriteria" item="criteria" separator="or" >
            <if test="criteria.valid" >
              <trim prefix="(" suffix=")" prefixOverrides="and" >
                <foreach collection="criteria.criteria" item="criterion" >
                  <choose >
                    <when test="criterion.noValue" >
                      and ${criterion.condition}
                    </when>
                    <when test="criterion.singleValue" >
                      and ${criterion.condition} #{criterion.value}
                    </when>
                    <when test="criterion.betweenValue" >
                      and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                    </when>
                    <when test="criterion.listValue" >
                      and ${criterion.condition}
                      <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
                        #{listItem}
                      </foreach>
                    </when>
                  </choose>
                </foreach>
              </trim>
            </if>
          </foreach>
        </where>
      </sql>
      <sql id="Base_Column_List" >
        id, company_id, office_id, login_name, password, no, name, email, phone, mobile, 
        user_type, photo, login_ip, login_date, login_flag, create_by, create_date, update_by, 
        update_date, remarks, del_flag
      </sql>
      <select id="selectByExample" resultMap="BaseResultMap" parameterType="com.zhihuizhengan.ssm.shiro.pojo.SysUserExample" >
        select
        <if test="distinct" >
          distinct
        </if>
        <include refid="Base_Column_List" />
        from sys_user
        <if test="_parameter != null" >
          <include refid="Example_Where_Clause" />
        </if>
        <if test="orderByClause != null" >
          order by ${orderByClause}
        </if>
      </select>

      <select id="selectSysUser" resultMap="BaseResultMap" parameterType="string" >
        select

        <include refid="Base_Column_List" />
        from sys_user where login_name=#{loginName}

      </select>
      <delete id="deleteByExample" parameterType="com.zhihuizhengan.ssm.shiro.pojo.SysUserExample" >
        delete from sys_user
        <if test="_parameter != null" >
          <include refid="Example_Where_Clause" />
        </if>
      </delete>
      <insert id="insert" parameterType="com.zhihuizhengan.ssm.shiro.pojo.SysUser" >
        insert into sys_user (id, company_id, office_id, 
          login_name, password, no, 
          name, email, phone, 
          mobile, user_type, photo, 
          login_ip, login_date, login_flag, 
          create_by, create_date, update_by, 
          update_date, remarks, del_flag
          )
        values (#{id,jdbcType=VARCHAR}, #{companyId,jdbcType=VARCHAR}, #{officeId,jdbcType=VARCHAR}, 
          #{loginName,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{no,jdbcType=VARCHAR}, 
          #{name,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{phone,jdbcType=VARCHAR}, 
          #{mobile,jdbcType=VARCHAR}, #{userType,jdbcType=CHAR}, #{photo,jdbcType=VARCHAR}, 
          #{loginIp,jdbcType=VARCHAR}, #{loginDate,jdbcType=TIMESTAMP}, #{loginFlag,jdbcType=VARCHAR}, 
          #{createBy,jdbcType=VARCHAR}, #{createDate,jdbcType=TIMESTAMP}, #{updateBy,jdbcType=VARCHAR}, 
          #{updateDate,jdbcType=TIMESTAMP}, #{remarks,jdbcType=VARCHAR}, #{delFlag,jdbcType=CHAR}
          )
      </insert>
      <insert id="insertSelective" parameterType="com.zhihuizhengan.ssm.shiro.pojo.SysUser" >
        insert into sys_user
        <trim prefix="(" suffix=")" suffixOverrides="," >
          <if test="id != null" >
            id,
          </if>
          <if test="companyId != null" >
            company_id,
          </if>
          <if test="officeId != null" >
            office_id,
          </if>
          <if test="loginName != null" >
            login_name,
          </if>
          <if test="password != null" >
            password,
          </if>
          <if test="no != null" >
            no,
          </if>
          <if test="name != null" >
            name,
          </if>
          <if test="email != null" >
            email,
          </if>
          <if test="phone != null" >
            phone,
          </if>
          <if test="mobile != null" >
            mobile,
          </if>
          <if test="userType != null" >
            user_type,
          </if>
          <if test="photo != null" >
            photo,
          </if>
          <if test="loginIp != null" >
            login_ip,
          </if>
          <if test="loginDate != null" >
            login_date,
          </if>
          <if test="loginFlag != null" >
            login_flag,
          </if>
          <if test="createBy != null" >
            create_by,
          </if>
          <if test="createDate != null" >
            create_date,
          </if>
          <if test="updateBy != null" >
            update_by,
          </if>
          <if test="updateDate != null" >
            update_date,
          </if>
          <if test="remarks != null" >
            remarks,
          </if>
          <if test="delFlag != null" >
            del_flag,
          </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides="," >
          <if test="id != null" >
            #{id,jdbcType=VARCHAR},
          </if>
          <if test="companyId != null" >
            #{companyId,jdbcType=VARCHAR},
          </if>
          <if test="officeId != null" >
            #{officeId,jdbcType=VARCHAR},
          </if>
          <if test="loginName != null" >
            #{loginName,jdbcType=VARCHAR},
          </if>
          <if test="password != null" >
            #{password,jdbcType=VARCHAR},
          </if>
          <if test="no != null" >
            #{no,jdbcType=VARCHAR},
          </if>
          <if test="name != null" >
            #{name,jdbcType=VARCHAR},
          </if>
          <if test="email != null" >
            #{email,jdbcType=VARCHAR},
          </if>
          <if test="phone != null" >
            #{phone,jdbcType=VARCHAR},
          </if>
          <if test="mobile != null" >
            #{mobile,jdbcType=VARCHAR},
          </if>
          <if test="userType != null" >
            #{userType,jdbcType=CHAR},
          </if>
          <if test="photo != null" >
            #{photo,jdbcType=VARCHAR},
          </if>
          <if test="loginIp != null" >
            #{loginIp,jdbcType=VARCHAR},
          </if>
          <if test="loginDate != null" >
            #{loginDate,jdbcType=TIMESTAMP},
          </if>
          <if test="loginFlag != null" >
            #{loginFlag,jdbcType=VARCHAR},
          </if>
          <if test="createBy != null" >
            #{createBy,jdbcType=VARCHAR},
          </if>
          <if test="createDate != null" >
            #{createDate,jdbcType=TIMESTAMP},
          </if>
          <if test="updateBy != null" >
            #{updateBy,jdbcType=VARCHAR},
          </if>
          <if test="updateDate != null" >
            #{updateDate,jdbcType=TIMESTAMP},
          </if>
          <if test="remarks != null" >
            #{remarks,jdbcType=VARCHAR},
          </if>
          <if test="delFlag != null" >
            #{delFlag,jdbcType=CHAR},
          </if>
        </trim>
      </insert>
      <select id="countByExample" parameterType="com.zhihuizhengan.ssm.shiro.pojo.SysUserExample" resultType="java.lang.Integer" >
        select count(*) from sys_user
        <if test="_parameter != null" >
          <include refid="Example_Where_Clause" />
        </if>
      </select>
      <update id="updateByExampleSelective" parameterType="map" >
        update sys_user
        <set >
          <if test="record.id != null" >
            id = #{record.id,jdbcType=VARCHAR},
          </if>
          <if test="record.companyId != null" >
            company_id = #{record.companyId,jdbcType=VARCHAR},
          </if>
          <if test="record.officeId != null" >
            office_id = #{record.officeId,jdbcType=VARCHAR},
          </if>
          <if test="record.loginName != null" >
            login_name = #{record.loginName,jdbcType=VARCHAR},
          </if>
          <if test="record.password != null" >
            password = #{record.password,jdbcType=VARCHAR},
          </if>
          <if test="record.no != null" >
            no = #{record.no,jdbcType=VARCHAR},
          </if>
          <if test="record.name != null" >
            name = #{record.name,jdbcType=VARCHAR},
          </if>
          <if test="record.email != null" >
            email = #{record.email,jdbcType=VARCHAR},
          </if>
          <if test="record.phone != null" >
            phone = #{record.phone,jdbcType=VARCHAR},
          </if>
          <if test="record.mobile != null" >
            mobile = #{record.mobile,jdbcType=VARCHAR},
          </if>
          <if test="record.userType != null" >
            user_type = #{record.userType,jdbcType=CHAR},
          </if>
          <if test="record.photo != null" >
            photo = #{record.photo,jdbcType=VARCHAR},
          </if>
          <if test="record.loginIp != null" >
            login_ip = #{record.loginIp,jdbcType=VARCHAR},
          </if>
          <if test="record.loginDate != null" >
            login_date = #{record.loginDate,jdbcType=TIMESTAMP},
          </if>
          <if test="record.loginFlag != null" >
            login_flag = #{record.loginFlag,jdbcType=VARCHAR},
          </if>
          <if test="record.createBy != null" >
            create_by = #{record.createBy,jdbcType=VARCHAR},
          </if>
          <if test="record.createDate != null" >
            create_date = #{record.createDate,jdbcType=TIMESTAMP},
          </if>
          <if test="record.updateBy != null" >
            update_by = #{record.updateBy,jdbcType=VARCHAR},
          </if>
          <if test="record.updateDate != null" >
            update_date = #{record.updateDate,jdbcType=TIMESTAMP},
          </if>
          <if test="record.remarks != null" >
            remarks = #{record.remarks,jdbcType=VARCHAR},
          </if>
          <if test="record.delFlag != null" >
            del_flag = #{record.delFlag,jdbcType=CHAR},
          </if>
        </set>
        <if test="_parameter != null" >
          <include refid="Update_By_Example_Where_Clause" />
        </if>
      </update>
      <update id="updateByExample" parameterType="map" >
        update sys_user
        set id = #{record.id,jdbcType=VARCHAR},
          company_id = #{record.companyId,jdbcType=VARCHAR},
          office_id = #{record.officeId,jdbcType=VARCHAR},
          login_name = #{record.loginName,jdbcType=VARCHAR},
          password = #{record.password,jdbcType=VARCHAR},
          no = #{record.no,jdbcType=VARCHAR},
          name = #{record.name,jdbcType=VARCHAR},
          email = #{record.email,jdbcType=VARCHAR},
          phone = #{record.phone,jdbcType=VARCHAR},
          mobile = #{record.mobile,jdbcType=VARCHAR},
          user_type = #{record.userType,jdbcType=CHAR},
          photo = #{record.photo,jdbcType=VARCHAR},
          login_ip = #{record.loginIp,jdbcType=VARCHAR},
          login_date = #{record.loginDate,jdbcType=TIMESTAMP},
          login_flag = #{record.loginFlag,jdbcType=VARCHAR},
          create_by = #{record.createBy,jdbcType=VARCHAR},
          create_date = #{record.createDate,jdbcType=TIMESTAMP},
          update_by = #{record.updateBy,jdbcType=VARCHAR},
          update_date = #{record.updateDate,jdbcType=TIMESTAMP},
          remarks = #{record.remarks,jdbcType=VARCHAR},
          del_flag = #{record.delFlag,jdbcType=CHAR}
        <if test="_parameter != null" >
          <include refid="Update_By_Example_Where_Clause" />
        </if>
      </update>
    </mapper>
3.service

SysUserService

package com.zhihuizhengan.ssm.shiro.service;

import com.zhihuizhengan.ssm.shiro.pojo.SysUser;

public interface SysUserService {
    /**
     * 根据用户名获取用户信息
     * @param name 用户名
     * @return
     */
    SysUser getUserInfoByName(String name);
    /**
     * 获取用户信息
     */
    SysUser getUserInfo(SysUser sysUser);
}

SysUserServiceImpl

package com.zhihuizhengan.ssm.shiro.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.zhihuizhengan.ssm.shiro.mapper.SysUserMapper;
import com.zhihuizhengan.ssm.shiro.pojo.SysUser;
import com.zhihuizhengan.ssm.shiro.pojo.SysUserExample;
import com.zhihuizhengan.ssm.shiro.pojo.SysUserExample.Criteria;
import com.zhihuizhengan.ssm.shiro.service.SysUserService;
import com.zhihuizhengan.ssm.shiro.util.MatchUtil;

@Service(value="sysUserService")
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    public SysUserMapper getSysUserMapper() {
        return sysUserMapper;
    }

    public void setSysUserMapper(SysUserMapper sysUserMapper) {
        this.sysUserMapper = sysUserMapper;
    }

    @Override
    public SysUser getUserInfoByName(String loginName) {
        if (!MatchUtil.isEmpty(loginName)) {
            return sysUserMapper.selectSysUser(loginName);
            /*SysUserExample example = new SysUserExample();
            Criteria criteria = example.createCriteria();
            criteria.andLoginNameEqualTo(name);
            List<SysUser> userList = sysUserMapper.selectByExample(example);
            if (!MatchUtil.isEmpty(userList) && userList.size() > 0) {
                return userList.get(0);
            }*/
        }
        return null;
    }

    @Override
    public SysUser getUserInfo(SysUser sysUser) {
        if (!MatchUtil.isEmpty(sysUser)) {
            SysUserExample example = new SysUserExample();
            Criteria criteria = example.createCriteria();
            criteria.andLoginNameEqualTo(sysUser.getLoginName());
            criteria.andPasswordEqualTo(sysUser.getPassword());
            List<SysUser> userList = sysUserMapper.selectByExample(example);
            if (!MatchUtil.isEmpty(userList) && userList.size() > 0) {
                return userList.get(0);
            }
        }
        return null;
    }

}
4.util

MatchUtil.java

    package com.zhihuizhengan.ssm.shiro.util;



    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;


    public class MatchUtil {

        /**
         * 判断对象是否为空
         *
         * @param obj 对象
         * @return 是否为空
         */
        public static boolean isEmpty(Object obj) {
            return obj == null;
        }

        /**
         * 判断哈希是否为空
         *
         * @param map 哈希
         * @return 是否为空
         */
        public static boolean isEmpty(Map<?, ?> map) {
            return (map == null || map.size() == 0);
        }

        /**
         * 判断字符是否为空
         *
         * @param str 字符
         * @return 是否为空
         */
        public static boolean isEmpty(String str) {
            return (str == null || "".equals(str) || "null".equalsIgnoreCase(str) || str.trim().length() == 0);
        }

        /**
         * 判断数组是否为空
         *
         * @param arr 数组
         * @return 是否为空
         */
        public static boolean isEmpty(Arrays[] arr) {
            return (arr == null || arr.length == 0);
        }

        /**
         * 判断列表是否为空
         *
         * @param lis 列表
         * @return 是否为空
         */
        public static boolean isEmpty(List<?> lis) {
            return (lis == null || lis.size() == 0);
        }

        /**
         * 判断集合是否为空
         *
         * @param ita 集合
         * @return 是否为空
         */
        public static boolean isEmpty(Iterator<?> ita) {
            return (ita == null || !ita.hasNext());
        }

        /**
         * 判断缓存是否为空
         *
         * @param sbf 缓存
         * @return 是否为空
         */
        public static boolean isEmpty(StringBuffer sbf) {
            return (sbf == null || sbf.length() == 0);
        }

    }

StringUtils.java

    package com.zhihuizhengan.ssm.shiro.util;

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.List;
    import java.util.UUID;

    import javax.servlet.http.HttpServletRequest;

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;

    /**
     * 字符处理工具类
     */
    public class StringUtils extends org.apache.commons.lang3.StringUtils {

        private static final transient Logger logger =  LoggerFactory.getLogger(StringUtils.class);


        /**
         * 获得用户远程地址
         */
        public static String getRemoteAddr(HttpServletRequest request){
            String remoteAddr = request.getHeader("X-Real-IP");
            if (isNotBlank(remoteAddr)) {
                remoteAddr = request.getHeader("X-Forwarded-For");
            }else if (isNotBlank(remoteAddr)) {
                remoteAddr = request.getHeader("Proxy-Client-IP");
            }else if (isNotBlank(remoteAddr)) {
                remoteAddr = request.getHeader("WL-Proxy-Client-IP");
            }
            return remoteAddr != null ? remoteAddr : request.getRemoteAddr();
        }
    }
5.controller

SysUserController.java

        package com.zhihuizhengan.ssm.shiro.controller;

        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;

        import org.apache.shiro.SecurityUtils;
        import org.apache.shiro.authz.annotation.RequiresPermissions;
        import org.apache.shiro.subject.Subject;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.stereotype.Controller;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RequestMethod;
        import org.springframework.web.bind.annotation.RequestParam;
        import org.springframework.web.bind.annotation.ResponseBody;

        import com.zhihuizhengan.ssm.shiro.pojo.SysUser;
        import com.zhihuizhengan.ssm.shiro.service.SysUserService;
        import com.zhihuizhengan.ssm.shiro.util.MatchUtil;

        import net.sf.json.JSONObject;
        @Controller
        public class SysUserController {
            @Autowired
            private SysUserService sysUserService;

            /**
             * 登录页面
             */
            @RequestMapping(value="/login")
            public String login(HttpServletRequest request, HttpServletResponse response) {
                System.out.println(123);
                return "login";
            }

            /**
             * 登录提交表单(post),并创建token,
             */
            @RequestMapping(value="/login" , method = RequestMethod.POST)
            public String loginForm(HttpServletRequest request, HttpServletResponse response) {
            // 当第一次登陆的时候,不会走下面的地址, 如果成功会走配置的 successUrl配置对应的地址
            // 当用户已经登陆过后,已经存在session中, 不会再次去创建token,此时会走下面的 return "/index" 直接进入页面
                return "/index";
            }
            /**
             * 退出
             */
            @RequestMapping(value="/loginOut")
            public String loginOut(HttpServletRequest request, HttpServletResponse response) {
                return "login";
            }

            /**
             * 验证登录
             */
            @RequestMapping(value="/loginVerify")
            @ResponseBody
            public String verifyLogin(@RequestParam String loginName, @RequestParam String password) {
                JSONObject result = new JSONObject();
                SysUser sysUser = new SysUser();
                sysUser.setLoginName(loginName);
                sysUser.setPassword(password);
                SysUser userInfo = sysUserService.getUserInfo(sysUser);
                if (!MatchUtil.isEmpty(userInfo)) {
                    result.put("status", "1");
                } else {
                    result.put("status", "0");
                }
                return result.toString();
            }
            /**
             * 登录成功跳转
             */
            @RequestMapping(value="/index")
            @RequiresPermissions(value="index:view")
            public String indexPage(HttpServletRequest request, HttpServletResponse response){
                Subject subject = SecurityUtils.getSubject();
                Subject subject = SecurityUtils.getSubject();
                if (!MatchUtil.isEmpty(subject)) {
                    Principal principal = (Principal) subject.getPrincipal();
                    request.setAttribute("name", !MatchUtil.isEmpty(principal) ? principal.getName(): "");
                }
                return "index";
            }
        }

SysUserController2.java

package com.zhihuizhengan.ssm.shiro.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.zhihuizhengan.ssm.shiro.pojo.SysUser;
import com.zhihuizhengan.ssm.shiro.service.SysUserService;
import com.zhihuizhengan.ssm.shiro.util.MatchUtil;

import net.sf.json.JSONObject;
/*@Controller*/
public class SysUserController2 implements Controller  {
    @Autowired
    private SysUserService sysUserService;
    /**
     * 1.收集参数/验证参数
     * 2.绑定参数到命令对象
     * 3.将命令对象传入业务对象进行业务处理
     * 4.选择下一个页面
     */
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelAndView mvAndView = new ModelAndView();
        // 添加数据模型
        mvAndView.addObject("message", "Hello World!");
        // 设置视图逻辑名,视图解析器更具该名字解析到具体的视图
        mvAndView.setViewName("login");
        return mvAndView;
    }
}
6.security

FormAuthenticationFilter.java
/**
* Copyright © 2012-2014 JeeSite All rights reserved.
*/
package com.zhihuizhengan.ssm.shiro.security;

    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;

    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.web.util.WebUtils;
    import org.springframework.stereotype.Service;

    import com.zhihuizhengan.ssm.shiro.util.StringUtils;

    /**
     * 表单验证(包含验证码)过滤类
     * @author ThinkGem
     * @version 2014-5-19
     */
    @Service
    public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter {

        public static final String DEFAULT_CAPTCHA_PARAM = "validateCode";
        public static final String DEFAULT_MOBILE_PARAM = "mobileLogin";
        public static final String DEFAULT_MESSAGE_PARAM = "message";

        private String captchaParam = DEFAULT_CAPTCHA_PARAM;
        private String mobileLoginParam = DEFAULT_MOBILE_PARAM;
        private String messageParam = DEFAULT_MESSAGE_PARAM;

        protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
            String parameter = request.getParameter("username");
            String parameter2 = request.getParameter("loginName");
            String username = getUsername(request);
            String password = getPassword(request);
            boolean rememberMe = isRememberMe(request);
            String host = StringUtils.getRemoteAddr((HttpServletRequest)request);
            String captcha = getCaptcha(request);
            boolean mobile = isMobileLogin(request);
            return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha, mobile);
        }

        public String getCaptchaParam() {
            return captchaParam;
        }

        protected String getCaptcha(ServletRequest request) {
            return WebUtils.getCleanParam(request, getCaptchaParam());
        }

        public String getMobileLoginParam() {
            return mobileLoginParam;
        }

        protected boolean isMobileLogin(ServletRequest request) {
            return WebUtils.isTrue(request, getMobileLoginParam());
        }

        public String getMessageParam() {
            return messageParam;
        }

        /**
         * 登录成功之后跳转URL
         */
        public String getSuccessUrl() {
            return super.getSuccessUrl();
        }

        @Override
        protected void issueSuccessRedirect(ServletRequest request,
                ServletResponse response) throws Exception {
             WebUtils.issueRedirect(request, response, getSuccessUrl(), null, true);
        }

        /**
         * 登录失败调用事件
         */
        @Override
        protected boolean onLoginFailure(AuthenticationToken token,
                AuthenticationException e, ServletRequest request, ServletResponse response) {
            String className = e.getClass().getName(), message = "";
            if (IncorrectCredentialsException.class.getName().equals(className)
                    || UnknownAccountException.class.getName().equals(className)){
                message = "用户或密码错误, 请重试.";
            }
            else if (e.getMessage() != null && StringUtils.startsWith(e.getMessage(), "msg:")){
                message = StringUtils.replace(e.getMessage(), "msg:", "");
            }
            else{
                message = "系统出现点问题,请稍后再试!";
                e.printStackTrace(); // 输出到控制台
            }
            request.setAttribute(getFailureKeyAttribute(), className);
            request.setAttribute(getMessageParam(), message);
            return true;
        }
    }

SystemAuthorizingRealm.java

    package com.zhihuizhengan.ssm.shiro.security;

    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;

    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.SimpleAuthenticationInfo;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.Permission;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.crypto.hash.Md5Hash;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.apache.shiro.util.ByteSource;
    import org.apache.tomcat.util.security.MD5Encoder;
    import org.springframework.beans.factory.annotation.Autowired;

    import com.zhihuizhengan.ssm.shiro.pojo.SysUser;
    import com.zhihuizhengan.ssm.shiro.service.SysUserService;
    import com.zhihuizhengan.ssm.shiro.util.MatchUtil;

    public class SystemAuthorizingRealm extends AuthorizingRealm{
        @Autowired
        private SysUserService sysUserService;
        /**
         * 认证回调函数, 登录时调用
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) {
            String userName = (String) authenticationToken.getPrincipal();
            if (MatchUtil.isEmpty(userName)) {
                return  null;
            }
            SysUser user = sysUserService.getUserInfoByName(userName);
            if(!MatchUtil.isEmpty(user)){
                /* byte[] salt = Md5Hash.toBytes(user.getPassword());*/
                 SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(new Principal(user, false),
                        user.getPassword(), null, getName());

                 return simpleAuthenticationInfo;
            }
           return null;
        }

        /**
         * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            Principal principal = (Principal) getAvailablePrincipal(principals);

            String userName = (String) principal.getLoginName();
            if(!MatchUtil.isEmpty(userName)){

                SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();

                //登录用户拥有权限的菜单
                /*List<SysMenu> menuList =  getSysMenuService().getMenuListByLoginName(userName);*/
                List<String> permissionList=new ArrayList<String>();
                //登录用户的角色列表
                List<String> roleList =  new ArrayList<String>();
                if ("xzb".equals(userName)) {
                    permissionList.add("index:edit");
                    permissionList.add("index:view");

                    // 写的角色
                    roleList.add("write");
                }
                if ("xzb1".equals(userName)) {
                    permissionList.add("index:view");

                    // 读的角色
                    roleList.add("read");
                }

                info.addStringPermissions(permissionList);



                // 添加用户角色信息
                for (String role : roleList){
                    info.addRole(role);
                }
                return info;
            }else{
                return null;
            }
        }

        @Override
        protected void checkPermission(Permission permission, AuthorizationInfo info) {
            authorizationValidate(permission);
            super.checkPermission(permission, info);
        }

        @Override
        protected boolean[] isPermitted(List<Permission> permissions, AuthorizationInfo info) {
            if (permissions != null && !permissions.isEmpty()) {
                for (Permission permission : permissions) {
                    authorizationValidate(permission);
                }
            }
            return super.isPermitted(permissions, info);
        }

        @Override
        public boolean isPermitted(PrincipalCollection principals, Permission permission) {
            authorizationValidate(permission);
            return super.isPermitted(principals, permission);
        }

        @Override
        protected boolean isPermittedAll(Collection<Permission> permissions, AuthorizationInfo info) {
            if (permissions != null && !permissions.isEmpty()) {
                for (Permission permission : permissions) {
                    authorizationValidate(permission);
                }
            }
            return super.isPermittedAll(permissions, info);
        }

        /**
         * 授权验证方法
         * 
         * @param permission
         */
        private void authorizationValidate(Permission permission) {
            // 模块授权预留接口
        }

        /**
         * 清空所有关联认证
         * 
         * @Deprecated 不需要清空,授权缓存保存到session中
         */
        @Deprecated
        public void clearAllCachedAuthorizationInfo() {
        }

        /**
         * 授权用户信息
         */
        public static class Principal implements Serializable {

            private static final long serialVersionUID = 1L;

            private String id; // 编号
            private String loginName; // 登录名
            private String name; // 姓名
            private boolean mobileLogin; // 是否手机登录

            // private Map<String, Object> cacheMap;

            public Principal(SysUser user, boolean mobileLogin) {
                this.id = user.getId();
                this.loginName = user.getLoginName();
                this.name = user.getName();
                this.mobileLogin = mobileLogin;
            }

            public String getId() {
                return id;
            }

            public String getLoginName() {
                return loginName;
            }

            public String getName() {
                return name;
            }

            public boolean isMobileLogin() {
                return mobileLogin;
            }

            @Override
            public String toString() {
                return id;
            }

        }

    }

UsernamePasswordToken.java

    /**
     * Copyright &copy; 2012-2014 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
     */
    package com.zhihuizhengan.ssm.shiro.security;

    /**
     * 用户和密码(包含验证码)令牌类
     * @author ThinkGem
     * @version 2013-5-19
     */
    public class UsernamePasswordToken extends org.apache.shiro.authc.UsernamePasswordToken {

        private static final long serialVersionUID = 1L;

        private String captcha;
        private boolean mobileLogin;

        public UsernamePasswordToken() {
            super();
        }

        public UsernamePasswordToken(String username, char[] password,
                boolean rememberMe, String host, String captcha, boolean mobileLogin) {
            super(username, password, rememberMe, host);
            this.captcha = captcha;
            this.mobileLogin = mobileLogin;
        }

        public String getCaptcha() {
            return captcha;
        }

        public void setCaptcha(String captcha) {
            this.captcha = captcha;
        }

        public boolean isMobileLogin() {
            return mobileLogin;
        }

    }
8. views

login.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
        <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>登录</title>
    <link href="${pageContext.request.contextPath}/css/pintuer/pintuer.css" rel="stylesheet" />
    <script type="text/javascript" src="${pageContext.request.contextPath}/js/common/jquery-1.8.3.min.js"></script>
    <script type="text/javascript" src="${pageContext.request.contextPath}/js/common/md5.js"></script>
    <script type="text/javascript" src="${pageContext.request.contextPath}/js/pintuer/pintuer.js"></script>
    </head>
    <body>
        <div class="center x5" align="center">
            <form id="sysUserForm" action="${pageContext.request.contextPath}/login" method="post">
                <span class="message"></span>
                <input class="input" type="text" name="loginName" data-validate="required:必填" placeholder="请输入用户名" />
                <input class="input" type="password" name="password" data-validate="required:必填" placeholder="请输入密码"  />
                <input type="hidden" name="username" id="username">
                <button type="button" onclick="loginVerify()">登录</button>
            </form>
        </div>
        <script type="text/javascript">
            function loginVerify(){
                var loginName = $("input[name=loginName]").val();
                var password = $("input[name=password]").val();
                if (loginName == "") {
                    $(".message").html("<span class='text-red'>用户名不能为空!</span>");
                    return false;
                }
                if (password == "") {
                    $(".message").html("<span class='text-red'>密码不能为空!</span>");
                    return false;
                }
                if (loginName != "" && password != "") {
                    $(".message").html("")
                }
                if (loginName != "") {
                    $("#username").val(loginName);
                }
                if (password != "") {
                // 对密码进行md5加密
                password = hex_md5(password);
                 $("input[name=password]").val(password);
                }
                 var data = $("#sysUserForm").serialize();
                 $.ajax({
                     url : '${pageContext.request.contextPath}' + "/loginVerify",
                     data: {"loginName":loginName,"password":password,"username":username},
                     dataType : 'json',
                     type: 'post',
                     traditional: true,
                     success : function(result){
                         if (result.status == '1') {
                             // 成功
                             $("#sysUserForm").submit();
                         } else {
                             // 失败
                             $(".message").html("<span class='text-red'>密码或用户名错误!</span>")
                         }
                     }
                 })
            }
        </script>
    </body>
    </html>

index.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
     <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>登录</title>
    <script type="text/javascript" src="${pageContext.request.contextPath}/js/common/jquery-3.2.1.min.js"></script>
    <script type="text/javascript" src="${pageContext.request.contextPath}/js/common/md5.js"></script>
    </head>
    <body>
        欢迎您,${name }登录成功!!!!!
        <shiro:hasPermission name="index:edit">${name }可以有权限看到我</shiro:hasPermission>
        <shiro:hasRole name="write">${name } 有写的权限看到我</shiro:hasRole>
        <shiro:hasRole name="read">${name } 有du的权限看到我</shiro:hasRole>
    </body>
    </html>

此项目我只用了一个用户, 如果要设置角色/权限. 可以通过建表,在数据库中查询来获取相应的权限;

注意: 本数据库用户表中存储的密码都是经过md5加密后的密码: 在登录表单验证生成tooken的时候是没有经过加盐处理, 直接通过页面传递的密码经过前台md5加密, 去后台库比对的.

本人用的sys_user 脚本:

    /*
    SQLyog Enterprise v12.09 (64 bit)
    MySQL - 5.6.24-72.2-log 
    *********************************************************************
    */
    /*!40101 SET NAMES utf8 */;

    create table `sys_user` (
        `id` varchar (192),
        `company_id` varchar (192),
        `office_id` varchar (192),
        `login_name` varchar (300),
        `password` varchar (300),
        `no` varchar (300),
        `name` varchar (300),
        `email` varchar (600),
        `phone` varchar (600),
        `mobile` varchar (600),
        `user_type` char (3),
        `photo` varchar (3000),
        `login_ip` varchar (300),
        `login_date` datetime ,
        `login_flag` varchar (192),
        `create_by` varchar (192),
        `create_date` datetime ,
        `update_by` varchar (192),
        `update_date` datetime ,
        `remarks` varchar (765),
        `del_flag` char (3)
    ); 

    eg.
    录入一条数据账户: xzb 密码:xzb
    insert into `sys_user` (`id`, `company_id`, `office_id`, `login_name`, `password`, `no`, `name`, `email`, `phone`, `mobile`, `user_type`, `photo`, `login_ip`, `login_date`, `login_flag`, `create_by`, `create_date`, `update_by`, `update_date`, `remarks`, `del_flag`) values('7e57f36fc1124adea9ed3c354d6d4807','bfe466c9cf38427385e6b009e61abb6d','bfe466c9cf38427385e6b009e61abb6d','xzb','54512b1c7414188441aea85d0f9a6f26',NULL,'小谢',NULL,NULL,NULL,'2',NULL,'10.1.64.140','2018-08-23 11:49:05','1','1','2018-08-10 18:41:01','1','2018-08-23 14:35:30',NULL,'0');

猜你喜欢

转载自blog.csdn.net/qq_34898847/article/details/81983221
今日推荐