springboot与redis
阅读原文时间:2023年07月11日阅读:1

用到的框架技术有:springboot、mybatis、shiro、redis

前端有:layui、jqGrid

这里先不讲redis在Windows安装,比较简单,百度看一下其他文章就可以了,有空这里也可以补一个教程。

1、先看项目目录

2、下面放源码

实体类,权限PermissionEntity.java

package com.xiaostudy.shiro_test1.entity;

import java.io.Serializable;

/**
* 权限实体类
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 2019/6/8
* Time: 14:21
* Description: No Description
*/
public class PermissionEntity implements Serializable {
private String id;
private String name;
private String url;

 public String getId() {  
     return id;  
 }

 public void setId(String id) {  
     this.id = id;  
 }

 public String getName() {  
     return name;  
 }

 public void setName(String name) {  
     this.name = name;  
 }

 public String getUrl() {  
     return url;  
 }

 public void setUrl(String url) {  
     this.url = url;  
 }  

}

实体类,角色RoleEntity.java

package com.xiaostudy.shiro_test1.entity;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

/**
* 角色实体类
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 2019/6/8
* Time: 14:24
* Description: No Description
*/
public class RoleEntity implements Serializable {
private String id;
private String name;
private Set permissions = new HashSet<>();

 public String getId() {  
     return id;  
 }

 public void setId(String id) {  
     this.id = id;  
 }

 public String getName() {  
     return name;  
 }

 public void setName(String name) {  
     this.name = name;  
 }

 public Set<PermissionEntity> getPermissions() {  
     return permissions;  
 }

 public void setPermissions(Set<PermissionEntity> permissions) {  
     this.permissions = permissions;  
 }  

}

实体类,用户UserEntity.java

package com.xiaostudy.shiro_test1.entity;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

/**
* 用户实体类
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 2019/6/8
* Time: 14:26
* Description: No Description
*/
public class UserEntity implements Serializable {
private String id;
private String name;
private String password;
private Set roles = new HashSet<>();

 public String getId() {  
     return id;  
 }

 public void setId(String id) {  
     this.id = id;  
 }

 public String getName() {  
     return name;  
 }

 public void setName(String name) {  
     this.name = name;  
 }

 public String getPassword() {  
     return password;  
 }

 public void setPassword(String password) {  
     this.password = password;  
 }

 public Set<RoleEntity> getRoles() {  
     return roles;  
 }

 public void setRoles(Set<RoleEntity> roles) {  
     this.roles = roles;  
 }  

}

实体类,测试redis实体类TestRedisEntity.java

package com.xiaostudy.shiro_test1.entity;

import java.io.Serializable;

/**
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 2019/6/8
* Time: 22:04
* Description: No Description
*/
public class TestRedisEntity implements Serializable {
private int id;
private String name;
private String password;

 public int getId() {  
     return id;  
 }

 public void setId(int id) {  
     this.id = id;  
 }

 public String getName() {  
     return name;  
 }

 public void setName(String name) {  
     this.name = name;  
 }

 public String getPassword() {  
     return password;  
 }

 public void setPassword(String password) {  
     this.password = password;  
 }  

}

自定义Realm类,UserRealm.java

package com.xiaostudy.shiro_test1.realm;

import com.xiaostudy.shiro_test1.entity.PermissionEntity;
import com.xiaostudy.shiro_test1.entity.RoleEntity;
import com.xiaostudy.shiro_test1.entity.UserEntity;
import com.xiaostudy.shiro_test1.service.UserService;
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.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
* 自定义Realm,实现授权与认证
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 2019/6/8
* Time: 15:01
* Description: No Description
*/
public class UserRealm extends AuthorizingRealm {

 @Autowired  
 private UserService userService;

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

     System.out.println("===执行授权===");

     Subject subject = SecurityUtils.getSubject();  
     UserEntity user = (UserEntity)subject.getPrincipal();  
     if(user != null){  
         SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();  
         // 角色字符串集合  
         Collection<String> rolesCollection = new HashSet<>();  
         // 权限字符串集合  
         Collection<String> premissionCollection = new HashSet<>();  
         // 读取并赋值用户角色与权限  
         Set<RoleEntity> roles = user.getRoles();  
         for(RoleEntity role : roles){  
             rolesCollection.add(role.getName());  
             Set<PermissionEntity> permissions = role.getPermissions();  
             for (PermissionEntity permission : permissions){  
                 // 权限名称为PermissionEntity为字段url  
                 premissionCollection.add(permission.getUrl());  
             }  
             info.addStringPermissions(premissionCollection);  
         }  
         info.addRoles(rolesCollection);  
         return info;  
     }  
     return null;  
 }

 /\*\*  
  \* 用户认证  
  \*\*/  
 @Override  
 protected AuthenticationInfo doGetAuthenticationInfo(  
         AuthenticationToken authenticationToken) throws AuthenticationException {

     System.out.println("===执行认证===");

     UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;  
     UserEntity bean = userService.findByName(token.getUsername());

     if(bean == null){  
         // 用户不存在  
         throw new UnknownAccountException();  
     } else {  
         bean = userService.findById(bean.getId());  
         if(null == bean) {  
             // 认证失败  
             throw new AuthenticationException();  
         }  
     }

     ByteSource credentialsSalt = ByteSource.Util.bytes(bean.getName());

     return new SimpleAuthenticationInfo(bean, bean.getPassword(),  
             credentialsSalt, getName());  
 }  

}

处理没权限异常,NoPermissionException.java

package com.xiaostudy.shiro_test1.exception;

