SpringBoot整合Mybatis和Shiro(程式碼記錄)
阿新 • • 發佈:2020-07-22
本文為個人學習demo記錄隨筆,主要程式碼記錄
*Redis部分忽略,因為僅僅是整合,未測試
*內容中包含很多個人學習性程式碼
一、專案目錄
展開
二、詳細程式碼
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"View Code> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.1.RELEASE</version> <relativePath/> </parent> <groupId>com.classic</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <mybatis.version>2.1.3</mybatis.version> <shiro.version>1.5.3</shiro.version> <hikaricp.version>3.4.5</hikaricp.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <!-- JDBC --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> <exclusions> <exclusion> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jdbc</artifactId> </exclusion> </exclusions> </dependency> <!-- HikariCP --> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> </dependency> <!-- MySQL --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- Mybatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>${mybatis.version}</version> </dependency> <!-- shiro --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>${shiro.version}</version> </dependency> <!-- Redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
application.properties
### 基本配置 ### server.port=8080 server.servlet.context-path=/demo ### DataSource ### spring.datasource.url=jdbc:mysql://localhost:3306/sourceplan?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false spring.datasource.username=root spring.datasource.password=pw123456 # 驅動 spring.datasource.driver-class-name=com.mysql.jdbc.Driver # 資料來源型別 spring.datasource.type=com.zaxxer.hikari.HikariDataSource # 連線池名稱 spring.datasource.hikari.pool-name=DateSourceHikariCP # 等待連線池分配連線的最大時長(毫秒),超過這個時長還沒可用的連線則發生SQLException, 預設:30秒 spring.datasource.hikari.connection-timeout=30000 # 最小連線數 spring.datasource.hikari.minimum-idle=10 # 最大連線數 spring.datasource.hikari.maximum-pool-size=2000 # 自動提交 spring.datasource.hikari.auto-commit=true # 連線超時的最大時長(毫秒),超時則被釋放(retired),預設:10分鐘 spring.datasource.hikari.idle-timeout=600000 # 連線的生命時長(毫秒),超時而且沒被使用則被釋放(retired),預設:30分鐘 1800000ms spring.datasource.hikari.max-lifetime=1800000 # 連線測試 spring.datasource.hikari.connection-test-query=SELECT 1 ### MyBatis 配置 ### # 所有POJO類所在包路徑 #mybatis.type-aliases-package=com.test.pojo # mapper對映檔案 mybatis.mapper-locations=classpath:mapper/*.xml ### Redis pool 配置 ### # Redis資料庫索引(預設為0,最大15) #spring.redis.database=0 # Redis伺服器地址 #spring.redis.host=192.168.0.24 # Redis伺服器連線埠 #spring.redis.port=6379 # Redis伺服器連線密碼(預設為空) #spring.redis.password= # 連線池最大連線數(使用負值表示沒有限制) #spring.redis.pool.max-active=200 # 連線池最大阻塞等待時間(使用負值表示沒有限制) #spring.redis.pool.max-wait=-1 # 連線池中的最大空閒連線 #spring.redis.pool.max-idle=10 # 連線池中的最小空閒連線 #spring.redis.pool.min-idle=0 # 連線超時時間(毫秒) #spring.redis.timeout=1000View Code
啟動類:DemoApplication.java
package com.classic.app; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; import org.springframework.transaction.annotation.EnableTransactionManagement; @SpringBootApplication @ComponentScan(basePackages = {"com.classic"}) @MapperScan("com.classic.dao") @EnableTransactionManagement // 啟註解事務管理,等同於xml配置方式的 <tx:annotation-driven /> public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }View Code
建表語句(表中均為模擬資料)
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for permission -- ---------------------------- DROP TABLE IF EXISTS `permission`; CREATE TABLE `permission` ( `id` int(11) NOT NULL AUTO_INCREMENT, `permission_code` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of permission -- ---------------------------- INSERT INTO `permission` VALUES ('1', 'query'); INSERT INTO `permission` VALUES ('2', 'update'); INSERT INTO `permission` VALUES ('3', 'insert'); INSERT INTO `permission` VALUES ('4', 'delete'); -- ---------------------------- -- Table structure for role -- ---------------------------- DROP TABLE IF EXISTS `role`; CREATE TABLE `role` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `role_code` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of role -- ---------------------------- INSERT INTO `role` VALUES ('1', 'ADMIN'); INSERT INTO `role` VALUES ('2', 'USER'); -- ---------------------------- -- Table structure for role_to_permission -- ---------------------------- DROP TABLE IF EXISTS `role_to_permission`; CREATE TABLE `role_to_permission` ( `id` int(11) NOT NULL AUTO_INCREMENT, `role_id` int(11) DEFAULT NULL, `permission_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of role_to_permission -- ---------------------------- INSERT INTO `role_to_permission` VALUES ('1', '1', '1'); INSERT INTO `role_to_permission` VALUES ('2', '1', '2'); INSERT INTO `role_to_permission` VALUES ('3', '1', '3'); INSERT INTO `role_to_permission` VALUES ('4', '1', '4'); INSERT INTO `role_to_permission` VALUES ('5', '2', '1'); -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `username` varchar(30) DEFAULT NULL, `password` varchar(30) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES ('1', 'zhousjcn', 'pw123456'); INSERT INTO `user` VALUES ('2', 'zhousj', 'pw123456'); -- ---------------------------- -- Table structure for user_role -- ---------------------------- DROP TABLE IF EXISTS `user_role`; CREATE TABLE `user_role` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `user_id` bigint(20) DEFAULT NULL, `role_id` bigint(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user_role -- ---------------------------- INSERT INTO `user_role` VALUES ('1', '1', '1'); INSERT INTO `user_role` VALUES ('2', '2', '2');View Code
entity
User.java
package com.classic.entity; import java.util.Set; public class User { private Long id; private String username; private String password; /* * 使用者對應角色集合 */ private Set<Role> roleSet; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Set<Role> getRoleSet() { return roleSet; } public void setRoleSet(Set<Role> roleSet) { this.roleSet = roleSet; } }View Code
Role.java
package com.classic.entity; import java.util.Set; public class Role { private Long id; private String roleCode; /** * 角色對應許可權集合 */ private Set<Permission> permissionSet; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getRoleCode() { return roleCode; } public void setRoleCode(String roleCode) { this.roleCode = roleCode; } public Set<Permission> getPermissionSet() { return permissionSet; } public void setPermissionSet(Set<Permission> permissionSet) { this.permissionSet = permissionSet; } }View Code
Permission.java
package com.classic.entity; public class Permission { private Long id; private String permissionCode; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getPermissionCode() { return permissionCode; } public void setPermissionCode(String permissionCode) { this.permissionCode = permissionCode; } }View Code
AbstractDao.java
package com.classic.commons; /** * 一些規定的dao層介面 * @author ... * */ public abstract class AbstractDao { }View Code
configure包
DemoExceptionHandler.java
package com.classic.configure; import org.apache.shiro.authz.UnauthenticatedException; import org.apache.shiro.authz.UnauthorizedException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; /** * 異常捕捉類 */ @ControllerAdvice public class DemoExceptionHandler { private static Logger logger = LoggerFactory.getLogger(DemoExceptionHandler.class); @ExceptionHandler @ResponseBody public String unauthenticatedExceptionHandler(UnauthenticatedException e) { logger.warn(e.getMessage(), e); return "使用者名稱或密碼錯誤"; } @ExceptionHandler @ResponseBody public String unauthorizedExceptionHandler(UnauthorizedException e) { logger.warn(e.getMessage(), e); return "許可權不足"; } @ExceptionHandler @ResponseBody public String exceptionHandler(Exception e) { logger.error(e.getMessage(), e); return "未知異常"; } }View Code
ExceptionMessageType.java
package com.classic.configure; public enum ExceptionMessageType { AUTHENTICATION_EXCEPTION, AUTHORIZATION_EXCEPTION, UNAUTHENTICATED_EXCEPTION, // 賬號密碼錯誤 UNAUTHORIZED_EXCEPTION // 許可權不足 }View Code
RedisConfig.java
package com.classic.configure; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonTypeInfo.As; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping; import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; @Configuration public class RedisConfig { @Bean // @SuppressWarnings("all") public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<String, Object>(); template.setConnectionFactory(factory); Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, DefaultTyping.NON_FINAL, As.PROPERTY); jackson2JsonRedisSerializer.setObjectMapper(om); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // key採用String的序列化方式 template.setKeySerializer(stringRedisSerializer); // hash的key也採用String的序列化方式 template.setHashKeySerializer(stringRedisSerializer); // value序列化方式採用jackson template.setValueSerializer(jackson2JsonRedisSerializer); // hash的value序列化方式採用jackson template.setHashValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; } }View Code
ShiroConfig.java
package com.classic.configure; import java.util.HashMap; import java.util.Map; import org.apache.shiro.mgt.SecurityManager; 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.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.classic.realm.UserRealm; @Configuration public class ShiroConfig { @Autowired private UserRealm userRealm; /** * 開啟Shiro的註解(如@RequiresRoles,@RequiresPermissions) * 配置以下兩個bean(DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor)即可實現此功能 * @return */ @Bean @ConditionalOnMissingBean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator daapc = new DefaultAdvisorAutoProxyCreator(); daapc.setProxyTargetClass(true); return daapc; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } //許可權管理,配置主要是Realm的管理認證 @Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(userRealm); return securityManager; } //Filter工廠,設定對應的過濾條件和跳轉條件 @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); Map<String, String> map = new HashMap<>(); //登出 map.put("/logout", "logout"); //對所有使用者認證 map.put("/**", "authc"); // 如果未登入這跳轉登入 shiroFilterFactoryBean.setLoginUrl("/user/login"); //首頁 shiroFilterFactoryBean.setSuccessUrl("/index"); //錯誤頁面,認證不通過跳轉 shiroFilterFactoryBean.setUnauthorizedUrl("/error"); shiroFilterFactoryBean.setFilterChainDefinitionMap(map); return shiroFilterFactoryBean; } }View Code
realm包
UserRealm.java
package com.classic.realm; import java.util.Set; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.classic.entity.Permission; import com.classic.entity.Role; import com.classic.entity.User; import com.classic.service.UserService; @Component public class UserRealm extends AuthorizingRealm { @Autowired private UserService userService; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { Object primaryPrincipal = principals.getPrimaryPrincipal(); if (primaryPrincipal == null) { return null; } String principal = primaryPrincipal.toString(); User user = userService.queryUserByUsername(principal); if (user == null) { return null; } SimpleAuthorizationInfo sai = new SimpleAuthorizationInfo(); Set<Role> roleSet = user.getRoleSet(); if (roleSet != null && roleSet.size() > 0) { for (Role role : roleSet) { // 新增角色 sai.addRole(role.getRoleCode()); // 新增許可權 Set<Permission> permissionSet = role.getPermissionSet(); if (permissionSet != null && permissionSet.size() > 0) { for (Permission permission : permissionSet) { sai.addStringPermission(permission.getPermissionCode()); } } } } return sai; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //加這一步的目的是在Post請求的時候會先進認證,然後在到請求 Object principalObj = token.getPrincipal(); if (principalObj == null) { return null; } //獲取使用者資訊 String principal = principalObj.toString(); User user = userService.queryUserByUsername(principal); if (user == null) { //這裡返回後會報出對應異常 return null; } else { //這裡驗證authenticationToken和simpleAuthenticationInfo的資訊 SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(principal, user.getPassword().toString(), getName()); return simpleAuthenticationInfo; } } }View Code
util包
RedisUtil.java
package com.classic.util; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; /** * Redis工具類 */ @Component public final class RedisUtil { @Autowired private RedisTemplate<String, Object> redisTemplate; // =============================common============================ /** * 指定快取失效時間 * @param key 鍵 * @param time 時間(秒) * @return */ public boolean expire(String key, long time) { try { if (time > 0) { redisTemplate.expire(key, time, TimeUnit.SECONDS); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 根據key 獲取過期時間 * @param key 鍵 不能為null * @return 時間(秒) 返回0代表為永久有效 */ public long getExpire(String key) { return redisTemplate.getExpire(key, TimeUnit.SECONDS); } /** * 判斷key是否存在 * @param key 鍵 * @return true 存在 false不存在 */ public boolean hasKey(String key) { try { return redisTemplate.hasKey(key); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 刪除快取 * @param key 可以傳一個值 或多個 */ @SuppressWarnings("unchecked") public void del(String... key) { if (key != null && key.length > 0) { if (key.length == 1) { redisTemplate.delete(key[0]); } else { redisTemplate.delete(CollectionUtils.arrayToList(key)); } } } // ============================String============================= /** * 普通快取獲取 * @param key 鍵 * @return 值 */ public Object get(String key) { return key == null ? null : redisTemplate.opsForValue().get(key); } /** * 普通快取放入 * @param key 鍵 * @param value 值 * @return true成功 false失敗 */ public boolean set(String key, Object value) { try { redisTemplate.opsForValue().set(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 普通快取放入並設定時間 * @param key 鍵 * @param value 值 * @param time 時間(秒) time要大於0 如果time小於等於0 將設定無限期 * @return true成功 false 失敗 */ public boolean set(String key, Object value, long time) { try { if (time > 0) { redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); } else { set(key, value); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 遞增 * @param key 鍵 * @param delta 要增加幾(大於0) * @return */ public long incr(String key, long delta) { if (delta < 0) { throw new RuntimeException("遞增因子必須大於0"); } return redisTemplate.opsForValue().increment(key, delta); } /** * 遞減 * @param key 鍵 * @param delta 要減少幾(小於0) * @return */ public long decr(String key, long delta) { if (delta < 0) { throw new RuntimeException("遞減因子必須大於0"); } return redisTemplate.opsForValue().increment(key, -delta); } // ================================Map================================= /** * HashGet * @param key 鍵 不能為null * @param item 項 不能為null * @return 值 */ public Object hget(String key, String item) { return redisTemplate.opsForHash().get(key, item); } /** * 獲取hashKey對應的所有鍵值 * @param key 鍵 * @return 對應的多個鍵值 */ public Map<Object, Object> hmget(String key) { return redisTemplate.opsForHash().entries(key); } /** * HashSet * @param key 鍵 * @param map 對應多個鍵值 * @return true 成功 false 失敗 */ public boolean hmset(String key, Map<String, Object> map) { try { redisTemplate.opsForHash().putAll(key, map); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * HashSet 並設定時間 * @param key 鍵 * @param map 對應多個鍵值 * @param time 時間(秒) * @return true成功 false失敗 */ public boolean hmset(String key, Map<String, Object> map, long time) { try { redisTemplate.opsForHash().putAll(key, map); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 向一張hash表中放入資料,如果不存在將建立 * @param key 鍵 * @param item 項 * @param value 值 * @return true 成功 false失敗 */ public boolean hset(String key, String item, Object value) { try { redisTemplate.opsForHash().put(key, item, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 向一張hash表中放入資料,如果不存在將建立 * @param key 鍵 * @param item 項 * @param value 值 * @param time 時間(秒) 注意:如果已存在的hash表有時間,這裡將會替換原有的時間 * @return true 成功 false失敗 */ public boolean hset(String key, String item, Object value, long time) { try { redisTemplate.opsForHash().put(key, item, value); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 刪除hash表中的值 * @param key 鍵 不能為null * @param item 項 可以使多個 不能為null */ public void hdel(String key, Object... item) { redisTemplate.opsForHash().delete(key, item); } /** * 判斷hash表中是否有該項的值 * @param key 鍵 不能為null * @param item 項 不能為null * @return true 存在 false不存在 */ public boolean hHasKey(String key, String item) { return redisTemplate.opsForHash().hasKey(key, item); } /** * hash遞增 如果不存在,就會建立一個 並把新增後的值返回 * @param key 鍵 * @param item 項 * @param by 要增加幾(大於0) * @return */ public double hincr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, by); } /** * hash遞減 * @param key 鍵 * @param item 項 * @param by 要減少記(小於0) * @return */ public double hdecr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, -by); } // ============================set============================= /** * 根據key獲取Set中的所有值 * @param key 鍵 * @return */ public Set<Object> sGet(String key) { try { return redisTemplate.opsForSet().members(key); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 根據value從一個set中查詢,是否存在 * @param key 鍵 * @param value 值 * @return true 存在 false不存在 */ public boolean sHasKey(String key, Object value) { try { return redisTemplate.opsForSet().isMember(key, value); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 將資料放入set快取 * @param key 鍵 * @param values 值 可以是多個 * @return 成功個數 */ public long sSet(String key, Object... values) { try { return redisTemplate.opsForSet().add(key, values); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 將set資料放入快取 * @param key 鍵 * @param time 時間(秒) * @param values 值 可以是多個 * @return 成功個數 */ public long sSetAndTime(String key, long time, Object... values) { try { Long count = redisTemplate.opsForSet().add(key, values); if (time > 0) expire(key, time); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 獲取set快取的長度 * @param key 鍵 * @return */ public long sGetSetSize(String key) { try { return redisTemplate.opsForSet().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 移除值為value的 * @param key 鍵 * @param values 值 可以是多個 * @return 移除的個數 */ public long setRemove(String key, Object... values) { try { Long count = redisTemplate.opsForSet().remove(key, values); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } // ===============================list================================= /** * 獲取list快取的內容 * @param key 鍵 * @param start 開始 * @param end 結束 0 到 -1代表所有值 * @return */ public List<Object> lGet(String key, long start, long end) { try { return redisTemplate.opsForList().range(key, start, end); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 獲取list快取的長度 * @param key 鍵 * @return */ public long lGetListSize(String key) { try { return redisTemplate.opsForList().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 通過索引 獲取list中的值 * @param key 鍵 * @param index 索引 index>=0時, 0 表頭,1 第二個元素,依次類推;index<0時,-1,表尾,-2倒數第二個元素,依次類推 * @return */ public Object lGetIndex(String key, long index) { try { return redisTemplate.opsForList().index(key, index); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 將list放入快取 * @param key 鍵 * @param value 值 * @param time 時間(秒) * @return */ public boolean lSet(String key, Object value) { try { redisTemplate.opsForList().rightPush(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 將list放入快取 * @param key 鍵 * @param value 值 * @param time 時間(秒) * @return */ public boolean lSet(String key, Object value, long time) { try { redisTemplate.opsForList().rightPush(key, value); if (time > 0) expire(key, time); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 將list放入快取 * @param key 鍵 * @param value 值 * @param time 時間(秒) * @return */ public boolean lSet(String key, List<Object> value) { try { redisTemplate.opsForList().rightPushAll(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 將list放入快取 * * @param key 鍵 * @param value 值 * @param time 時間(秒) * @return */ public boolean lSet(String key, List<Object> value, long time) { try { redisTemplate.opsForList().rightPushAll(key, value); if (time > 0) expire(key, time); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 根據索引修改list中的某條資料 * @param key 鍵 * @param index 索引 * @param value 值 * @return */ public boolean lUpdateIndex(String key, long index, Object value) { try { redisTemplate.opsForList().set(key, index, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 移除N個值為value * @param key 鍵 * @param count 移除多少個 * @param value 值 * @return 移除的個數 */ public long lRemove(String key, long count, Object value) { try { Long remove = redisTemplate.opsForList().remove(key, count, value); return remove; } catch (Exception e) { e.printStackTrace(); return 0; } } }View Code
dao層
UserMapper.java
package com.classic.dao; import java.util.List; import org.apache.ibatis.annotations.Select; import com.classic.entity.User; public interface UserMapper { @Select("select * from user") List<User> queryAll(); @Select( "select id,username,password from user " + "where username = #{username}" ) User queryUserByUsername(String username); }View Code
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.classic.dao.UserMapper"> <!-- <select id="queryAll" resultType="com.classic.entity.User"> select * from user </select> --> </mapper>View Code
RoleMapper.java
package com.classic.dao; import java.util.Set; import org.apache.ibatis.annotations.Select; import com.classic.entity.Role; public interface RoleMapper { Set<Role> queryRolesByIds(Set<Long> ids); @Select("select role_id from user_role where user_id=#{userId}") Set<Long> queryRoleIdsByUserId(Long userId); }View Code
RoleMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.classic.dao.RoleMapper"> <sql id="selectAllColumnSql"> select id,role_code roleCode from role </sql> <select id="queryRolesByIds" resultType="com.classic.entity.Role"> <include refid="selectAllColumnSql" /> where id in <foreach collection="ids" item="id" index="index" open="(" close=")" separator=","> #{id} </foreach> </select> </mapper>View Code
PermissionMapper.java
package com.classic.dao; import java.util.Set; import org.apache.ibatis.annotations.Select; import com.classic.entity.Permission; public interface PermissionMapper { Set<Permission> queryPermissionsByIds(Set<Integer> ids); @Select("select permission_id from role_to_permission where role_id=#{roleId}") Set<Integer> queryPermissionIdsByRoleId(Long roleId); }View Code
PermissionMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.classic.dao.PermissionMapper"> <sql id="selectAllColumnSql"> select id,permission_code permissionCode from permission </sql> <select id="queryPermissionsByIds" resultType="com.classic.entity.Permission"> <include refid="selectAllColumnSql"/> where id in <foreach collection="ids" item="id" index="index" open="(" close=")" separator=","> #{id} </foreach> </select> </mapper>View Code
service層
UserService.java
package com.classic.service; import java.util.List; import com.classic.entity.User; public interface UserService { List<User> queryAll(); User queryUserByUsername(String username); }View Code
UserServiceImp.java
package com.classic.service; import java.util.List; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.classic.dao.UserMapper; import com.classic.entity.Role; import com.classic.entity.User; @Service public class UserServiceImp implements UserService { @Autowired private UserMapper userMapper; @Autowired private RoleService roleService; @Override public List<User> queryAll() { return userMapper.queryAll(); } @Override public User queryUserByUsername(String username) { User user = userMapper.queryUserByUsername(username); if (user != null) { Long userId = user.getId(); Set<Role> roleSet = roleService.queryRolesByUserId(userId); user.setRoleSet(roleSet); } return user; } }View Code
RoleService.java
package com.classic.service; import java.util.Set; import com.classic.entity.Role; public interface RoleService { Set<Role> queryRolesByUserId(Long userId); }View Code
RoleServiceImpl.java
package com.classic.service; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.classic.dao.RoleMapper; import com.classic.entity.Role; @Service public class RoleServiceImpl implements RoleService { @Autowired private RoleMapper roleMapper; @Autowired private PermissionService permissionService; @Override public Set<Role> queryRolesByUserId(Long userId) { Set<Long> ids = roleMapper.queryRoleIdsByUserId(userId); if (ids != null && ids.size() > 0) { Set<Role> roleSet = roleMapper.queryRolesByIds(ids); if (roleSet != null && roleSet.size() > 0) { for (Role role : roleSet) { Long roleId = role.getId(); role.setPermissionSet(permissionService.queryPermissionsByRoleId(roleId)); } } return roleSet; } return null; } }View Code
PermissionService.java
package com.classic.service; import java.util.Set; import com.classic.entity.Permission; public interface PermissionService { Set<Permission> queryPermissionsByRoleId(Long roleId); }View Code
PermissionServiceImpl.java
package com.classic.service; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.classic.dao.PermissionMapper; import com.classic.entity.Permission; @Service public class PermissionServiceImpl implements PermissionService { @Autowired private PermissionMapper permissionMapper; @Override public Set<Permission> queryPermissionsByRoleId(Long roleId) { Set<Integer> ids = permissionMapper.queryPermissionIdsByRoleId(roleId); if (ids != null && ids.size() > 0) { return permissionMapper.queryPermissionsByIds(ids); } return null; } }View Code
Controller層(僅提供測試介面)
UserController.java
package com.classic.controller; import java.util.List; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresRoles; import org.apache.shiro.subject.Subject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.classic.entity.User; import com.classic.service.UserService; @RestController @RequestMapping("/user") public class UserController { private static final Logger logger = LoggerFactory.getLogger(UserController.class); @Autowired private UserService userService; @GetMapping("/queryAll") public List<User> queryAll() { return userService.queryAll(); } @GetMapping("/queryByUsername") public User queryByUsername(String username) { return userService.queryUserByUsername(username); } @RequestMapping("/login") public String userLogin(User user) { //新增使用者認證資訊 Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUsername(), user.getPassword()); try { //進行驗證,這裡可以捕獲異常,然後返回對應資訊 subject.login(usernamePasswordToken); // subject.checkRole("ADMIN"); // subject.checkPermissions("query", "add"); } catch (AuthenticationException e) { logger.error(e.getMessage(), e); return "賬號或密碼錯誤!"; } catch (AuthorizationException e) { logger.error(e.getMessage(), e); return "沒有許可權"; } return "登入成功"; } @RequestMapping("/index") @RequiresRoles(value={"ADMIN","USER"},logical = Logical.OR) @RequiresPermissions(value={"query"},logical = Logical.OR) public String indexTest() { return "Index"; } @RequestMapping("/logout") public String userLogout() { Subject subject = SecurityUtils.getSubject(); subject.logout(); return "登出成功"; } }View Code
參考連結:
https://www.jianshu.com/p/7f724bec3dc3