3-8 基于SpringBoot连接数据库与配置MyBatis实操 创建表sql

11                    13-8 基于SpringBoot连接数据库与配置MyBatis实操

springSecurity提供了     现成的基于内存管理的类     

shiro则必须自己设计这样的类      需要自己设计用户权限这样的体系

这里基于RBAC简单的设计一套

 

 

 

 

-- 权限表 --
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');

-- 权限角色关系表 --
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');

-- 用户角色关系表 --
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要告诉它扫描相关的注解

现在写几个case     需要些几个realm     shiro的授权和登录     需要实现相关的认证和授权    核心是自定义的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;

//需要实现  AuthorizingRealm
public class AuthRealm extends AuthorizingRealm {


    //需要注入user的serviece
    @Autowired
    private UserService userService;


    // 2、授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //授权是在验证登录成功之后进行的   在认证登录之后我们会将user这个对象放到session 中
        //s所以我们先从session 中取出这个对象

        //通过这个方法可以取出session 中的对象     相当于从session中获取用户
        User user = (User) principals.fromRealm(this.getClass().getName()).iterator().next();
        List<String> permissionList = new ArrayList<>();//一个角色有多个权限
        List<String> roleNameList = new ArrayList<>();//一个用户有多个角色
        Set<Role> roleSet = user.getRoles();//用户所有的角色
        if (CollectionUtils.isNotEmpty(roleSet)) {//用户的角色不为空  遍历用户所有的角色
            //这里只有一个循环  不是2个循环 看清楚了
            for(Role role : roleSet) {// 角色
                roleNameList.add(role.getRname());//存储用户名下的角色名称
                Set<Permission> permissionSet = role.getPermissions();//角色有可能重复权限这里使用set 可以去重复
                if (CollectionUtils.isNotEmpty(permissionSet)) {//如果该角色下面有权限
                    for (Permission permission : permissionSet) {
                        permissionList.add(permission.getName());//每个角色的权限 都加进去  set可以去重复
                    }
                }
            }
        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermissions(permissionList);
        info.addRoles(roleNameList);
        return info;
    }

    // 1、首先先写   认证登录
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException    {
        //首先先写   传入的token  转换为 UsernamePasswordToken    强行转换就可以了
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        String username = usernamePasswordToken.getUsername();
        User user = userService.findByUsername(username);//获取用户
        // 完成了认证登录的部分    参数       用户对象      认证器就是密码             当前类名
        return new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getName());
        // 上面是转换为AuthenticationInfo这个对象         1、这就完成认证登录功能     2、接下来写授权
    }


    //上面  1,2 完成  就需要 校验user.getPassword(),是否是我们要求的规则  实现一个接口传入即可
    //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 {


    // 完成了简单的密码校验的重写
    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        //首先token强转
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        //强转后获取password   得到是数组强转String   这个是user对象中的password字段
        String password = new String(usernamePasswordToken.getPassword());
        //获取数据库密码   其实就是我们刚刚传入的值
        String dbPassword = (String) info.getCredentials();//强转
        //验证规则  自己定义就好了   这里就写是否相等就好了
        return this.equals(password, dbPassword);
    }

    //完成 shiro的认证和授权    和密码校验规则之后
    //我们需要将他们注入到我们这个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  作为标识   在项目启动时自动配置这个类
@Configuration
public class ShiroConfiguration {

    //1、首先写密码和自定义规则   定义自己的类
    @Bean("credentialMatcher")
    public CredentialMatcher credentialMatcher() {
        return new CredentialMatcher();//直接声明这个实例即可   拿到这个bean就可以拿到校验规则
    }

    //2.自定义authRealm 完成
    @Bean("authRealm")                 // 用上下文的bean   这里从spring中取出来 就上bean的名字
    public AuthRealm authRealm(@Qualifier("credentialMatcher") CredentialMatcher matcher) {
        AuthRealm authRealm = new AuthRealm();//定义real的实例
        authRealm.setCacheManager(new MemoryConstrainedCacheManager());
        authRealm.setCredentialsMatcher(matcher);//实例中给出自己的密码比较器
        return authRealm;
    }