import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 2019/6/8
* Time: 15:13
* Description: No Description
*/
@ControllerAdvice
public class NoPermissionException {
// 授权失败,就是说没有该权限
@ExceptionHandler(UnauthorizedException.class)
public String handleShiroException(Exception ex) {
return "/error/unAuth";
}

 @ResponseBody  
 @ExceptionHandler(AuthorizationException.class)  
 public String AuthorizationException(Exception ex) {  
     return "权限认证失败";  
 }  

}

shiro配置类,ShiroConfig.java

package com.xiaostudy.shiro_test1.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.xiaostudy.shiro_test1.realm.UserRealm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
* Shiro配置类
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 2019/6/8
* Time: 15:06
* Description: No Description
*/
@Configuration
public class ShiroConfig {

 // 创建自定义 realm  
 @Bean  
 public UserRealm userRealm() {  
     UserRealm userRealm = new UserRealm();  
     return userRealm;  
 }

 // 创建 SecurityManager 对象  
 @Bean  
 public DefaultWebSecurityManager securityManager() {  
     DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();  
     securityManager.setRealm(userRealm());  
     return securityManager;  
 }

 // Filter工厂,设置对应的过滤条件和跳转条件  
 @Bean  
 public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {  
     ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();  
     shiroFilterFactoryBean.setSecurityManager(securityManager);  
     /\*\*  
      \* anon:匿名用户可访问  
      \* authc:认证用户可访问  
      \* user:使用rememberMe可访问  
      \* perms:对应权限可访问  
      \* role:对应角色权限可访问  
      \*/  
     LinkedHashMap<String, String> map = new LinkedHashMap<>();  

// map.put("/resources/**", "anon");//匿名访问静态资源
map.put("/static/**", "anon");//匿名访问静态资源
map.put("/statics/**", "anon");//匿名访问静态资源
map.put("/jquery.jqGrid-4.6.0/**", "anon");//匿名访问静态资源
map.put("/jquery-ui-1.12.0-rc.2/**", "anon");//匿名访问静态资源
map.put("/layui/**", "anon");//匿名访问静态资源
map.put("/external/**", "anon");//匿名访问静态资源
map.put("/jquery/**", "anon");//匿名访问静态资源
map.put("/js/**", "anon");//匿名访问静态资源
map.put("/css/**", "anon");//匿名访问静态资源
map.put("/images/**", "anon");//匿名访问静态资源
// 开放登录接口
map.put("/login", "anon");
// map.put("/login", "authc");
// 对登录跳转接口进行释放
map.put("/error", "anon");
// 对所有用户认证
map.put("/**", "authc");
// 登出
map.put("/logout", "logout");
// 登录
// 注意:这里配置的 /login 是指到 @RequestMapping(value="/login")中的 /login
shiroFilterFactoryBean.setLoginUrl("/login");
// 首页
shiroFilterFactoryBean.setSuccessUrl("/index");
// 错误页面,认证不通过跳转
shiroFilterFactoryBean.setUnauthorizedUrl("/error/unAuth");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}

 // 加入注解的使用,不加这个,注解不生效  
 @Bean  
 public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {  
     AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();  
     authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);  
     return authorizationAttributeSourceAdvisor;  
 }

 // 跟上面的注解配置搭配使用,有时候加了上面的配置后注解不生效,需要加入下面的配置  
 @Bean  
 @ConditionalOnMissingBean  
 public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {  
     DefaultAdvisorAutoProxyCreator app = new DefaultAdvisorAutoProxyCreator();  
     app.setProxyTargetClass(true);  
     return app;  
 }

 @Bean  
 public ShiroDialect shiroDialect() {  
     return new ShiroDialect();  
 }  

}

静态资源过滤配置类【告诉shiro不要拦截】,WebMvcConfig.java

package com.xiaostudy.shiro_test1.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 2019/6/9
* Time: 0:51
* Description: No Description
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

 /\*\*  
  \* @author xiaobu  
  \* @date 2019/1/18 13:51  
  \* @param registry  registry  
  \* @descprition  等价于 http://localhost:9001/1.txt 依次在static upload目录下找1.txt文件  
  \* @version 1.0  
  \*/  
 @Override  
 public void addResourceHandlers(ResourceHandlerRegistry registry) {  
     registry.addResourceHandler("/\*\*").addResourceLocations("classpath:/static/");  
     registry.addResourceHandler("/static/\*\*").addResourceLocations("classpath:/static/");  
 }

}

用户mapper,UserMapper.xml



 <resultMap id="userMap" type="com.xiaostudy.shiro\_test1.entity.UserEntity">  
     <id property="id" column="id"/>  
     <result property="name" column="name"/>  
     <result property="password" column="password"/>  
     <collection property="roles" ofType="com.xiaostudy.shiro\_test1.entity.RoleEntity">  
         <id property="id" column="roleId"/>  
         <result property="name" column="roleName"/>  
         <collection property="permissions" ofType="com.xiaostudy.shiro\_test1.entity.PermissionEntity">  
             <id property="id" column="permissionId"/>  
             <result property="name" column="permissionName"/>  
             <result property="url" column="permissionUrl"/>  
         </collection>  
     </collection>  
 </resultMap>

 <select id="findByName" parameterType="java.lang.String" resultType="com.xiaostudy.shiro\_test1.entity.UserEntity">  
   SELECT id, name, password  
     FROM user  
       WHERE name = #{name}  
 </select>

 <select id="findById" parameterType="java.lang.String" resultMap="userMap">  
   SELECT user.id, user.name, user.password,  
         role.id as roleId, role.name as roleName,  
         permission.id as permissionId,  
         permission.name as permissionName,  
         permission.url as permissionUrl  
     FROM user, user\_role, role, role\_permission, permission  
       WHERE user.id = #{id}  
         AND user.id = user\_role.user\_id  
         AND user\_role.role\_id = role.id  
         AND role.id = role\_permission.role\_id  
         AND role\_permission.permission\_id = permission.id  
 </select>

