SSM 集成 shiro权限 并对用户校验及授权

本文详细介绍了使用Apache Shiro框架进行权限管理的具体实践,包括数据库表设计、Shiro配置、DAO层实现、Controller层测试等内容,展示了如何通过Shiro进行用户登录验证、授权及角色菜单权限管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近更新时间:2019-06-10 15:39

一、准备数据库表

1. 提供四张表,用户表就不提供了。

注:用户表、角色表、用户角色映射表、菜单表、角色菜单映射表。

/*
 Navicat Premium Data Transfer

 Source Server         : localhost
 Source Server Type    : MySQL
 Source Server Version : 50540
 Source Host           : localhost:3306
 Source Schema         : nz

 Target Server Type    : MySQL
 Target Server Version : 50540
 File Encoding         : 65001

 Date: 30/05/2019 18:05:54
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for sys_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role`  (
  `sr_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `sr_key` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '角色编码',
  `sr_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `sr_description` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '描述',
  `sr_value` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '角色名称',
  `sr_grade` int(20) NOT NULL DEFAULT 0 COMMENT '角色等级',
  `sr_del` int(2) NOT NULL DEFAULT 0 COMMENT '是否删除 0 未删除 1 已删除',
  PRIMARY KEY (`sr_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '角色表' ROW_FORMAT = Compact;

INSERT INTO `sys_role` VALUES (1, 'ROLE_USER', '2019-05-30 17:33:09', '', '普通会员', 1, 0);
INSERT INTO `sys_role` VALUES (2, 'ROLE_STYLIST', '2019-05-30 17:33:10', '', '设计师', 2, 0);
INSERT INTO `sys_role` VALUES (3, 'ROLE_ADMIN', '2019-05-30 17:33:11', '', '管理员', 3, 0);
INSERT INTO `sys_role` VALUES (4, 'ROLE_ADMINISTRATOR', '2019-05-30 17:33:11', '', '超级管理员', 4, 0);

-- ----------------------------
-- Table structure for sys_user_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role`  (
  `sur_userid` bigint(20) NOT NULL COMMENT '用户编号',
  `sur_roleid` int(2) NOT NULL DEFAULT 1 COMMENT '角色编号',
  `sur_del` int(2) NOT NULL DEFAULT 0 COMMENT '是否删除 0 未删除 1 已删除',
  PRIMARY KEY (`sur_userid`, `sur_roleid`) USING BTREE,
  INDEX `FKhh52n8vd4ny9ff4x9fb8v65qx`(`sur_roleid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户角色映射表' ROW_FORMAT = Compact;

INSERT INTO `sys_user_role` VALUES (5, 1, 0);
INSERT INTO `sys_user_role` VALUES (160, 1, 0);
INSERT INTO `sys_user_role` VALUES (9, 2, 0);
INSERT INTO `sys_user_role` VALUES (160, 2, 0);
INSERT INTO `sys_user_role` VALUES (160, 3, 0);

-- ----------------------------
-- Table structure for sys_menu
-- ----------------------------
DROP TABLE IF EXISTS `sys_menu`;
CREATE TABLE `sys_menu`  (
  `sm_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `sm_dataurl` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '连接路径或方法',
  `sm_class` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '菜单样式',
  `sm_code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '菜单编码',
  `sm_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '菜单名称',
  `sm_parentcode` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '上级菜单编码',
  `sm_sequence` bigint(20) NULL DEFAULT 0 COMMENT '排序',
  `sm_type` varchar(2) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '1' COMMENT '菜单类型(1是左导航菜单 2是按钮权限)',
  `sm_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `sm_del` int(2) NOT NULL DEFAULT 0 COMMENT '是否删除 0 未删除 1 已删除',
  PRIMARY KEY (`sm_id`) USING BTREE,
  UNIQUE INDEX `uk_sys_authority_menu_code`(`sm_code`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '菜单表' ROW_FORMAT = Compact;

INSERT INTO `sys_menu` VALUES (1, '' ,'', 'indexNavigation', '首页导航', '', 0, '1', '2019-05-30 17:33:09', 0);
INSERT INTO `sys_menu` VALUES (2, 'jd_menu01.jsp', 'index-newIcon1', 'CCTV198301', '菜单01', 'indexNavigation', 0, '1', '2019-05-30 17:33:09', 0);
INSERT INTO `sys_menu` VALUES (3, 'jd_menu02.jsp', 'index-newIcon2', 'CCTV198302', '菜单02', 'indexNavigation', 0, '1', '2019-05-30 17:33:09', 0);
INSERT INTO `sys_menu` VALUES (4, 'jd_menu03.jsp', 'index-newIcon3', 'CCTV198303', '菜单03', 'indexNavigation', 0, '1', '2019-05-30 17:33:09', 0);
INSERT INTO `sys_menu` VALUES (5, 'jd_menu04.jsp', 'index-newIcon4', 'CCTV198304', '菜单04', 'indexNavigation', 0, '1', '2019-05-30 17:33:09', 0);
INSERT INTO `sys_menu` VALUES (6, 'jd_menu05.jsp', 'index-newIcon5', 'CCTV198305', '菜单05', 'indexNavigation', 0, '1', '2019-05-30 17:33:09', 0);
INSERT INTO `sys_menu` VALUES (7, 'jd_menu06.jsp', 'index-newIcon6', 'CCTV198306', '菜单06', 'indexNavigation', 0, '1', '2019-05-30 17:33:09', 0);

-- ----------------------------
-- Table structure for sys_menu_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_menu_role`;
CREATE TABLE `sys_menu_role`  (
  `smr_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键编号自增长',
  `smr_rolekey` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '角色编码',
  `smr_menucode` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '菜单编码',
  `smr_type` varchar(2) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '1' COMMENT '菜单类型 1 导航 2 按钮',
  `smr_disabled` varchar(2) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '0' COMMENT '是否禁用 0 未禁用 1 已禁用',
  `smr_fmenu` varchar(2) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '0' COMMENT '是否顶级菜单 0 否 1 是',
  `smr_del` int(2) NOT NULL DEFAULT 0 COMMENT '是否删除 0 未删除 1 已删除',
  PRIMARY KEY (`smr_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '角色菜单映射表' ROW_FORMAT = Compact;

INSERT INTO `sys_menu_role` VALUES (1, 'ROLE_USER', 'CCTV198301', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (2, 'ROLE_USER', 'CCTV198302', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (3, 'ROLE_USER', 'CCTV198303', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (4, 'ROLE_USER', 'CCTV198304', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (5, 'ROLE_USER', 'CCTV198305', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (6, 'ROLE_USER', 'indexNavigation', 1, 0, 1, 0);

INSERT INTO `sys_menu_role` VALUES (7, 'ROLE_STYLIST', 'CCTV198301', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (8, 'ROLE_STYLIST', 'CCTV198302', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (9, 'ROLE_STYLIST', 'CCTV198303', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (10, 'ROLE_STYLIST', 'CCTV198304', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (11, 'ROLE_STYLIST', 'CCTV198305', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (12, 'ROLE_STYLIST', 'indexNavigation', 1, 0, 1, 0);

INSERT INTO `sys_menu_role` VALUES (13, 'ROLE_ADMIN', 'CCTV198301', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (14, 'ROLE_ADMIN', 'CCTV198302', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (15, 'ROLE_ADMIN', 'CCTV198303', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (16, 'ROLE_ADMIN', 'CCTV198304', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (17, 'ROLE_ADMIN', 'CCTV198305', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (18, 'ROLE_ADMIN', 'indexNavigation', 1, 0, 1, 0);

INSERT INTO `sys_menu_role` VALUES (19, 'ROLE_ADMINISTRATOR', 'CCTV198301', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (20, 'ROLE_ADMINISTRATOR', 'CCTV198302', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (21, 'ROLE_ADMINISTRATOR', 'CCTV198303', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (22, 'ROLE_ADMINISTRATOR', 'CCTV198304', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (23, 'ROLE_ADMINISTRATOR', 'CCTV198305', 1, 0, 0, 0);
INSERT INTO `sys_menu_role` VALUES (24, 'ROLE_ADMINISTRATOR', 'indexNavigation', 1, 0, 1, 0);

SET FOREIGN_KEY_CHECKS = 1;

2. 提供几条sql语句。

# 获得用户最大权限角色
SELECT id, user, passWord, sr_key, sr_value
FROM sys_employee, sys_role, sys_user_role
WHERE id = sur_userid AND sr_id = sur_roleid AND id = 160
ORDER BY sr_id DESC
LIMIT 0, 1;

# 根据父级菜单查询子级查单
SELECT * FROM sys_menu WHERE sm_parentcode = 'indexNavigation';

# 根据用户ID查询用户所属角色的所有的权限
SELECT * FROM sys_menu_role 
	WHERE smr_rolekey = (	
			SELECT sr_key FROM sys_employee, sys_role, sys_user_role WHERE id = sur_userid AND sr_id = sur_roleid AND id = 5 ORDER BY sr_id DESC LIMIT 0, 1
		);
		
# 根据用户ID查询用户所属角色的所有的顶级菜单权限
SELECT * FROM sys_menu
WHERE sm_code IN (
	SELECT smr_menucode FROM sys_menu_role 
	WHERE smr_rolekey = (	
			SELECT sr_key FROM sys_employee, sys_role, sys_user_role WHERE id = sur_userid AND sr_id = sur_roleid AND id = 5 ORDER BY sr_id DESC LIMIT 0, 1
		) AND smr_fmenu = 1
);

# 根据用户ID查询用户所属角色的所有子菜单权限
SELECT * FROM sys_menu
WHERE sm_code IN (
	SELECT smr_menucode FROM sys_menu_role 
	WHERE smr_rolekey = (	
			SELECT sr_key FROM sys_employee, sys_role, sys_user_role WHERE id = sur_userid AND sr_id = sur_roleid AND id = 5 ORDER BY sr_id DESC LIMIT 0, 1
		) AND smr_fmenu = 0
);

二、shiro的配置

1. xml

1.1. pom.xml

<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-all -->
<dependency>
	<groupId>org.apache.shiro</groupId>
	<artifactId>shiro-all</artifactId>
	<version>1.4.1</version>
	<type>pom</type>
</dependency>

1.2. ehcache-shiro.xml

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

    <diskStore path="java.io.tmpdir/ningze-shiro-ehcache"/>

    <!-- 默认缓存 -->
    <defaultCache maxElementsInMemory="1000" eternal="false"
                  overflowToDisk="true" timeToIdleSeconds="300" timeToLiveSeconds="180"
                  diskPersistent="false" diskExpiryThreadIntervalSeconds="120" />

    <!-- 登录记录缓存 -->
    <cache name="passwordRetryCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

    <!-- 授权缓存 -->
    <cache name="authorizationCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

    <!-- 认证缓存 -->
    <cache name="authenticationCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

    <cache name="shiro-activeSessionCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

    <cache name="shiro-kickout-session"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

</ehcache>

1.3. spring-shiro.xml

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


    <!-- 缓存管理器 使用Ehcache实现 -->
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/>
    </bean>

    <!-- 自定义权限认证 -->
    <bean id="shiroSecurityRealm" class="com.rerise.controller.nz.shiro.ShiroSecurityRealm">
        <!-- 设置密码的加密方式 - Sha512 -->
        <property name="credentialsMatcher">
            <bean class="org.apache.shiro.authc.credential.Sha512CredentialsMatcher"/>
        </property>
    </bean>

    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!--认证管理器-->
        <property name="realm" ref="shiroSecurityRealm"/>
        <!-- 缓存管理器 -->
        <property name="cacheManager" ref="cacheManager"/>
        <!-- rememberMe管理器 -->
        <property name="rememberMeManager" ref="rememberMeManager"/>
    </bean>
    <!-- 会话ID生成器 -->
    <bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>

    <!-- 会话Cookie模板 -->
    <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <constructor-arg value="SID"/>
        <!-- 如果设置为true,则客户端不会暴露给服务端脚本代码,有助于减少某些类型的跨站脚本攻击 -->
        <property name="httpOnly" value="true"/>
        <!--<property name="path" value="/" />-->
        <!-- 配置存储Session Cookie的cmkn为 一级域名 -->
        <!--<property name="domain" value=".cmkn.cn"/>-->
        <property name="maxAge" value="-1"/><!-- maxAge=-1表示浏览器关闭时失效此Cookie -->
    </bean>

    <!--手动指定cookie-->
    <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <constructor-arg value="rememberMe"/>
        <property name="httpOnly" value="true"/>
        <!-- JSESSIONID的path为/用于多个系统共享JSESSIONID -->
        <property name="path" value="/"/>
        <!-- 配置存储rememberMe Cookie的cmkn为 一级域名 -->
        <!--<property name="domain" value=".cmkn.cn"/>-->
        <property name="maxAge" value="604800"/><!-- 7天604800 -->
        <property name="name" value="rememberMe"/>
    </bean>
    <!-- rememberMe管理器 -->
    <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
        <property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('7gzYfKjTASKdsai43ds==')}"/>
        <property name="cookie" ref="rememberMeCookie"/>
    </bean>

    <!-- 会话DAO -->
    <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
        <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/>
        <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
    </bean>
    <!-- 会话验证调度器 -->
    <bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">
        <property name="sessionValidationInterval" value="3000000"/>
        <property name="sessionManager" ref="sessionManager"/>
    </bean>

    <!-- 会话管理器 -->
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <property name="globalSessionTimeout" value="3000000"/>
        <property name="deleteInvalidSessions" value="true"/>
        <property name="sessionValidationSchedulerEnabled" value="true"/>
        <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
        <property name="sessionDAO" ref="sessionDAO"/>
        <property name="sessionIdCookieEnabled" value="true"/>
        <property name="sessionIdCookie" ref="sessionIdCookie"/>
    </bean>

    <!-- 基于Form表单的身份验证过滤器 -->
    <bean id="formAuthenticationFilter" class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
        <property name="usernameParam" value="username"/>
        <property name="passwordParam" value="password"/>
        <property name="rememberMeParam" value="rememberMe"/>
        <property name="loginUrl" value="/userLB/jd_login_do"/>
        <property name="successUrl" value="/jd_index.jsp"/>
    </bean>

    <!-- 自定义用户过滤器 -->
    <bean id="sysUserFilter" class="com.rerise.controller.nz.shiro.SysUserFilter"/>

    <!--Shiro的Web过滤器-->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- Shiro的安全管理器,所有关于安全的操作都会经过SecurityManager -->
        <property name="securityManager" ref="securityManager"/>
        <!-- 系统认证提交地址,如果用户退出即session丢失就会访问这个页面 -->
        <property name="loginUrl" value="/userLB/jd_login_do"/>
        <!-- 系统认证成功跳转地址 -->
        <property name="successUrl" value="/jd_index.jsp"/>
        <!-- 权限验证失败跳转的页面,需要配合Spring的ExceptionHandler异常处理机制使用 -->
        <property name="unauthorizedUrl" value="/errors/500.html"/>
        <property name="filters">
            <util:map>
                <entry key="authc">
                    <bean class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter"/>
                </entry>
                <entry key="sysUser" value-ref="sysUserFilter"/>
            </util:map>
        </property>
        <property name="filterChainDefinitions">
            <value>
                <!-- 静态资源不拦截 -->
                /js/** = anon
                /assets/** = anon
                /css/** = anon
                /upload/** = anon
                <!-- 登录页面不拦截 -->
                /userLB/jd_login_do = anon

                <!-- Shiro提供了退出登录的配置`logout`,会生成路径为`/logout`的请求地址,访问这个地址即会退出当前账户并清空缓存 -->
                /logout = authc
                /userLB/exit = authc

                <!-- user表示身份通过或通过记住我通过的用户都能访问系统 -->
                <!-- /index.jsp = user -->
                <!-- 表示访问该地址用户必须身份验证通过或RememberMe登录的都可以 -->
                <!-- /** = authc -->
            </value>
        </property>
    </bean>

    <!--用aop的方式实现shiro注解-->
    <aop:config proxy-target-class="true"/>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>

    <!-- Post processor that automatically invokes init() and destroy() methods -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

</beans>

1.4. web.xml

<!-- 加载xml文件 -->
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath:spring-shiro.xml</param-value>
</context-param>
<!-- 监听上下文 -->
<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- shiro 安全过滤器 -->
<filter>
	<filter-name>shiroFilter</filter-name>
	<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
	<async-supported>true</async-supported>
	<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>

2. dao

2.1. SysRoleDao.java

package com.rerise.dao.nz;

import com.rerise.pojo.nz.SysRole;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * 角色表(SysRole)表数据库访问层
 *
 * @author xlm
 * @since 2019-06-06 14:38:58
 */
