javascript
3-8 基于SpringBoot连接数据库与配置MyBatis实操 创建表sql
11? ? ? ? ? ? ? ? ? ? 13-8 基于SpringBoot連接數(shù)據(jù)庫與配置MyBatis實(shí)操
springSecurity提供了? ? ?現(xiàn)成的基于內(nèi)存管理的類? ? ?
shiro則必須自己設(shè)計這樣的類? ? ? 需要自己設(shè)計用戶權(quán)限這樣的體系
這里基于RBAC簡單的設(shè)計一套
?
?
?
?
-- 權(quán)限表 -- CREATE TABLE permission (pid int(11) NOT NULL AUTO_INCREMENT,name VARCHAR(255) NOT NULL DEFAULT '',url VARCHAR(255) DEFAULT '',PRIMARY KEY (pid) ) ENGINE = InnoDB DEFAULT CHARSET = utf8;INSERT INTO permission VALUES ('1', 'add', ''); INSERT INTO permission VALUES ('2', 'delete', ''); INSERT INTO permission VALUES ('3', 'edit', ''); INSERT INTO permission VALUES ('4', 'query', '');-- 用戶表 -- CREATE TABLE user(uid int(11) NOT NULL AUTO_INCREMENT,username VARCHAR(255) NOT NULL DEFAULT '',password VARCHAR(255) NOT NULL DEFAULT '',PRIMARY KEY (uid) ) ENGINE = InnoDB DEFAULT CHARSET = utf8;INSERT INTO user VALUES ('1', 'admin', '123'); INSERT INTO user VALUES ('2', 'demo', '123');-- 角色表 -- CREATE TABLE role(rid int(11) NOT NULL AUTO_INCREMENT,rname VARCHAR(255) NOT NULL DEFAULT '',PRIMARY KEY (rid) ) ENGINE = InnoDB DEFAULT CHARSET = utf8;INSERT INTO role VALUES ('1', 'admin'); INSERT INTO role VALUES ('2', 'customer');-- 權(quán)限角色關(guān)系表 -- CREATE TABLE permission_role (rid int(11) NOT NULL ,pid int(11) NOT NULL ,KEY idx_rid (rid),KEY idx_pid (pid) ) ENGINE = InnoDB DEFAULT CHARSET = utf8;INSERT INTO permission_role VALUES ('1', '1'); INSERT INTO permission_role VALUES ('1', '2'); INSERT INTO permission_role VALUES ('1', '3'); INSERT INTO permission_role VALUES ('1', '4'); INSERT INTO permission_role VALUES ('2', '1'); INSERT INTO permission_role VALUES ('2', '4');-- 用戶角色關(guān)系表 -- CREATE TABLE user_role (uid int(11) NOT NULL ,rid int(11) NOT NULL ,KEY idx_uid (uid),KEY idx_rid (rid) ) ENGINE = InnoDB DEFAULT CHARSET = utf8;INSERT INTO user_role VALUES (1, 1); INSERT INTO user_role VALUES (2, 2);?
//mapper的配置
1.掃描mapper的路徑
2.使用spring要告訴它掃描相關(guān)的注解
現(xiàn)在寫幾個case? ? ?需要些幾個realm? ? ?shiro的授權(quán)和登錄? ? ?需要實(shí)現(xiàn)相關(guān)的認(rèn)證和授權(quán)? ? 核心是自定義的realm
?
?
?
********************************************************************************************************************************************
?
package com.mmall.demo2;import com.mmall.demo2.model.Permission; import com.mmall.demo2.model.Role; import com.mmall.demo2.model.User; import com.mmall.demo2.service.UserService; import org.apache.commons.collections.CollectionUtils; 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.authc.UsernamePasswordToken; 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 java.util.ArrayList; import java.util.List; import java.util.Set;//需要實(shí)現(xiàn) AuthorizingRealm public class AuthRealm extends AuthorizingRealm {//需要注入user的serviece@Autowiredprivate UserService userService;// 2、授權(quán)@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//授權(quán)是在驗(yàn)證登錄成功之后進(jìn)行的 在認(rèn)證登錄之后我們會將user這個對象放到session 中//s所以我們先從session 中取出這個對象//通過這個方法可以取出session 中的對象 相當(dāng)于從session中獲取用戶User user = (User) principals.fromRealm(this.getClass().getName()).iterator().next();List<String> permissionList = new ArrayList<>();//一個角色有多個權(quán)限List<String> roleNameList = new ArrayList<>();//一個用戶有多個角色Set<Role> roleSet = user.getRoles();//用戶所有的角色if (CollectionUtils.isNotEmpty(roleSet)) {//用戶的角色不為空 遍歷用戶所有的角色//這里只有一個循環(huán) 不是2個循環(huán) 看清楚了for(Role role : roleSet) {// 角色roleNameList.add(role.getRname());//存儲用戶名下的角色名稱Set<Permission> permissionSet = role.getPermissions();//角色有可能重復(fù)權(quán)限這里使用set 可以去重復(fù)if (CollectionUtils.isNotEmpty(permissionSet)) {//如果該角色下面有權(quán)限for (Permission permission : permissionSet) {permissionList.add(permission.getName());//每個角色的權(quán)限 都加進(jìn)去 set可以去重復(fù)}}}}SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();info.addStringPermissions(permissionList);info.addRoles(roleNameList);return info;}// 1、首先先寫 認(rèn)證登錄@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//首先先寫 傳入的token 轉(zhuǎn)換為 UsernamePasswordToken 強(qiáng)行轉(zhuǎn)換就可以了UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;String username = usernamePasswordToken.getUsername();User user = userService.findByUsername(username);//獲取用戶// 完成了認(rèn)證登錄的部分 參數(shù) 用戶對象 認(rèn)證器就是密碼 當(dāng)前類名return new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getName());// 上面是轉(zhuǎn)換為AuthenticationInfo這個對象 1、這就完成認(rèn)證登錄功能 2、接下來寫授權(quán)}//上面 1,2 完成 就需要 校驗(yàn)user.getPassword(),是否是我們要求的規(guī)則 實(shí)現(xiàn)一個接口傳入即可//CredentialMatcher //public class CredentialMatcher extends SimpleCredentialsMatcher {}****************************************************************************************************** package com.mmall.demo2;import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;public class CredentialMatcher extends SimpleCredentialsMatcher {// 完成了簡單的密碼校驗(yàn)的重寫@Overridepublic boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {//首先token強(qiáng)轉(zhuǎn)UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;//強(qiáng)轉(zhuǎn)后獲取password 得到是數(shù)組強(qiáng)轉(zhuǎn)String 這個是user對象中的password字段String password = new String(usernamePasswordToken.getPassword());//獲取數(shù)據(jù)庫密碼 其實(shí)就是我們剛剛傳入的值String dbPassword = (String) info.getCredentials();//強(qiáng)轉(zhuǎn)//驗(yàn)證規(guī)則 自己定義就好了 這里就寫是否相等就好了return this.equals(password, dbPassword);}//完成 shiro的認(rèn)證和授權(quán) 和密碼校驗(yàn)規(guī)則之后//我們需要將他們注入到我們這個shiro的配置中//public class ShiroConfiguration { }******************************************************************************************************
?
package com.mmall.demo2;import org.apache.shiro.cache.MemoryConstrainedCacheManager; 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.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import java.util.LinkedHashMap;//這個類是shrio的核心配置 //在springboot中用@Configuration 作為標(biāo)識 在項(xiàng)目啟動時自動配置這個類 @Configuration public class ShiroConfiguration {//1、首先寫密碼和自定義規(guī)則 定義自己的類@Bean("credentialMatcher")public CredentialMatcher credentialMatcher() {return new CredentialMatcher();//直接聲明這個實(shí)例即可 拿到這個bean就可以拿到校驗(yàn)規(guī)則}//2.自定義authRealm 完成@Bean("authRealm") // 用上下文的bean 這里從spring中取出來 就上bean的名字public AuthRealm authRealm(@Qualifier("credentialMatcher") CredentialMatcher matcher) {AuthRealm authRealm = new AuthRealm();//定義real的實(shí)例authRealm.setCacheManager(new MemoryConstrainedCacheManager());authRealm.setCredentialsMatcher(matcher);//實(shí)例中給出自己的密碼比較器return authRealm;}//3、realm的上一層是securityManager 注入的是上一步中的realm@Bean("securityManager")public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm) {//這里使用DefaultWebSecurityManagerDefaultWebSecurityManager manager = new DefaultWebSecurityManager();//把第二步定義的authRealm放進(jìn)去manager.setRealm(authRealm);return manager;}//4.shiroFilter 注入上一步的securityManager 這里返回值是ShiroFilter的工廠Bean@Bean("shiroFilter")public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager) {//首先聲明實(shí)例 把securityManager 先注入進(jìn)去ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();bean.setSecurityManager(manager);//定義登錄的urlbean.setLoginUrl("/login");//定義登錄成功后跳轉(zhuǎn)的urlbean.setSuccessUrl("/index");//定義沒有權(quán)限訪問的urlbean.setUnauthorizedUrl("/unauthorized");//定義最核心的 某系請求怎么攔截 定義權(quán)限配置LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();//第一個參數(shù)是我們訪問的請求 第二個參數(shù)是我們使用的是什么樣的攔截器filterChainDefinitionMap.put("/index", "authc");//主頁必須登錄 authcfilterChainDefinitionMap.put("/login", "anon");//登錄不用校驗(yàn)filterChainDefinitionMap.put("/loginUser", "anon");filterChainDefinitionMap.put("/admin", "roles[admin]");filterChainDefinitionMap.put("/edit", "perms[edit]");filterChainDefinitionMap.put("/druid/**", "anon");filterChainDefinitionMap.put("/**", "user");bean.setFilterChainDefinitionMap(filterChainDefinitionMap);//設(shè)置進(jìn)filter//authc是什么含義?? 含義是前面的url使用authc的攔截器進(jìn)行驗(yàn)證//在enum DefaultFilter中//常用的就這幾個return bean;}// 這樣當(dāng)項(xiàng)目啟動的時候 shirofiler首先初始化 會依次初始化下去// 一層一層的就會初始化下去////下面的2個類 使得shiro和spring關(guān)聯(lián)是我們自己定制的//配置一下shiro和spring之間的幾個類 參數(shù)傳入securityManager@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) {//給一個實(shí)例AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();//設(shè)置securityManageradvisor.setSecurityManager(securityManager);return advisor;//這樣spring對securityManager使用就是我們自定義的securityManager}//z這個不用配置 只要出入shrio的管理就好了@Beanpublic DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();creator.setProxyTargetClass(true);//默認(rèn)是falsereturn creator;}//shrio的整個流程全部講解完畢了 }?
?
?
?
?
******************************************************************************************************
## database ## spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8 spring.datasource.username=root spring.datasource.password=root## mybatis ## # mybatis.xml文件的位置 mybatis.mapper-locations=mappers/*.xml # mybatis使用到的實(shí)體類pojo對象 都放到這個包下面 mybatis.type-aliases-package=com.mmall.demo2.model## jsp ## 定義頁面的位置 jsp放置在pages目錄下面 spring.mvc.view.prefix=/pages/ spring.mvc.view.suffix=.jsp******************************************************************************************************
在main文件夾中新加webapp文件夾,springboot默認(rèn)將頁面放在webapp下面? ?我們配置了jsp前綴為pages文件夾下面
?
******************************************************************************************************
?
package com.mmall.demo2;import com.alibaba.druid.support.http.StatViewServlet; import com.alibaba.druid.support.http.WebStatFilter; import org.mybatis.spring.SqlSessionFactoryBean; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;import javax.sql.DataSource;//@Configuration 加上這個注解在項(xiàng)目啟動時就配置 @Configuration public class DruidConfiguration {@Beanpublic ServletRegistrationBean statViewServlet() {ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");//白名單: 設(shè)置允許訪問的beanservletRegistrationBean.addInitParameter("allow", "127.0.0.1");//設(shè)置不允許訪問的ip//IP黑名單 (存在共同時,deny優(yōu)先于allow) : 如果滿足deny的即提示:Sorry, you are not permitted to view this page.servletRegistrationBean.addInitParameter("deny", "192.168.1.100");//登錄查看信息的賬號密碼. 查看druid登錄信息的用戶名和密碼servletRegistrationBean.addInitParameter("loginUsername", "druid");servletRegistrationBean.addInitParameter("loginPassword", "12345678");//是否能夠重置數(shù)據(jù).servletRegistrationBean.addInitParameter("resetEnable", "false");return servletRegistrationBean;}@Beanpublic FilterRegistrationBean statFilter() {FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());//添加過濾規(guī)則. 攔截那些請求filterRegistrationBean.addUrlPatterns("/*");//添加不需要忽略的格式信息. 過濾那些請求filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");return filterRegistrationBean;}@BeanPersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor() {return new PersistenceExceptionTranslationPostProcessor();}//配置數(shù)據(jù)庫的基本鏈接信息 信息也是是從application.properties文件中讀取@Bean(name = "dataSource")@Primary@ConfigurationProperties(prefix = "spring.datasource") //可以在application.properties中直接導(dǎo)入public DataSource dataSource() {return DataSourceBuilder.create().type(com.alibaba.druid.pool.DruidDataSource.class).build();}@Beanpublic SqlSessionFactoryBean sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean bean = new SqlSessionFactoryBean();bean.setDataSource(dataSource);PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();//最后指定mapper文件 有了這些就可以輕松的監(jiān)控數(shù)據(jù)庫的請求bean.setMapperLocations(resolver.getResources("classpath:/mappers/*.xml"));return bean;} } //訪問http://localhost:8080/druid/index.html 用戶名是上定義的druid 12345678 //可以對數(shù)據(jù)庫進(jìn)行監(jiān)控?
?
?
?
阿里的druid數(shù)據(jù)源監(jiān)控
******************************************************************************************************
代碼已經(jīng)上傳gitee
git@gitee.com:yjb1091947832/demo2druid.git
這節(jié)課內(nèi)容不少? 建議大家多看幾遍 ---? ?視頻老師
?
?
******************************************************************************************************
?
?
?
?
******************************************************************************************************
?
?
?
?
?
******************************************************************************************************
?
?
?
?
?
?
******************************************************************************************************
?
?
?
?
?
******************************************************************************************************
?
?
?
?
?
?
?
******************************************************************************************************
?
?
?
?
?
?
******************************************************************************************************
?
?
?
?
?
?
******************************************************************************************************
?
?
?
?
?
?
******************************************************************************************************
?
?
?
?
?
?
******************************************************************************************************
?
?
?
?
?
?
******************************************************************************************************
?
?
?
?
?
?
******************************************************************************************************
?
?
?
?
?
?
?
******************************************************************************************************
?
?
?
?
?
?
******************************************************************************************************
?
?
?
?
?
?
******************************************************************************************************
?
?
?
?
?
?
?
?
******************************************************************************************************
?
?
?
?
?
?
?
******************************************************************************************************
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的3-8 基于SpringBoot连接数据库与配置MyBatis实操 创建表sql的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 黑面是什么面 黑面是怎样形成的
- 下一篇: Spring MVC开发环境搭建