测试redis的mapper,TestRedisMapper.xml



 <select id="selectAll" resultType="com.xiaostudy.shiro\_test1.entity.TestRedisEntity" >  
   SELECT id, name, password  
     FROM test\_redis;  
 </select>

 <select id="selectPages" parameterType="java.lang.Integer" resultType="com.xiaostudy.shiro\_test1.entity.TestRedisEntity" >  
   SELECT id, name, password  
     FROM test\_redis limit #{page}, #{rows};  
 </select>

 <select id="selectTotal" resultType="java.lang.Integer" >  
   SELECT COUNT(\*) as total FROM test\_redis;  
 </select>

 <select id="selectById" parameterType="java.lang.Integer" resultType="com.xiaostudy.shiro\_test1.entity.TestRedisEntity">  
   SELECT id, name, password  
     FROM test\_redis  
       WHERE id = #{id};  
 </select>

 <select id="selectByName" parameterType="java.lang.String" resultType="com.xiaostudy.shiro\_test1.entity.TestRedisEntity">  
   SELECT id, name, password  
     FROM test\_redis  
       WHERE name = #{name};  
 </select>

 <insert id="insert" parameterType="com.xiaostudy.shiro\_test1.entity.TestRedisEntity" >  
     insert into test\_redis (name, password) value (#{name}, #{password});  
 </insert>

 <update id="update" parameterType="com.xiaostudy.shiro\_test1.entity.TestRedisEntity" >  
     update test\_redis  
         set  
         name = #{name},  
         password = #{password}  
         where  
         id = #{id};  
 </update>

 <delete id="deleteById" parameterType="java.lang.Integer" >  
     delete from test\_redis  
         where  
          id = #{id};  
 </delete>

 <delete id="deleteByName" parameterType="java.lang.String" >  
     delete from test\_redis  
         where  
          name = #{name};  
 </delete>

用户mapper,UserMapper.java

package com.xiaostudy.shiro_test1.mapper;

import com.xiaostudy.shiro_test1.entity.UserEntity;
import org.apache.ibatis.annotations.Mapper;

/**
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 2019/6/8
* Time: 14:45
* Description: No Description
*/
@Mapper
public interface UserMapper {

 // 根据用户名称,查询用户信息  
 public UserEntity findByName(String name);

 // 根据用户id,查询用户信息、角色、权限  
 public UserEntity findById(String id);  

}

测试redis的mapper,TestRedisMapper.java

package com.xiaostudy.shiro_test1.mapper;

import com.xiaostudy.shiro_test1.entity.TestRedisEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 2019/6/8
* Time: 22:07
* Description: No Description
*/
@Mapper
public interface TestRedisMapper {

 public List<TestRedisEntity> selectAll();

 /\*\*  
  \* 简单分页  
  \* <p>@Param的作用是告诉mapper他的参数名,因为存在多个参数</p>  
  \* @param page  
  \* @param rows  
  \* @return  
  \*/  
 public List<TestRedisEntity> selectPages(@Param("page") int page, @Param("rows") int rows);

 public int selectTotal();

 public TestRedisEntity selectById(int id);

 public TestRedisEntity selectByName(String name);

 public int insert(TestRedisEntity testRedisEntity);

 public int update(TestRedisEntity testRedisEntity);

 public int deleteById(int id);

 public int deleteByName(String name);  

}

用户service,UserService.java

package com.xiaostudy.shiro_test1.service;

import com.xiaostudy.shiro_test1.entity.UserEntity;

/**
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 2019/6/8
* Time: 14:55
* Description: No Description
*/
public interface UserService {

 UserEntity findByName(String name);

 UserEntity findById(String id);  

}

测试redis的service,TestRedisService.java

package com.xiaostudy.shiro_test1.service;

import com.xiaostudy.shiro_test1.entity.TestRedisEntity;
import com.xiaostudy.shiro_test1.entity.UserEntity;

import java.util.List;

/**
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 2019/6/8
* Time: 14:55
* Description: No Description
*/
public interface TestRedisService {

 public List<TestRedisEntity> selectAll();

 public List<TestRedisEntity> selectPages(int page, int rows);

 public int selectTotal();

 public TestRedisEntity selectById(int id);

 public TestRedisEntity selectByName(String name);

 public int insert(TestRedisEntity testRedisEntity);

 public int update(TestRedisEntity testRedisEntity);

 public int deleteById(int id);

 public int deleteByName(String name);  

}

用户service实现类,UserServiceImpl.java

package com.xiaostudy.shiro_test1.service.impl;

import com.xiaostudy.shiro_test1.entity.UserEntity;
import com.xiaostudy.shiro_test1.mapper.UserMapper;
import com.xiaostudy.shiro_test1.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 2019/6/8
* Time: 14:56
* Description: No Description
*/
@Service
public class UserServiceImpl implements UserService {

 @Autowired  
 private UserMapper userMapper;

 @Override  
 public UserEntity findByName(String name) {  
     return userMapper.findByName(name);  
 }

 @Override  
 public UserEntity findById(String id) {  
     return userMapper.findById(id);  
 }  

}

测试redis的service实现类,TestRedisServiceImpl.java

package com.xiaostudy.shiro_test1.service.impl;

import com.xiaostudy.shiro_test1.entity.TestRedisEntity;
import com.xiaostudy.shiro_test1.entity.UserEntity;
import com.xiaostudy.shiro_test1.mapper.TestRedisMapper;
import com.xiaostudy.shiro_test1.mapper.UserMapper;
import com.xiaostudy.shiro_test1.service.TestRedisService;
import com.xiaostudy.shiro_test1.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;

/**
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 2019/6/8
* Time: 14:56
* Description: No Description
*/
@Service
public class TestRedisServiceImpl implements TestRedisService {

@Autowired  
private TestRedisMapper testRedisMapper;

@Autowired  
private RedisTemplate<Object,Object> redisTemplate;

@Override  
public List<TestRedisEntity> selectAll() {  
    List<TestRedisEntity> redisEntityList = (List<TestRedisEntity>) redisTemplate.opsForValue().get("testRedisAll");  
    if(null == redisEntityList) {  
        redisEntityList = testRedisMapper.selectAll();  
        redisTemplate.opsForValue().set("testRedisAll", redisEntityList);  
    }  
    return redisEntityList;  
}

@Override  
public List<TestRedisEntity> selectPages(int page, int rows) {  
    int current = (page-1)\*rows;  
    List<TestRedisEntity> redisEntityList = (List<TestRedisEntity>) redisTemplate.opsForValue().get("testRedisByPages\_page" + page + "\_rows" + rows);  
    if(null == redisEntityList) {  
        redisEntityList = testRedisMapper.selectPages(current, rows);  
        redisTemplate.opsForValue().set("testRedisByPages\_page" + page + "\_rows" + rows, redisEntityList);  
    }  
    return redisEntityList;  
}

@Override  
public int selectTotal() {  
    String strTotal = (String) redisTemplate.opsForValue().get("testRedisTotal");  
    int total;  
    if(null == strTotal) {  
        total = testRedisMapper.selectTotal();  
        redisTemplate.opsForValue().set("testRedisTotal",String.valueOf(total));  
    } else {  
        total = Integer.parseInt(strTotal);  
    }  
    return total;  
}

@Override  
public TestRedisEntity selectById(int id) {  
    TestRedisEntity testRedisEntity = (TestRedisEntity) redisTemplate.opsForValue().get("testRedisById\_" + id);  
    if(null == testRedisEntity) {  
        testRedisEntity = testRedisMapper.selectById(id);  
        redisTemplate.opsForValue().set("testRedisById\_" + id, testRedisEntity);  
    }  
    return testRedisEntity;  
}

@Override  
public TestRedisEntity selectByName(String name) {  
    TestRedisEntity testRedisEntity = (TestRedisEntity) redisTemplate.opsForValue().get("testRedisByName\_" + name);  
    if(null == testRedisEntity) {  
        testRedisEntity = testRedisMapper.selectByName(name);  
        redisTemplate.opsForValue().set("testRedisByName\_" + name, testRedisEntity);  
    }  
    return testRedisEntity;  
}

@Override  
public int insert(TestRedisEntity testRedisEntity) {  
    int insert = testRedisMapper.insert(testRedisEntity);  
    this.closeRedis(insert, "testRedisByPages");  
    redisTemplate.opsForValue().set("testRedisTotal",String.valueOf(testRedisMapper.selectTotal()));  
    return insert;  
}

@Override  
public int update(TestRedisEntity testRedisEntity) {  
    int update = testRedisMapper.update(testRedisEntity);  
    this.closeRedis(update, "testRedisByPages");  
    redisTemplate.opsForValue().set("testRedisById\_" + testRedisEntity.getId(), testRedisEntity);  
    redisTemplate.opsForValue().set("testRedisByName\_" + testRedisEntity.getName(), testRedisEntity);  
    return update;  
}

@Override  
public int deleteById(int id) {  
    TestRedisEntity testRedisEntity = this.selectById(id);  
    int deleteById = testRedisMapper.deleteById(id);  
    this.closeRedis(deleteById, "testRedisByPages");  
    this.closeRedis(deleteById, "testRedisTotal");  
    this.closeRedis(deleteById, "testRedisById\_" + id);  
    this.closeRedis(deleteById, "testRedisByName\_" + testRedisEntity.getName());  
    return deleteById;  
}

@Override  
public int deleteByName(String name) {  
    TestRedisEntity testRedisEntity1 = this.selectByName(name);  
    int deleteByName = testRedisMapper.deleteByName(name);  
    this.closeRedis(deleteByName, "testRedisByPages");  
    this.closeRedis(deleteByName, "testRedisTotal");  
    this.closeRedis(deleteByName, "testRedisByName\_" + name);  
    this.closeRedis(deleteByName, "testRedisById\_" + testRedisEntity1.getId());  
    return deleteByName;  
}

/\*\*  
 \* 清空对应实体的缓存  
 \* @param count  
 \*/  
private void closeRedis(int count, String str) {  
    if(0 != count) {  
        redisTemplate.delete(redisTemplate.keys(str + "\*"));  
    }  
}  

}

用户登录controller,MainController.java

package com.xiaostudy.shiro_test1.web.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

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

/**
* 用户登录、登出、错误页面跳转控制器
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 2019/6/8
* Time: 15:15
* Description: No Description
*/
@Controller
public class MainController {

 @RequestMapping("/index")  
 public String index(HttpServletRequest request, HttpServletResponse response){  
     response.setHeader("root", request.getContextPath());  
     return "index";  
 }

 @RequestMapping("/login")  
 public String login(HttpServletRequest request, HttpServletResponse response){  
     response.setHeader("root", request.getContextPath());  
     String userName = request.getParameter("username");  
     String password = request.getParameter("password");

     // 等于null说明用户没有登录,只是拦截所有请求到这里,那就直接让用户去登录页面,就不认证了。  
     // 如果这里不处理,那个会返回用户名不存在,逻辑上不合理,用户还没登录怎么就用户名不存在?  
     if(null == userName) {  
         return "login";  
     }

     // 1.获取Subject  
     Subject subject = SecurityUtils.getSubject();  
     // 2.封装用户数据  
     UsernamePasswordToken token = new UsernamePasswordToken(userName, password);  
     // 3.执行登录方法  
     try{  
         subject.login(token);  
         return "redirect:/index";  
     } catch (UnknownAccountException e){  
         // 这里是捕获自定义Realm的用户名不存在异常  
         request.setAttribute("msg","用户名不存在!");  
     } catch (IncorrectCredentialsException e){  
         request.setAttribute("userName",userName);  
         request.setAttribute("msg","密码错误!");  
     } catch (AuthenticationException e) {  
         // 这里是捕获自定义Realm的认证失败异常  
         request.setAttribute("msg","认证失败!");  
     }

     return "login";  
 }

 @RequestMapping("/logout")  
 public String logout(){  
     Subject subject = SecurityUtils.getSubject();  
     if (subject != null) {  
         subject.logout();  
     }  

// return "redirect:/main";
return "login";
}

 @RequestMapping("/error/unAuth")  
 public String unAuth(){  
     return "/error/unAuth";  
 }

 @RequestMapping("/err")  
 public String err(){  
     return "/error/unAuth";  
 }  

}

用户权限controller,UserController.java

package com.xiaostudy.shiro_test1.web.controller;

import com.xiaostudy.shiro_test1.entity.UserEntity;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

/**
* 用户页面跳转
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 2019/6/8
* Time: 15:21
* Description: No Description
*/
@Controller
public class UserController {

 /\*\*  
  \* 个人中心,需认证可访问  
  \*/  
 @RequestMapping("/user/index")  
 @RequiresPermissions(value = "user")// 这里的user,就是对应权限实体类PermissionEntity的字段url,自定义Realm类UserRealm里是用这个字段  
 public String add(HttpServletRequest request){  
     UserEntity bean = (UserEntity) SecurityUtils.getSubject().getPrincipal();  
     request.setAttribute("userName", bean.getName());  
     return "/user/index";  
 }

 /\*\*  
  \* 会员中心,需认证且角色为vip可访问  
  \*/  
 @RequestMapping("/vip/index")  
 @RequiresPermissions(value = "vip")  
 public String update(){  
     return "/vip/index";  
 }  

}

测试redis的controller,TestRedisController.java

package com.xiaostudy.shiro_test1.web.controller;

import com.xiaostudy.shiro_test1.entity.TestRedisEntity;
import com.xiaostudy.shiro_test1.entity.UserEntity;
import com.xiaostudy.shiro_test1.service.TestRedisService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* 用户页面跳转
* Created with IntelliJ IDEA.
* User: Administrator
* Date: 2019/6/8
* Time: 15:21
* Description: No Description
*/
@Controller
@RequestMapping("/testRedis")
public class TestRedisController {

 @Autowired  
 private TestRedisService testRedisService;

 @RequestMapping("/index")  
 public String index() {  
     return "testRedis/index";  
 }

 @RequestMapping("/all")  
 @ResponseBody  
 public Map getTestRedisAll() {  
     List<TestRedisEntity> redisEntityList = testRedisService.selectAll();  
     Map map = new HashMap();  
     map.put("redisEntityList", redisEntityList);  
     return map;  
 }

 @RequestMapping("/pages")  
 @ResponseBody  
 public Map getTestRedisPages(String page, String rows) {  
     List<TestRedisEntity> redisEntityList = testRedisService.selectPages(Integer.parseInt(page), Integer.parseInt(rows));  
     int total = testRedisService.selectTotal();  
     Map map = new HashMap();  
     map.put("redisEntityList", redisEntityList);  
     map.put("pages", total/Integer.parseInt(rows)+((total%Integer.parseInt(rows) == 0) ? 0 : 1));  
     map.put("total", total);  
     map.put("current", Integer.parseInt(page));  
     return map;  
 }

 @RequestMapping("/getByName")  
 @ResponseBody  
 public Map getByName(String name) {  
     TestRedisEntity testRedisEntity = testRedisService.selectByName(name);  
     Map map = new HashMap();  
     map.put("redisEntity", testRedisEntity);  
     return map;  
 }

 @RequestMapping("/get")  
 @ResponseBody  
 public Map getTestRedisByName(String name) {  
     TestRedisEntity testRedisEntity = testRedisService.selectByName(name);  
     Map map = new HashMap();  
     map.put("testRedisEntity", testRedisEntity);  
     return map;  
 }

 @RequestMapping("/insert")  
 @ResponseBody  
 @RequiresPermissions(value = "vip")  
 public Map insertTestRedis(TestRedisEntity testRedisEntity) {  
     int insert = testRedisService.insert(testRedisEntity);  
     Map map = new HashMap();  
     map.put("result", insert);  
     return map;  
 }

 @RequestMapping("/update")  
 @ResponseBody  
 @RequiresPermissions(value = "vip")  
 public Map updateTestRedis(TestRedisEntity testRedisEntity) {  
     int update = testRedisService.update(testRedisEntity);  
     Map map = new HashMap();  
     map.put("result", update);  
     return map;  
 }

 @RequestMapping("/deleteById")  
 @ResponseBody  
 @RequiresPermissions(value = "vip")  
 public Map deleteById(String id) {  
     int deleteById = testRedisService.deleteById(Integer.parseInt(id));  
     Map map = new HashMap();  
     map.put("result", deleteById);  
     return map;  
 }

 @RequestMapping("/deleteByName")  
 @ResponseBody  
 @RequiresPermissions(value = "vip")  
 public Map deleteByName(String name) {  
     int deleteByName = testRedisService.deleteByName(name);  
     Map map = new HashMap();  
     map.put("result", deleteByName);  
     return map;  
 }

 @RequestMapping("/form")  
 public String form() {  
     return "testRedis/form";  
 }  

}

springboot启动类,ShiroTest1Application.java添加自定义序列化类bean,不要这个也可以,但是在redis上看就是\x\x\x之类

package com.xiaostudy.shiro_test1;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@SpringBootApplication
//@MapperScan(basePackages = "com.xiaostudy.shiro_test1.mapper")
public class ShiroTest1Application {

 public static void main(String\[\] args) {  
     SpringApplication.run(ShiroTest1Application.class, args);  
 }

 /\*\*  
  \* redisTemplate 序列化使用的jdkSerializeable, 存储二进制字节码, 所以自定义序列化类  
  \* @param redisConnectionFactory  
  \* @return  
  \*/  
 @Bean  
 public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {  
     RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();  
     redisTemplate.setConnectionFactory(redisConnectionFactory);

     // 使用Jackson2JsonRedisSerialize 替换默认序列化  
     Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

     ObjectMapper objectMapper = new ObjectMapper();  
     objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);  
     objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON\_FINAL);

     jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

     // 设置value的序列化规则和 key的序列化规则  
     redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);  
     redisTemplate.setKeySerializer(new StringRedisSerializer());  
     redisTemplate.afterPropertiesSet();  
     return redisTemplate;  
 }  

}