@Service
public interface SysRoleDao {

    /**
     * 通过ID查询单条数据
     *
     * @param srId 主键
     * @return 实例对象
     */
    @Select(" SELECT " +
              " sr_id, sr_key, sr_time, sr_description, sr_value, sr_grade, sr_del " +
            " FROM cloudclass.sys_role " +
            " WHERE sr_id = #{srId} "
    )
    @Results({
            @Result(property = "srId", column = "sr_id"),
            @Result(property = "srKey", column = "sr_key"),
            @Result(property = "srTime", column = "sr_time"),
            @Result(property = "srDescription", column = "sr_description"),
            @Result(property = "srValue", column = "sr_value"),
            @Result(property = "srGrade", column = "sr_grade"),
            @Result(property = "srDel", column = "sr_del"),
    })
    SysRole findById(Integer srId);
    
    /**
     * 通过ID查询单条数据
     *
     * @param srId 主键
     * @return Map对象
     */
    @Select(" SELECT " +
              " sr_id, sr_key, sr_time, sr_description, sr_value, sr_grade, sr_del " +
            " FROM cloudclass.sys_role " +
            " WHERE sr_id = #{srId} "
    )
    @Results({
            @Result(property = "srId", column = "sr_id"),
            @Result(property = "srKey", column = "sr_key"),
            @Result(property = "srTime", column = "sr_time"),
            @Result(property = "srDescription", column = "sr_description"),
            @Result(property = "srValue", column = "sr_value"),
            @Result(property = "srGrade", column = "sr_grade"),
            @Result(property = "srDel", column = "sr_del"),
    })
    Map<String,Object> findByIdMap(Integer srId);