    //3、realm的上一层是securityManager     注入的是上一步中的realm
    @Bean("securityManager")
    public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm) {
        //这里使用DefaultWebSecurityManager
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        //把第二步定义的authRealm放进去
        manager.setRealm(authRealm);
        return manager;
    }


   //4.shiroFilter   注入上一步的securityManager   这里返回值是ShiroFilter的工厂Bean
    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager) {
        //首先声明实例   把securityManager 先注入进去
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(manager);

        //定义登录的url
        bean.setLoginUrl("/login");
        //定义登录成功后跳转的url
        bean.setSuccessUrl("/index");
        //定义没有权限访问的url
        bean.setUnauthorizedUrl("/unauthorized");

        //定义最核心的 某系请求怎么拦截      定义权限配置
        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        //第一个参数是我们访问的请求   第二个参数是我们使用的是什么样的拦截器
        filterChainDefinitionMap.put("/index", "authc");//主页必须登录  authc
        filterChainDefinitionMap.put("/login", "anon");//登录不用校验
        filterChainDefinitionMap.put("/loginUser", "anon");
        filterChainDefinitionMap.put("/admin", "roles[admin]");
        filterChainDefinitionMap.put("/edit", "perms[edit]");
        filterChainDefinitionMap.put("/druid/**", "anon");
        filterChainDefinitionMap.put("/**", "user");
        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);//设置进filter

        //authc是什么含义??  含义是前面的url使用authc的拦截器进行验证
        //在enum DefaultFilter中
        //常用的就这几个

        return bean;
    }
    //  这样当项目启动的时候  shirofiler首先初始化  会依次初始化下去
    //  一层一层的就会初始化下去
    //








    //下面的2个类  使得shiro和spring关联是我们自己定制的


    //配置一下shiro和spring之间的几个类    参数传入securityManager
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) {
        //给一个实例
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        //设置securityManager
        advisor.setSecurityManager(securityManager);
        return advisor;//这样spring对securityManager使用就是我们自定义的securityManager
    }

    //z这个不用配置  只要出入shrio的管理就好了
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);//默认是false
        return 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使用到的实体类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默认将页面放在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  加上这个注解在项目启动时就配置
@Configuration
public class DruidConfiguration {

    @Bean
    public ServletRegistrationBean statViewServlet() {
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        //白名单:     设置允许访问的bean
        servletRegistrationBean.addInitParameter("allow", "127.0.0.1");
        //设置不允许访问的ip
        //IP黑名单 (存在共同时,deny优先于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");
        //是否能够重置数据.
        servletRegistrationBean.addInitParameter("resetEnable", "false");
        return servletRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean statFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        //添加过滤规则.      拦截那些请求
        filterRegistrationBean.addUrlPatterns("/*");
        //添加不需要忽略的格式信息.     过滤那些请求
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }

    @Bean
    PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor() {
        return new PersistenceExceptionTranslationPostProcessor();
    }

    //配置数据库的基本链接信息   信息也是是从application.properties文件中读取
    @Bean(name = "dataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource")    //可以在application.properties中直接导入
    public DataSource dataSource() {
        return DataSourceBuilder.create().type(com.alibaba.druid.pool.DruidDataSource.class).build();
    }

    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        //最后指定mapper文件  有了这些就可以轻松的监控数据库的请求
        bean.setMapperLocations(resolver.getResources("classpath:/mappers/*.xml"));
        return bean;
    }
}
//访问http://localhost:8080/druid/index.html   用户名是上定义的druid 12345678
//可以对数据库进行监控

 

 

 

 

阿里的druid数据源监控

******************************************************************************************************

代码已经上传gitee

git@gitee.com:yjb1091947832/demo2druid.git

这节课内容不少  建议大家多看几遍 ---   视频老师

 

 

******************************************************************************************************

 

 

 

 

******************************************************************************************************

 

 

 

 

 

******************************************************************************************************

 

 

 

 

 

 

******************************************************************************************************

 

 

 

 

 

******************************************************************************************************

 

 

 

 

 

 

 

******************************************************************************************************

 

 

 

 

 

 

******************************************************************************************************

 

 

 

 

 

 

******************************************************************************************************

 

 

 

 

 

 

******************************************************************************************************

 

 

 

 

 

 

******************************************************************************************************

 

 

 

 

 

 

******************************************************************************************************

 

 

 

 

 

 

******************************************************************************************************

 

 

 

 

 

 

 

******************************************************************************************************

 

 

 

 

 

 

******************************************************************************************************

 

 

 

 

 

 

******************************************************************************************************

 

 

 

 

 

 

 

 

******************************************************************************************************

 

 

 

 

 

 

 

******************************************************************************************************

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值