web.xml


http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app\_4\_0.xsd" version="4.0">
Archetype Created Web Application

 <!--请求编码设置-->  
 <filter>  
     <filter-name>encodingFilter</filter-name>  
     <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
     <init-param>  
         <param-name>encoding</param-name>  
         <param-value>UTF-8</param-value>  
     </init-param>  
     <init-param>  
         <param-name>forceEncoding</param-name>  
         <param-value>true</param-value>  
     </init-param>  
 </filter>  
 <filter-mapping>  
     <filter-name>encodingFilter</filter-name>  
     <url-pattern>/\*</url-pattern>  
 </filter-mapping>

 <listener>  
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
 </listener>  
 <listener>  
     <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>  
 </listener>  
 <servlet>  
     <servlet-name>SpringMVC</servlet-name>  
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
     <init-param>  
         <param-name>contextConfigLocation</param-name>  
         <param-value>classpath:spring-mvc.xml</param-value>  
     </init-param>  
     <load-on-startup>1</load-on-startup>  
     <async-supported>true</async-supported>  
 </servlet>  
 <servlet-mapping>  
     <servlet-name>SpringMVC</servlet-name>  
     <url-pattern>/</url-pattern>  
 </servlet-mapping>  
 <welcome-file-list>  
     <welcome-file>/index</welcome-file>  
 </welcome-file-list>

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