    /**
     * 查询指定行数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    @Select(" SELECT " +
              " sr_id, sr_key, sr_time, sr_description, sr_value, sr_grade, sr_del " +
            " FROM cloudclass.sys_role " +
            " LIMIT #{offset}, #{limit} "
    )
    @Results({
            @Result(property = "srId", column = "sr_id"),
            @Result(property = "srKey", column = "sr_key"),
            @Result(property = "srTime", column = "sr_time"),
            @Result(property = "srDescription", column = "sr_description"),
            @Result(property = "srValue", column = "sr_value"),
            @Result(property = "srGrade", column = "sr_grade"),
            @Result(property = "srDel", column = "sr_del"),
    })
    List<SysRole> findAllByLimit(@Param("offset") int offset, @Param("limit") int limit);


    /**
     * 通过实体作为筛选条件查询
     *
     * @param sysRole 实例对象
     * @return 对象列表
     */
    @Select("<script> " +
            " SELECT " +
              " sr_id, sr_key, sr_time, sr_description, sr_value, sr_grade, sr_del " +
            " FROM cloudclass.sys_role " +
            " WHERE 1=1 " +
              " <if test='srId != null'> " +
                    " AND sr_id = #{srId} " +
              " </if> " +
              " <if test='srKey != null and srKey != \"\"'> " +
                    " AND sr_key = #{srKey} " +
              " </if> " +
              " <if test='srTime != null and srTime != \"\"'> " +
                    " AND sr_time = #{srTime} " +
              " </if> " +
              " <if test='srDescription != null and srDescription != \"\"'> " +
                    " AND sr_description = #{srDescription} " +
              " </if> " +
              " <if test='srValue != null and srValue != \"\"'> " +
                    " AND sr_value = #{srValue} " +
              " </if> " +
              " <if test='srGrade != null'> " +
                    " AND sr_grade = #{srGrade} " +
              " </if> " +
              " <if test='srDel != null'> " +
                    " AND sr_del = #{srDel} " +
              " </if> " +
            " </script>"
    )
    @Results({
            @Result(property = "srId", column = "sr_id"),
            @Result(property = "srKey", column = "sr_key"),
            @Result(property = "srTime", column = "sr_time"),
            @Result(property = "srDescription", column = "sr_description"),
            @Result(property = "srValue", column = "sr_value"),
            @Result(property = "srGrade", column = "sr_grade"),
            @Result(property = "srDel", column = "sr_del"),
    })
    List<SysRole> findAll(SysRole sysRole);

    /**
     * 新增数据
     *
     * @param sysRole 实例对象
     * @return 影响行数
     */
    @Insert(" INSERT INTO cloudclass.sys_role(sr_key, sr_time, sr_description, sr_value, sr_grade, sr_del) " +
            " VALUES (#{srKey}, #{srTime}, #{srDescription}, #{srValue}, #{srGrade}, #{srDel}) "
    )
    Integer insert(SysRole sysRole);

    /**
     * 修改数据
     *
     * @param sysRole 实例对象
     * @return 影响行数
     */
    @Update("<script> " +
            " UPDATE cloudclass.sys_role " +
            " SET " +
                " <if test='srKey != null and srKey != \"\"'> " +
                    " sr_key = #{srKey}," +
                " </if> " +
                " <if test='srTime != null and srTime != \"\"'> " +
                    " sr_time = #{srTime}," +
                " </if> " +
                " <if test='srDescription != null and srDescription != \"\"'> " +
                    " sr_description = #{srDescription}," +
                " </if> " +
                " <if test='srValue != null and srValue != \"\"'> " +
                    " sr_value = #{srValue}," +
                " </if> " +
                " <if test='srGrade != null'> " +
                    " sr_grade = #{srGrade}," +
                " </if> " +
                " <if test='srDel != null'> " +
                    " sr_del = #{srDel}," +
                " </if> " +
            " WHERE sr_id = #{srId}" +
            " </script>"
    )
    Integer update(SysRole sysRole);

    /**
     * 通过主键删除数据
     *
     * @param srId 主键
     * @return 影响行数
     */
    @Delete(" DELETE FROM cloudclass.sys_role WHERE sr_id = #{srId} ")
    Integer deleteById(Integer srId);

}

2.2. SysUserRoleDao.java

package com.rerise.dao.nz;

import com.rerise.pojo.nz.SysUserRole;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * 用户角色映射表(SysUserRole)表数据库访问层
 *
 * @author xlm
 * @since 2019-06-06 14:38:58
 */
@Service
public interface SysUserRoleDao {

    /**
     * 通过ID查询单条数据
     *
     * @param surUserid 主键
     * @return 实例对象
     */
    @Select(" SELECT " +
              " sur_userid, sur_roleid, sur_del " +
            " FROM cloudclass.sys_user_role " +
            " WHERE sur_userid = #{surUserid} "
    )
    @Results({
            @Result(property = "surUserid", column = "sur_userid"),
            @Result(property = "surRoleid", column = "sur_roleid"),
            @Result(property = "surDel", column = "sur_del"),
    })
    SysUserRole findById(Long surUserid);
    
    /**
     * 通过ID查询单条数据
     *
     * @param surUserid 主键
     * @return Map对象
     */
    @Select(" SELECT " +
              " sur_userid, sur_roleid, sur_del " +
            " FROM cloudclass.sys_user_role " +
            " WHERE sur_userid = #{surUserid} "
    )
    @Results({
            @Result(property = "surUserid", column = "sur_userid"),
            @Result(property = "surRoleid", column = "sur_roleid"),
            @Result(property = "surDel", column = "sur_del"),
    })
    Map<String,Object> findByIdMap(Long surUserid);

    /**
     * 查询指定行数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    @Select(" SELECT " +
              " sur_userid, sur_roleid, sur_del " +
            " FROM cloudclass.sys_user_role " +
            " LIMIT #{offset}, #{limit} "
    )
    @Results({
            @Result(property = "surUserid", column = "sur_userid"),
            @Result(property = "surRoleid", column = "sur_roleid"),
            @Result(property = "surDel", column = "sur_del"),
    })
    List<SysUserRole> findAllByLimit(@Param("offset") int offset, @Param("limit") int limit);


    /**
     * 通过实体作为筛选条件查询
     *
     * @param sysUserRole 实例对象
     * @return 对象列表
     */
    @Select("<script> " +
            " SELECT " +
              " sur_userid, sur_roleid, sur_del " +
            " FROM cloudclass.sys_user_role " +
            " WHERE 1=1 " +
              " <if test='surUserid != null'> " +
                    " AND sur_userid = #{surUserid} " +
              " </if> " +
              " <if test='surRoleid != null'> " +
                    " AND sur_roleid = #{surRoleid} " +
              " </if> " +
              " <if test='surDel != null'> " +
                    " AND sur_del = #{surDel} " +
              " </if> " +
            " </script>"
    )
    @Results({
            @Result(property = "surUserid", column = "sur_userid"),
            @Result(property = "surRoleid", column = "sur_roleid"),
            @Result(property = "surDel", column = "sur_del"),
    })
    List<SysUserRole> findAll(SysUserRole sysUserRole);

    /**
     * 新增数据
     *
     * @param sysUserRole 实例对象
     * @return 影响行数
     */
    @Insert(" INSERT INTO cloudclass.sys_user_role(sur_del) " +
            " VALUES (#{surDel}) "
    )
    Integer insert(SysUserRole sysUserRole);

    /**
     * 修改数据
     *
     * @param sysUserRole 实例对象
     * @return 影响行数
     */
    @Update("<script> " +
            " UPDATE cloudclass.sys_user_role " +
            " SET " +
                " <if test='surDel != null'> " +
                    " sur_del = #{surDel}," +
                " </if> " +
            " WHERE sur_userid = #{surUserid}" +
            " </script>"
    )
    Integer update(SysUserRole sysUserRole);

    /**
     * 通过主键删除数据
     *
     * @param surUserid 主键
     * @return 影响行数
     */
    @Delete(" DELETE FROM cloudclass.sys_user_role WHERE sur_userid = #{surUserid} ")
    Integer deleteById(Long surUserid);

}

2.3. SysMenuDao.java

package com.rerise.dao.nz;

import com.rerise.pojo.nz.SysMenu;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * 菜单表(SysMenu)表数据库访问层
 *
 * @author xlm
 * @since 2019-06-06 14:38:58
 */
@Service
public interface SysMenuDao {

    /**
     * 通过ID查询单条数据
     *
     * @param smId 主键
     * @return 实例对象
     */
    @Select(" SELECT " +
            " sm_id, sm_dataurl, sm_class, sm_code, sm_name, sm_parentcode, sm_sequence, sm_type, sm_time, sm_del " +
            " FROM cloudclass.sys_menu " +
            " WHERE sm_id = #{smId} "
    )
    @Results({
            @Result(property = "smId", column = "sm_id"),
            @Result(property = "smDataurl", column = "sm_dataurl"),
            @Result(property = "smClass", column = "sm_class"),
            @Result(property = "smCode", column = "sm_code"),
            @Result(property = "smName", column = "sm_name"),
            @Result(property = "smParentcode", column = "sm_parentcode"),
            @Result(property = "smSequence", column = "sm_sequence"),
            @Result(property = "smType", column = "sm_type"),
            @Result(property = "smTime", column = "sm_time"),
            @Result(property = "smDel", column = "sm_del"),
    })
    SysMenu findById(Long smId);