spring-mvc.xml


http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

<!-- 把Controller交给spring管理 -->  
<context:component-scan base-package="com.xiaostudy"/>

<!-- 配置注解处理器映射器 功能:寻找执行类Controller -->  
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>

<!-- 配置注解处理器适配器 功能:调用controller方法,执行controller -->  
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

<!-- 配置sprigmvc视图解析器:解析逻辑试图  
     后台返回逻辑试图:index  
    视图解析器解析出真正物理视图:前缀+逻辑试图+后缀====/WEB-INF/index.jsp -->  
<!--<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
    <property name="prefix" value="/WEB-INF/"/>  
    <property name="suffix" value=".jsp"/>  
</bean>-->  

application.yml

spring:
datasource:
url: jdbc:mysql://localhost:3306/my_test?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
# 初始化时建立物理连接连接的个数
initialSize: 5
# 最小连接池数量
minIdle: 5
# 最大连接池数量
maxActive: 20
# 获取连接时最大等待时间(ms),即60s
maxWait: 60000
# 1.Destroy线程会检测连接的间隔时间;2.testWhileIdle的判断依据
timeBetweenEvictionRunsMillis: 60000
# 最小生存时间ms
minEvictableIdleTimeMillis: 600000
maxEvictableIdleTimeMillis: 900000
# 用来检测连接是否有效的sql
validationQuery: SELECT 1 FROM DUAL
# 申请连接时执行validationQuery检测连接是否有效,启用会降低性能
testOnBorrow: false
# 归还连接时执行validationQuery检测连接是否有效,启用会降低性能
testOnReturn: false
# 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,
# 执行validationQuery检测连接是否有效,不会降低性能
testWhileIdle: true
# 是否缓存preparedStatement,mysql建议关闭
poolPreparedStatements: false
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,log4j
thymeleaf:
suffix: .html
charset: utf-8
#清除缓存,实现热部署
cache: false
mvc:
# 配置静态资源映射路径,/public、/resources路径失效
static-path-pattern: templates/**

 #redis配置  
 redis:  
   host: 127.0.0.1  
   port: 6379  
   password:  
   database: 2  
   timeout: 3000ms  
   jedis:  
     pool:  
       max-active: 200  
       max-idle: 100  
       min-idle: 1  
       max-wait: 3000ms

mybatis:
mapper-locations: classpath:mapper/*.xml
# mapperLocations: classpath:mapper/*.xml
# 虽然可以配置这项来进行pojo包扫描,但其实我更倾向于在mapper.xml写全类名
# type-aliases-package: com.xiaostudy.shiro_test1.entity

# 后台打印sql
logging:
level:
com.xiaostudy.shiro_test1.mapper : debug

登录页面,login.html



登录

用户登录




用户名
密码
\[\[${msg }\]\]



主页,index.html


首页

首页






通过认证后普通用户可以访问,user/index.html



用户中心

用户中心




欢迎\[\[${userName }\]\],这里是用户中心



通过认证后,vip用户可以访问,vip/index.html



会员中心

会员中心




欢迎来到会员中心



认证通过后,普通用户访问vip页面时跳转提示没有权限,error/unAuth.html



未授权提示

您还不是会员 ,没有权限访问这个页面!



认证通过后,所有用户可以访问,测试redis主页,testRedis/index.html



首页





 <script src="" th:src="@{/statics/js/jquery-3.0.0.js}"></script>  
 <!--jqueryui-->  
 <link href="//cdn.bootcss.com/jqueryui/1.12.0-rc.2/jquery-ui.min.css" th:href="@{/statics/jquery-ui-1.12.0-rc.2/jquery-ui.min.css}" rel="stylesheet">  
 <!--jqgrid的css-->  
 <link href="//cdn.bootcss.com/jqgrid/4.6.0/css/ui.jqgrid.css" th:href="@{/statics/jquery.jqGrid-4.6.0/css/ui.jqgrid.css}" rel="stylesheet">

 <!--locale-->  
 <script src="//cdn.bootcss.com/jqgrid/4.6.0/js/i18n/grid.locale-en.js" th:src="@{/statics/jquery.jqGrid-4.6.0/js/i18n/grid.locale-en.js}"></script>  
 <!--jqgrid的js-->  
 <script src="//cdn.bootcss.com/jqgrid/4.6.0/js/jquery.jqGrid.min.js" th:src="@{/statics/jquery.jqGrid-4.6.0/js/jquery.jqGrid.min.js}"></script>  
 <link href="" th:href="@{/statics/layui/css/layui.css}" rel="stylesheet">  
 <script src="" th:src="@{/statics/layui/layui.all.js}"></script>  



测试redis









测试redis主页,添加、修改、查看的form页面,testRedis/form.html





Title





 <script src="" th:src="@{/statics/js/jquery-3.0.0.js}"></script>  
 <!--jqueryui-->  
 <link href="//cdn.bootcss.com/jqueryui/1.12.0-rc.2/jquery-ui.min.css" th:href="@{/statics/jquery-ui-1.12.0-rc.2/jquery-ui.min.css}" rel="stylesheet">  
 <!--jqgrid的css-->  
 <link href="//cdn.bootcss.com/jqgrid/4.6.0/css/ui.jqgrid.css" th:href="@{/statics/jquery.jqGrid-4.6.0/css/ui.jqgrid.css}" rel="stylesheet">

 <!--locale-->  
 <script src="//cdn.bootcss.com/jqgrid/4.6.0/js/i18n/grid.locale-en.js" th:src="@{/statics/jquery.jqGrid-4.6.0/js/i18n/grid.locale-en.js}"></script>  
 <!--jqgrid的js-->  
 <script src="//cdn.bootcss.com/jqgrid/4.6.0/js/jquery.jqGrid.min.js" th:src="@{/statics/jquery.jqGrid-4.6.0/js/jquery.jqGrid.min.js}"></script>  
 <link href="" th:href="@{/statics/layui/css/layui.css}" rel="stylesheet">  
 <script src="" th:src="@{/statics/layui/layui.all.js}"></script>  





pom.xml


http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
org.springframework.boot spring-boot-starter-parent 2.1.5.RELEASE
com.xiaostudy
shiro_test1
0.0.1-SNAPSHOT
shiro_test1
Demo project for Spring Boot

 <properties>  
     <java.version>1.8</java.version>  
 </properties>

 <dependencies>  
     <dependency>  
         <groupId>org.springframework.boot</groupId>  
         <artifactId>spring-boot-starter-jdbc</artifactId>  
     </dependency>  
     <dependency>  
         <groupId>org.springframework.boot</groupId>  
         <artifactId>spring-boot-starter-thymeleaf</artifactId>  
     </dependency>  
     <dependency>  
         <groupId>org.springframework.boot</groupId>  
         <artifactId>spring-boot-starter-web</artifactId>  
     </dependency>  
     <dependency>  
         <groupId>org.mybatis.spring.boot</groupId>  
         <artifactId>mybatis-spring-boot-starter</artifactId>  
         <version>2.0.1</version>  
     </dependency>

     <dependency>  
         <groupId>mysql</groupId>  
         <artifactId>mysql-connector-java</artifactId>  
         <scope>runtime</scope>  
     </dependency>  
     <dependency>  
         <groupId>org.springframework.boot</groupId>  
         <artifactId>spring-boot-starter-test</artifactId>  
         <scope>test</scope>  
     </dependency>

     <!-- 数据库连接池 -->  
     <dependency>  
         <groupId>com.alibaba</groupId>  
         <artifactId>druid</artifactId>  
         <version>1.1.10</version>  
     </dependency>  
     <!-- Shiro -->  
     <dependency>  
         <groupId>org.apache.shiro</groupId>  
         <artifactId>shiro-spring</artifactId>  
         <version>1.3.2</version>  
     </dependency>  
     <!-- log4j -->  
     <dependency>  
         <groupId>log4j</groupId>  
         <artifactId>log4j</artifactId>  
         <version>1.2.17</version>  
     </dependency>

     <dependency>  
         <groupId>com.github.theborakompanioni</groupId>  
         <artifactId>thymeleaf-extras-shiro</artifactId>  
         <version>2.0.0</version>  
     </dependency>

     <!--热部署-->  
     <dependency>  
         <groupId>org.springframework.boot</groupId>  
         <artifactId>spring-boot-devtools</artifactId>  
         <scope>runtime</scope>  
     </dependency>

     <!-- redis 包 -->  
     <dependency>  
         <groupId>org.springframework.boot</groupId>  
         <artifactId>spring-boot-starter-data-redis</artifactId>  
         <version>1.4.7.RELEASE</version>  
     </dependency>  
 </dependencies>

 <build>  
     <plugins>  
         <plugin>  
             <groupId>org.springframework.boot</groupId>  
             <artifactId>spring-boot-maven-plugin</artifactId>  
         </plugin>  
     </plugins>  
 </build>

数据库表创建

用户表、角色表、权限表、用户与角色多对多表、角色与权限多对多表

DROP TABLE IF EXISTS `role_permission`;
DROP TABLE IF EXISTS `permission`;
DROP TABLE IF EXISTS `user_role`;
DROP TABLE IF EXISTS `role`;
DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
`id` VARCHAR(255) PRIMARY KEY,
`name` VARCHAR(255),
`password` VARCHAR(255)
) engine = InnoDB default charset = utf8 comment = '用户表';

CREATE TABLE `role` (
`id` VARCHAR(255) PRIMARY KEY,
`name` VARCHAR(255)
) engine = InnoDB default charset = utf8 comment = '角色表';

CREATE TABLE `user_role` (
`id` VARCHAR(255) PRIMARY KEY,
`user_id` VARCHAR(255),
`role_id` VARCHAR(255),
FOREIGN KEY (`user_id`) REFERENCES `user`(id),
FOREIGN KEY (`role_id`) REFERENCES `role`(id)
) engine = InnoDB default charset = utf8 comment = '用户与角色多对多表';

CREATE TABLE `permission` (
`id` VARCHAR(255) PRIMARY KEY,
`name` VARCHAR(255),
`url` VARCHAR(255)
) engine = InnoDB default charset = utf8 comment = '权限表';

CREATE TABLE `role_permission` (
`id` VARCHAR(255) PRIMARY KEY,
`role_id` VARCHAR(255),
`permission_id` VARCHAR(255),
FOREIGN KEY (`role_id`) REFERENCES `role`(id),
FOREIGN KEY (`permission_id`) REFERENCES `permission`(id)
) engine = InnoDB default charset = utf8 comment = '角色与权限多对多表';

insert into `user` (`id`, `name`, `password`) values('','admin','');
insert into `user` (`id`, `name`, `password`) values('','vip','');
insert into `user` (`id`, `name`, `password`) values('','svip','');

insert into `role` (`id`, `name`) values('','user');
insert into `role` (`id`, `name`) values('','vip');
insert into `role` (`id`, `name`) values('','svip');

insert into `permission` (`id`, `name`, `url`) values('','user','user');
insert into `permission` (`id`, `name`, `url`) values('','vip','vip');
insert into `permission` (`id`, `name`, `url`) values('','svip','svip');

insert into `user_role` (`id`, `user_id`, `role_id`) values('','','');
insert into `user_role` (`id`, `user_id`, `role_id`) values('','','');
insert into `user_role` (`id`, `user_id`, `role_id`) values('','','');
insert into `user_role` (`id`, `user_id`, `role_id`) values('','','');
insert into `user_role` (`id`, `user_id`, `role_id`) values('','','');
insert into `user_role` (`id`, `user_id`, `role_id`) values('','','');

insert into `role_permission` (`id`, `role_id`, `permission_id`) values('','','');
insert into `role_permission` (`id`, `role_id`, `permission_id`) values('','','');
insert into `role_permission` (`id`, `role_id`, `permission_id`) values('','','');
insert into `role_permission` (`id`, `role_id`, `permission_id`) values('','','');
insert into `role_permission` (`id`, `role_id`, `permission_id`) values('','','');
insert into `role_permission` (`id`, `role_id`, `permission_id`) values('','','');

测试redis表

DROP TABLE IF EXISTS `test_redis`;

CREATE TABLE `test_redis` (
`id` int(11) PRIMARY KEY auto_increment,
`name` VARCHAR(255),
`password` VARCHAR(255)
) engine = InnoDB default charset = utf8 comment = '测试redis表';

3、layui与jqGrid相关下载

layui官网下载:https://www.layui.com/

jqGrid官网下载:http://www.trirand.com/blog/?page_id=6

jqueryUI官网下载:http://jqueryui.com/download/all/

jquery下载:http://www.jq22.com/jquery-info122

4、测试

测试权限的就不在这里重复测试了,可以看一下之前写的文章【直接看最后的测试】:https://www.cnblogs.com/xiaostudy/p/10990999.html