    /**
     * 通过 smParentcode 查询子菜单数据
     *
     * @param smParentcode 父级菜单code
     * @return 实例对象
     */
    @Select(" SELECT " +
            " sm_id, sm_dataurl, sm_class, sm_code, sm_name, sm_parentcode, sm_sequence, sm_type, sm_time, sm_del " +
            " FROM cloudclass.sys_menu " +
            " WHERE sm_parentcode = #{smParentcode} AND sm_del = 0 "
    )
    @Results({
            @Result(property = "smId", column = "sm_id"),
            @Result(property = "smDataurl", column = "sm_dataurl"),
            @Result(property = "smClass", column = "sm_class"),
            @Result(property = "smCode", column = "sm_code"),
            @Result(property = "smName", column = "sm_name"),
            @Result(property = "smParentcode", column = "sm_parentcode"),
            @Result(property = "smSequence", column = "sm_sequence"),
            @Result(property = "smType", column = "sm_type"),
            @Result(property = "smTime", column = "sm_time"),
            @Result(property = "smDel", column = "sm_del"),
    })
    List<SysMenu> findBySmParentcode(String smParentcode);

    /**
     * 通过ID查询单条数据
     *
     * @param smId 主键
     * @return Map对象
     */
    @Select(" SELECT " +
            " sm_id, sm_dataurl, sm_class, sm_code, sm_name, sm_parentcode, sm_sequence, sm_type, sm_time, sm_del " +
            " FROM cloudclass.sys_menu " +
            " WHERE sm_id = #{smId} "
    )
    @Results({
            @Result(property = "smId", column = "sm_id"),
            @Result(property = "smDataurl", column = "sm_dataurl"),
            @Result(property = "smClass", column = "sm_class"),
            @Result(property = "smCode", column = "sm_code"),
            @Result(property = "smName", column = "sm_name"),
            @Result(property = "smParentcode", column = "sm_parentcode"),
            @Result(property = "smSequence", column = "sm_sequence"),
            @Result(property = "smType", column = "sm_type"),
            @Result(property = "smTime", column = "sm_time"),
            @Result(property = "smDel", column = "sm_del"),
    })
    Map<String, Object> findByIdMap(Long smId);

    /**
     * 查询指定行数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Select(" SELECT " +
            " sm_id, sm_dataurl, sm_class, sm_code, sm_name, sm_parentcode, sm_sequence, sm_type, sm_time, sm_del " +
            " FROM cloudclass.sys_menu " +
            " LIMIT #{offset}, #{limit} "
    )
    @Results({
            @Result(property = "smId", column = "sm_id"),
            @Result(property = "smDataurl", column = "sm_dataurl"),
            @Result(property = "smClass", column = "sm_class"),
            @Result(property = "smCode", column = "sm_code"),
            @Result(property = "smName", column = "sm_name"),
            @Result(property = "smParentcode", column = "sm_parentcode"),
            @Result(property = "smSequence", column = "sm_sequence"),
            @Result(property = "smType", column = "sm_type"),
            @Result(property = "smTime", column = "sm_time"),
            @Result(property = "smDel", column = "sm_del"),
    })
    List<SysMenu> findAllByLimit(@Param("offset") int offset, @Param("limit") int limit);


    /**
     * 通过实体作为筛选条件查询
     *
     * @param sysMenu 实例对象
     * @return 对象列表
     */
    @Select("<script> " +
            " SELECT " +
            " sm_id, sm_dataurl, sm_class, sm_code, sm_name, sm_parentcode, sm_sequence, sm_type, sm_time, sm_del " +
            " FROM cloudclass.sys_menu " +
            " WHERE 1=1 " +
            " <if test='smId != null'> " +
            " AND sm_id = #{smId} " +
            " </if> " +
            " <if test='smDataurl != null and smDataurl != \"\"'> " +
            " AND sm_dataurl = #{smDataurl} " +
            " </if> " +
            " <if test='smClass != null and smClass != \"\"'> " +
            " AND sm_class = #{smClass} " +
            " </if> " +
            " <if test='smCode != null and smCode != \"\"'> " +
            " AND sm_code = #{smCode} " +
            " </if> " +
            " <if test='smName != null and smName != \"\"'> " +
            " AND sm_name = #{smName} " +
            " </if> " +
            " <if test='smParentcode != null and smParentcode != \"\"'> " +
            " AND sm_parentcode = #{smParentcode} " +
            " </if> " +
            " <if test='smSequence != null'> " +
            " AND sm_sequence = #{smSequence} " +
            " </if> " +
            " <if test='smType != null and smType != \"\"'> " +
            " AND sm_type = #{smType} " +
            " </if> " +
            " <if test='smTime != null and smTime != \"\"'> " +
            " AND sm_time = #{smTime} " +
            " </if> " +
            " <if test='smDel != null'> " +
            " AND sm_del = #{smDel} " +
            " </if> " +
            " </script>"
    )
    @Results({
            @Result(property = "smId", column = "sm_id"),
            @Result(property = "smDataurl", column = "sm_dataurl"),
            @Result(property = "smClass", column = "sm_class"),
            @Result(property = "smCode", column = "sm_code"),
            @Result(property = "smName", column = "sm_name"),
            @Result(property = "smParentcode", column = "sm_parentcode"),
            @Result(property = "smSequence", column = "sm_sequence"),
            @Result(property = "smType", column = "sm_type"),
            @Result(property = "smTime", column = "sm_time"),
            @Result(property = "smDel", column = "sm_del"),
    })
    List<SysMenu> findAll(SysMenu sysMenu);

    /**
     * 新增数据
     *
     * @param sysMenu 实例对象
     * @return 影响行数
     */
    @Insert(" INSERT INTO cloudclass.sys_menu(sm_dataurl, sm_class, sm_code, sm_name, sm_parentcode, sm_sequence, sm_type, sm_time, sm_del) " +
            " VALUES (#{smDataurl}, #{smClass}, #{smCode}, #{smName}, #{smParentcode}, #{smSequence}, #{smType}, #{smTime}, #{smDel}) "
    )
    Integer insert(SysMenu sysMenu);

    /**
     * 修改数据
     *
     * @param sysMenu 实例对象
     * @return 影响行数
     */
    @Update("<script> " +
            " UPDATE cloudclass.sys_menu " +
            " SET " +
            " <if test='smDataurl != null and smDataurl != \"\"'> " +
            " sm_dataurl = #{smDataurl}," +
            " </if> " +
            " <if test='smClass != null and smClass != \"\"'> " +
            " sm_class = #{smClass}," +
            " </if> " +
            " <if test='smCode != null and smCode != \"\"'> " +
            " sm_code = #{smCode}," +
            " </if> " +
            " <if test='smName != null and smName != \"\"'> " +
            " sm_name = #{smName}," +
            " </if> " +
            " <if test='smParentcode != null and smParentcode != \"\"'> " +
            " sm_parentcode = #{smParentcode}," +
            " </if> " +
            " <if test='smSequence != null'> " +
            " sm_sequence = #{smSequence}," +
            " </if> " +
            " <if test='smType != null and smType != \"\"'> " +
            " sm_type = #{smType}," +
            " </if> " +
            " <if test='smTime != null and smTime != \"\"'> " +
            " sm_time = #{smTime}," +
            " </if> " +
            " <if test='smDel != null'> " +
            " sm_del = #{smDel}," +
            " </if> " +
            " WHERE sm_id = #{smId}" +
            " </script>"
    )
    Integer update(SysMenu sysMenu);

    /**
     * 通过主键删除数据
     *
     * @param smId 主键
     * @return 影响行数
     */
    @Delete(" DELETE FROM cloudclass.sys_menu WHERE sm_id = #{smId} ")
    Integer deleteById(Long smId);

}

2.4. SysMenuRoleDao.java

package com.rerise.dao.nz;

import com.rerise.pojo.nz.SysMenuRole;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * 角色菜单映射表(SysMenuRole)表数据库访问层
 *
 * @author xlm
 * @since 2019-06-06 14:38:58
 */
@Service
public interface SysMenuRoleDao {

    /**
     * 通过ID查询单条数据
     *
     * @param smrId 主键
     * @return 实例对象
     */
    @Select(" SELECT " +
              " smr_id, smr_rolekey, smr_menucode, smr_type, smr_disabled, smr_fmenu, smr_del " +
            " FROM cloudclass.sys_menu_role " +
            " WHERE smr_id = #{smrId} "
    )
    @Results({
            @Result(property = "smrId", column = "smr_id"),
            @Result(property = "smrRolekey", column = "smr_rolekey"),
            @Result(property = "smrMenucode", column = "smr_menucode"),
            @Result(property = "smrType", column = "smr_type"),
            @Result(property = "smrDisabled", column = "smr_disabled"),
            @Result(property = "smrFmenu", column = "smr_fmenu"),
            @Result(property = "smrDel", column = "smr_del"),
    })
    SysMenuRole findById(Long smrId);
    
    /**
     * 通过ID查询单条数据
     *
     * @param smrId 主键
     * @return Map对象
     */
    @Select(" SELECT " +
              " smr_id, smr_rolekey, smr_menucode, smr_type, smr_disabled, smr_fmenu, smr_del " +
            " FROM cloudclass.sys_menu_role " +
            " WHERE smr_id = #{smrId} "
    )
    @Results({
            @Result(property = "smrId", column = "smr_id"),
            @Result(property = "smrRolekey", column = "smr_rolekey"),
            @Result(property = "smrMenucode", column = "smr_menucode"),
            @Result(property = "smrType", column = "smr_type"),
            @Result(property = "smrDisabled", column = "smr_disabled"),
            @Result(property = "smrFmenu", column = "smr_fmenu"),
            @Result(property = "smrDel", column = "smr_del"),
    })
    Map<String,Object> findByIdMap(Long smrId);

    /**
     * 查询指定行数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    @Select(" SELECT " +
              " smr_id, smr_rolekey, smr_menucode, smr_type, smr_disabled, smr_fmenu, smr_del " +
            " FROM cloudclass.sys_menu_role " +
            " LIMIT #{offset}, #{limit} "
    )
    @Results({
            @Result(property = "smrId", column = "smr_id"),
            @Result(property = "smrRolekey", column = "smr_rolekey"),
            @Result(property = "smrMenucode", column = "smr_menucode"),
            @Result(property = "smrType", column = "smr_type"),
            @Result(property = "smrDisabled", column = "smr_disabled"),
            @Result(property = "smrFmenu", column = "smr_fmenu"),
            @Result(property = "smrDel", column = "smr_del"),
    })
    List<SysMenuRole> findAllByLimit(@Param("offset") int offset, @Param("limit") int limit);


    /**
     * 通过实体作为筛选条件查询
     *
     * @param sysMenuRole 实例对象
     * @return 对象列表
     */
    @Select("<script> " +
            " SELECT " +
              " smr_id, smr_rolekey, smr_menucode, smr_type, smr_disabled, smr_fmenu, smr_del " +
            " FROM cloudclass.sys_menu_role " +
            " WHERE 1=1 " +
              " <if test='smrId != null'> " +
                    " AND smr_id = #{smrId} " +
              " </if> " +
              " <if test='smrRolekey != null and smrRolekey != \"\"'> " +
                    " AND smr_rolekey = #{smrRolekey} " +
              " </if> " +
              " <if test='smrMenucode != null and smrMenucode != \"\"'> " +
                    " AND smr_menucode = #{smrMenucode} " +
              " </if> " +
              " <if test='smrType != null and smrType != \"\"'> " +
                    " AND smr_type = #{smrType} " +
              " </if> " +
              " <if test='smrDisabled != null and smrDisabled != \"\"'> " +
                    " AND smr_disabled = #{smrDisabled} " +
              " </if> " +
              " <if test='smrFmenu != null and smrFmenu != \"\"'> " +
                    " AND smr_fmenu = #{smrFmenu} " +
              " </if> " +
              " <if test='smrDel != null'> " +
                    " AND smr_del = #{smrDel} " +
              " </if> " +
            " </script>"
    )
    @Results({
            @Result(property = "smrId", column = "smr_id"),
            @Result(property = "smrRolekey", column = "smr_rolekey"),
            @Result(property = "smrMenucode", column = "smr_menucode"),
            @Result(property = "smrType", column = "smr_type"),
            @Result(property = "smrDisabled", column = "smr_disabled"),
            @Result(property = "smrFmenu", column = "smr_fmenu"),
            @Result(property = "smrDel", column = "smr_del"),
    })
    List<SysMenuRole> findAll(SysMenuRole sysMenuRole);

    /**
     * 新增数据
     *
     * @param sysMenuRole 实例对象
     * @return 影响行数
     */
    @Insert(" INSERT INTO cloudclass.sys_menu_role(smr_rolekey, smr_menucode, smr_type, smr_disabled, smr_fmenu, smr_del) " +
            " VALUES (#{smrRolekey}, #{smrMenucode}, #{smrType}, #{smrDisabled}, #{smrFmenu}, #{smrDel}) "
    )
    Integer insert(SysMenuRole sysMenuRole);

    /**
     * 修改数据
     *
     * @param sysMenuRole 实例对象
     * @return 影响行数
     */
    @Update("<script> " +
            " UPDATE cloudclass.sys_menu_role " +
            " SET " +
                " <if test='smrRolekey != null and smrRolekey != \"\"'> " +
                    " smr_rolekey = #{smrRolekey}," +
                " </if> " +
                " <if test='smrMenucode != null and smrMenucode != \"\"'> " +
                    " smr_menucode = #{smrMenucode}," +
                " </if> " +
                " <if test='smrType != null and smrType != \"\"'> " +
                    " smr_type = #{smrType}," +
                " </if> " +
                " <if test='smrDisabled != null and smrDisabled != \"\"'> " +
                    " smr_disabled = #{smrDisabled}," +
                " </if> " +
                " <if test='smrFmenu != null and smrFmenu != \"\"'> " +
                    " smr_fmenu = #{smrFmenu}," +
                " </if> " +
                " <if test='smrDel != null'> " +
                    " smr_del = #{smrDel}," +
                " </if> " +
            " WHERE smr_id = #{smrId}" +
            " </script>"
    )
    Integer update(SysMenuRole sysMenuRole);

    /**
     * 通过主键删除数据
     *
     * @param smrId 主键
     * @return 影响行数
     */
    @Delete(" DELETE FROM cloudclass.sys_menu_role WHERE smr_id = #{smrId} ")
    Integer deleteById(Long smrId);

}

2.5. SysUserManageDao.java

package com.rerise.dao.nz;

import com.rerise.pojo.nz.SysMenu;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;

import java.util.List;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 *
 * @author NingZe
 * @description: 用户权限管理 - 数据层
 * @path: DecoSearch-manage-com.rerise.dao.nz-SysUserManageDao
 * @date: 2019/6/6 0006 15:03
 * @version: 02.06
 * To change this template use File | Settings | File Templates.
 */
public interface SysUserManageDao {

    /**
     * 根据用户ID添加默认角色 - 普通用户
     *
     * @param userID
     * @return
     */
    @Insert(" INSERT INTO sys_user_role(sur_userid) VALUES (#{userID}); ")
    Integer addRole(Integer userID);

    /**
     * 根据用户ID获得用户所有角色
     *
     * @param userID
     * @return
     */
    @Select(" SELECT sr_key, sr_value " +
            " FROM df_employee, sys_role, sys_user_role " +
            " WHERE id = sur_userid AND sr_id = sur_roleid AND id = #{userID} AND sr_del = 0 " +
            " ORDER BY sr_grade DESC "
    )
    @Results({
            @Result(property = "KEY", column = "sr_key"),
            @Result(property = "VAL", column = "sr_value")
    })
    List<Map<String, String>> findUserRoles(Integer userID);

    /**
     * 根据角色编号获得角色所有的菜单 - 菜单格式为 / 父子菜单
     *
     * @param smCode 角色编号
     * @return
     */
    @Select("<script>" +
            " SELECT " +
            " sm_id, sm_dataurl, sm_class, sm_code, sm_name, sm_parentcode, sm_sequence, sm_type, sm_time, sm_del " +
            " FROM sys_menu " +
            " WHERE sm_code IN ( SELECT smr_menucode FROM sys_menu_role WHERE smr_rolekey = #{smCode} AND smr_fmenu = 1 AND smr_del = 0 ) AND sm_del = 0 " +
            "</script>"
    )
    @Results({
            @Result(property = "smId", column = "sm_id"),
            @Result(property = "smDataurl", column = "sm_dataurl"),
            @Result(property = "smClass", column = "sm_class"),
            @Result(property = "smCode", column = "sm_code"),
            @Result(property = "smName", column = "sm_name"),
            @Result(property = "smParentcode", column = "sm_parentcode"),
            @Result(property = "smSequence", column = "sm_sequence"),
            @Result(property = "smType", column = "sm_type"),
            @Result(property = "smTime", column = "sm_time"),
            @Result(property = "smDel", column = "sm_del"),
            @Result(column="sm_code",property="sysMenuList",many=@Many(select="com.rerise.dao.nz.SysMenuDao.findBySmParentcode",fetchType= FetchType.EAGER))
    })
    List<SysMenu> findUserMenus(String smCode);

}

3. controller

3.1. SysUserFilter.java

package com.rerise.controller.nz.shiro;

import org.apache.shiro.web.filter.PathMatchingFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * Created by IntelliJ IDEA.
 *
 * @author NingZe
 * @description: 自定义用户过滤器
 * @path: DecoSearch-manage-com.rerise.controller.nz.shiro-SysUserFilter
 * @date: 2019/5/31 0031 11:12
 * @version: 02.06
 * To change this template use File | Settings | File Templates.
 */
public class SysUserFilter extends PathMatchingFilter {

    @Override
    protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) {
        //可以参考http://jinnianshilongnian.iteye.com/blog/2025656
        return true;
    }
}

3.2. ShiroSecurityRealm.java

package com.rerise.controller.nz.shiro;

import com.rerise.dao.nz.SysUserManageDao;
import com.rerise.pojo.nz.SysMenu;
import com.rerise.pojo.sys.DfUserLB;
import com.rerise.service.sys.UserLBService;
import com.rerise.tool.IXlmToolKit;
import com.rerise.tool.impl.XlmToolKit;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Sha512Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 *
 * @author NingZe
 * description: 登录/权限认证
 * path: DecoSearch-manage-com.rerise.controller.nz.shiro-ShiroSecurityRealm
 * date: 2019/5/31 0031 11:31
 * version: 02.06
 * To change this template use File | Settings | File Templates.
 */
public class ShiroSecurityRealm extends AuthorizingRealm {

    /**
     * 用户
     */
    @Autowired
    private UserLBService uhs;

    /**
     * 用户权限管理
     */
    @Autowired
    private SysUserManageDao sumd;

    /**
     * log4j 日志
     */
    private final static Logger log = LogManager.getLogger(ShiroSecurityRealm.class);

    /**
     * 工具类
     */
    private IXlmToolKit kit = new XlmToolKit();

    /**
     * 用户校验
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {

        // 存放用户登录信息
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;

        // 根据用户名查询用户信息
        // 注:这里是通过用户名去查找的信息,因为shiro的SimpleAuthenticationInfo会帮我们校验一次。返回结果的话 1.可以是密码 2.也可以是对象 - 这边采用的是对象,后面会用到用户的信息。
        // ① 如果通过账户去查的话,我们可以得到两种状态 1. 账户存在 2.账户不存在。然后我们通过查询返回的密码与表单的密码对比,即可得到 1. 密码正确 2. 密码错误。
        // ② 如果通过账户与密码去查的话,只会有两个不确定的答案 1. true 2. false。为false的话,咋也不知道是帐号还是密码错误,咋也不敢问,它也不会说。
        DfUserLB user = uhs.findUserNZ(token.getUsername());
        // 判断用户是否存在
        if (user != null) {
            // 判断用户是否锁定
            if (user.getLockEmp() == 1) {
                // 账户已被锁定
                throw new LockedAccountException();
            }
            // 获得密码并加密并set到对象中 - xml 配置了什么加密,那我们必须使用那种加密方式,否则shiro比对时会出现 IncorrectCredentialsException 异常
            // org.apache.shiro.authc.IncorrectCredentialsException: Submitted credentials for token [org.apache.shiro.authc.UsernamePasswordToken - ningze, rememberMe=false] did not match the expected credentials.
            user.setPassWord(new Sha512Hash(user.getPassWord()).toHex());
            // 交给AuthenticationRealm使用CredentialsMatcher进行密码匹配
            // 参数一: 期望登陆后,保存在subject中的信息 user
            // 参数二: 密码, Shiro会为我们进行密码对比校验
            // 参数三: realm名称
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassWord(), getName());
            // 获得手机号
            String str = user.getPhone();
            // 判断手机号是否为空
            if (kit.isStrNull(str)) {
                // 将手机号中部以*号代替,并设置到用户对象中
                user.setPhone(str.substring(0, 3) + "****" + str.substring(7, 11));
            }
            return info;
        }
        // 账户不存在
        throw new UnknownAccountException();
    }


    /**
     * 用户授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        // 存放用户授权信息
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        // 获得shiro保存在session中用户的信息
        DfUserLB user = (DfUserLB) principals.getPrimaryPrincipal();

        // 存放用户ID
        int userID = user.getId();

        // 获得用户所有角色
        List<Map<String, String>> userRoles = sumd.findUserRoles(userID);

        // 用户无角色 - 添加默认普通用户角色
        if (!kit.isListNull(userRoles)) {
            // 添加角色
            int status = sumd.addRole(userID);
            // 判断是否执行成功
            if (status > 0) {
                // 获得用户所有角色
                userRoles = sumd.findUserRoles(userID);
            }
        }

        // 将角色赋予用户
        for (Map<String, String> ur : userRoles) {
            info.addRole(ur.get("KEY"));
        }

        // 获得最高角色code
        String key = userRoles.get(0).get("KEY");

        // 根据角色编号获得角色所有的菜单 - 菜单格式为 / 父子菜单
        // 一级菜单 - 父级
        List<SysMenu> userMenus = sumd.findUserMenus(key);
        for (SysMenu sm : userMenus) {
            log.debug(sm.getSmName());
            // 二级菜单 - 子级
            List<SysMenu> sysMenuList = sm.getSysMenuList();
            for (SysMenu sml : sysMenuList) {
                log.debug("\t" + sml.getSmName());
            }
        }

        // 获得 shiro - session
        Session session = SecurityUtils.getSubject().getSession();
        // 获得认证情况 - true or false
        session.getAttribute("org.apache.shiro.subject.support.DefaultSubjectContext_AUTHENTICATED_SESSION_KEY");
        // 获得认证成功后存放的信息
        session.getAttribute("org.apache.shiro.subject.support.DefaultSubjectContext_PRINCIPALS_SESSION_KEY");
        // 存放用户角色
        session.setAttribute("userRoles", userRoles);
        // 存放用户权限菜单
        session.setAttribute("userMenus", userMenus);

        log.warn("用户最高角色为 " + userRoles.get(0).get("VAL") + " , 角色编号为 " + key);

        // 将操作权限赋予用户 - 赋了一个玩,暂时没起实际作用。
        info.addStringPermission("find");
        return info;
    }

    // -----------------------------------------------------------------------------------------------------------------

    /**
     * 用户登陆验证/授权
     *
     * param user
     * return
     */
    public static DfUserLB loginVerify(DfUserLB user) {
        // shiro - start
        // 获得当前正在执行的subject
        Subject subject = SecurityUtils.getSubject();
        try {
            // 计算耗时
            long l = System.currentTimeMillis();
            log.info("正在认证 ......");
            // 验证 - 登陆认证并将信息保存到session - 记得传入明文密码
            subject.login(new UsernamePasswordToken(user.getUser(), user.getPassWord()));
            log.info("认证成功 耗时:" + (System.currentTimeMillis() - l) + " ms");

            // 计算耗时
            long l1 = System.currentTimeMillis();
            log.info("正在授权 ......");
            // 授权 - 其中的一种方式:调用 hasRole(str) - (参数一定要带) 才会执行 doGetAuthorizationInfo
            // 判断用户是否具有某个角色
            subject.hasRole("USER");
            log.info("授权完成 耗时:" + (System.currentTimeMillis() - l1) + " ms");
            // 获得shiro保存在session中的用户信息
            user = (DfUserLB) subject.getPrincipal();
            log.info("昵称为 " + user.getName() + " 用户名为 " + user.getUser());
        } catch ( UnknownAccountException uae ) {
            log.error("账户不存在");
        } catch ( IncorrectCredentialsException ice ) {
            log.error("密码不正确");
        } catch ( LockedAccountException lae ) {
            log.error("账户已被锁定");
        }
        return user;
        // shiro - end
    }

}

三、编写登录controller测试

1. 用户登陆验证/授权

在这里插入图片描述

/**
 * log4j 日志
 */
private final static Logger log = LogManager.getLogger(UserHgController.class);

/**
 * 工具类
 */
private IXlmToolKit kit = new XlmToolKit();

/**
  * description: 登录校验
  *
  * @param user
  * @return
  * @throws Exception
  */
 @RequestMapping(value = {"/login"}, method = RequestMethod.POST)
 @ResponseBody
 public String login(DfUserLB user) {
     return kit.parseJackson(ShiroSecurityRealm.loginVerify(user));
 }

2. 结果如下

在这里插入图片描述


本文到此结束了

ssm+shiro+layui+easyui实现的后台权限管理系统 项目描述 基于SSM+Shiro+Layui+Easyui实现的后台权限管理系统 丰富的代码注释会很方便于你的理解,清晰的代码层次会让你更清楚的明白企业级架构!希望能在有限的时间帮助你快速的提高自己!学习本项目需要一定的基础哈。 介绍 BM致力于更完善,代码注释更丰富,更易于理解学习的企业级后台管理系统 技术 ssm 框架 , shiro权限管理,layui + easyui 页面技术 功能 1.用户信息管理,2.角色管理,3.资源管理,4.部门资源,5.字典管理,6.日志管理,7.日志图表管理,后期功能陆续更新(boot版等等) 运行环境 jdk8+tomcat8+mysql+IntelliJ IDEA+maven 项目技术(必填) ssm+shiro+layui+easyui 数据库文件 链接:https://pan.baidu.com/s/15wqlVBqwEsB4PQ00rBxIuw 提取码:9yv8 jar包文件 链接:https://pan.baidu.com/s/1HcQq1M-_JCvY7hbuxtDQnQ 提取码:wmtnssm+shiro+layui+easyui实现的后台权限管理系统 项目描述 基于SSM+Shiro+Layui+Easyui实现的后台权限管理系统 丰富的代码注释会很方便于你的理解,清晰的代码层次会让你更清楚的明白企业级架构!希望能在有限的时间帮助你快速的提高自己!学习本项目需要一定的基础哈。 介绍 BM致力于更完善,代码注释更丰富,更易于理解学习的企业级后台管理系统 技术 ssm 框架 , shiro权限管理,layui + easyui 页面技术 功能 1.用户信息管理,2.角色管理,3.资源管理,4.部门资源,5.字典管理,6.日志管理,7.日志图表管理,后期功能陆续更新(boot版等等) 运行环境 jdk8+tomcat8+mysql+IntelliJ IDEA+maven 项目技术(必填) ssm+shiro+layui+easyui 数据库文件 链接:https://pan.baidu.com/s/15wqlVBqwEsB4PQ00rBxIuw 提取码:9yv8 jar包文件 链接:https://pan.baidu.com/s/1HcQq1M-_JCvY7hbuxtDQnQ 提取码:wmtn
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值