韩源-末日生存手册 - sql
type: channel
link: https://kerryhan.cn/index.php/tag/sql
items: docker容器化部署Mysql8
items: Shiro授权功能详解
items: springboot+mybatisPlus代码层级梳理
items: Aop面向切面编程

docker容器化部署Mysql8
type: item
date: 2023-12-18T09:21:42+00:00
description: 宿主机创建映射文件目录，分别是/home/mysql/conf，/home/mysql/data、/home/mysql/logsconf目录下创建my.cnf文件[client] default-character-set = utf8mb4 [mysqld] pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock datadir = /var/lib/mysql secure-file-priv= NULL # Custom config should go here # 字符集 character_set_server=utf8mb4 collation-server=utf8mb4_unicode_ci # 创建新表时将使用的默认存储引擎 default-storage-engine=INNODB # 是否对sql语句大小写敏感，0:大小写敏感,1:忽略大小写区别。，只能在初始化服务器时配置。禁止在服务器初始化后更改 # 设置为2时，表名和数据库名按声明存储，但以小写形式进行比较 lower_case_table_names = 2 # 最大连接数 max_connections = 1000 # Innodb缓存池大小 innodb_buffer_pool_size = 4G # 表文件描述符的缓存大小 table_open_cache_instances=1 table_open_cache=2000 table_definition_cache=2000 !includedir /etc/mysql/conf.d/在conf、data、logs同层目录下，创建start.shdocker run --restart=always \ --name mysql \ --privileged=true \ -d -p 3306:3306 \ -v /home/mysql/conf/my.cnf:/etc/mysql/my.cnf \ -v /home/mysql/logs:/logs \ -v /home/mysql/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=Hanyuan1230@... \ mysql:8.0.35拉取docker的镜像文件 docker pull mysql:8.0.35sh start.sh命令执行脚本代码，创建mysql的docker容器进入mysql容器，docker exec -it mysql bash登录mysql，mysql -u root -p此时root用户外界还不能使用，要给root分配权限。第一行命令：grant all PRIVILEGES on . to root@'%' WITH GRANT OPTION;第二行命令：use mysql第三行命令：update user set host='%' where user='root';至此，外界就可以用root连接到mysql了

Shiro授权功能详解
type: item
date: 2021-04-10T06:57:00+00:00
description: 授权，也叫访问控制，即在应用中控制谁能访问哪些资源（如访问页面/编辑数据/页面操作等）。在授权中需了解的几个关键对象：主体（Subject）、资源（Resource）、权限（Permission）、角色（Role） 主体主体，即访问应用的用户，在Shiro中使用Subject代表该用户。用户只有授权后才允许访问相应的资源。资源在应用中用户可以访问的任何东西，比如访问JSP页面、查看/编辑某些数据、访问某个业务方法、打印文本等等都是资源。用户只要授权后才能访问。权限安全策略中的原子授权单位，通过权限我们可以表示在应用中用户有没有操作某个资源的权力。即权限表示在应用中用户能不能访问某个资源，如：访问用户列表页面查看/新增/修改/删除用户数据（即很多时候都是CRUD（增查改删）式权限控制）打印文档等等。。。如上可以看出，权限代表了用户有没有操作某个资源的权利，即反映在某个资源上的操作允不允许，不反映谁去执行这个操作。所以后续还需要把权限赋予给用户，即定义哪个用户允许在某个资源上做什么操作（权限），Shiro不会去做这件事情，而是由实现人员提供。Shiro支持粗粒度权限（如用户模块的所有权限）和细粒度权限（操作某个用户的权限，即实例级别的），后续部分介绍。角色角色代表了操作集合，可以理解为权限的集合，一般情况下我们会赋予用户角色而不是权限，即这样用户可以拥有一组权限，赋予权限时比较方便。典型的如：项目经理、技术总监、CTO、开发工程师等都是角色，不同的角色拥有一组不同的权限。隐式角色：即直接通过角色来验证用户有没有操作权限，如在应用中CTO、技术总监、开发工程师可以使用打印机，假设某天不允许开发工程师使用打印机，此时需要从应用中删除相应代码；再如在应用中CTO、技术总监可以查看用户、查看权限；突然有一天不允许技术总监查看用户、查看权限了，需要在相关代码中把技术总监角色从判断逻辑中删除掉；即粒度是以角色为单位进行访问控制的，粒度较粗；如果进行修改可能造成多处代码修改。显示角色：在程序中通过权限控制谁能访问某个资源，角色聚合一组权限集合；这样假设哪个角色不能访问某个资源，只需要从角色代表的权限集合中移除即可；无须修改多处代码；即粒度是以资源/实例为单位的；粒度较细。请google搜索“RBAC”和“RBAC新解”分别了解“基于角色的访问控制”“基于资源的访问控制(Resource-Based Access Control)”。授权方式Shiro支持三种方式的授权：编程式：通过写if/else授权代码块完成：Subject subject = SecurityUtils.getSubject(); if(subject.hasRole(“admin”)) { //有权限 } else { //无权限 }注解式：通过在执行的Java方法上放置相应的注解完成：@RequiresRoles("admin") public void hello() { //有权限 } 没有权限将抛出相应的异常；JSP/GSP标签：在JSP/GSP页面通过相应的标签完成：<shiro:hasRole name="admin"> <!— 有权限 —></shiro:hasRole> 后续部分将详细介绍如何使用。 授权基于角色的访问控制（隐式角色）1、在ini配置文件配置用户拥有的角色（shiro-role.ini）[users] zhang=123,role1,role2 wang=123,role1规则即：“用户名=密码,角色1，角色2”，如果需要在应用中判断用户是否有相应角色，就需要在相应的Realm中返回角色信息，也就是说Shiro不负责维护用户-角色信息，需要应用提供，Shiro只是提供相应的接口方便验证，后续会介绍如何动态的获取用户角色。2、测试用例（com.github.zhangkaitao.shiro.chapter3.RoleTest）@Test public void testHasRole() { login("classpath:shiro-role.ini", "zhang", "123"); //判断拥有角色：role1 Assert.assertTrue(subject().hasRole("role1")); //判断拥有角色：role1 and role2 Assert.assertTrue(subject().hasAllRoles(Arrays.asList("role1", "role2"))); //判断拥有角色：role1 and role2 and !role3 boolean[] result = subject().hasRoles(Arrays.asList("role1", "role2", "role3")); …

springboot+mybatisPlus代码层级梳理
type: item
date: 2020-04-30T14:40:00+00:00
description: 代码层级梳理代码层级annotation层ExcelVoAttribut主要用于写@ExcelVoAttribute注解，可以更灵活的配置Excel数据表导出的一些基本配置LogDirection主要用于写@LogDirection注解，注解里包含一个字段（接口描述），通过接口添加这个注解，填写上接口的功能，当用户在访问接口时候，可以利用aop技术，把用户的操作记到日志里aspect层LogDrectionAspect主要定义了aop切点的位置和增强的方法/** * @Author Johnny * @Date 2020/4/16 * @Version 1.0 */ @Aspect @Component @Slf4j public class LogDirectionAspect { @Pointcut("@annotation(logDirection)") public void doLogDirection(LogDirection logDirection){ } @Around(value = "doLogDirection(logDirection)",argNames = "pjp,logDirection") public Object doBefore(ProceedingJoinPoint pjp,LogDirection logDirection) throws Throwable{ if (!"".equals(logDirection.direction())) { log.info(logDirection.direction()+"接口被调用"); return pjp.proceed(); } return "接口信息不规范"; } }@Pointcut定义切点，此处定义切点为使用@LogDirection的方法@Around定义增强的方法，通过around的参数ProceedingJoinPoint可以很好的控制程序能不能继续执行下一步，在权限判定发挥着比较重要的作用拓展：利用下面的这种方法，需要在xml文件中配置bean实例，当然也可以在方法中通过手动扫包的方法获得bean实例进行操作/** * @Author Johnny * @Date 2020/4/16 * @Version 1.0 */ @Aspect public class MyAdvice { /** * 配置切点 */ @Pointcut("execution(* com.soft1851.spring.web.dao..*.insert*(..))") public void pointCut() { } /** * 配置前置增强 */ @Before("MyAdvice.pointCut()") public void beforeMethod() { System.out.println("等待数据插入"); } /** * 配置后置增强 */ @AfterReturning("execution(* com.soft1851.spring.web.dao..*.*(..))") public void afterMethod(){ System.out.println("关闭数据库"); } }xml配置实例 <bean name="forumDao" class="com.soft1851.spring.web.dao.impl.ForumDaoImpl"/> <bean name="myAdvice" class="com.soft1851.spring.web.interceptor.MyAdvice"/> <aop:aspectj-autoproxy/>common层ResponseResult和ResultCode这两个类可以将响应体统一进行封装，将接口的响应体规范化，使前端获取数据也更加友好贴下代码，防止以后找不到ResponseResult类package com.soft1851.music.admin.common; import lombok.Data; import java.io.Serializable; /** * @author Johnny * @Date: 2020/4/21 19:52 * @Description: */ @Data public class ResponseResult implements Serializable { private static final long serialVersionUID = -3948389268046368059L; private Integer code; private String msg; private Obje…

Aop面向切面编程
type: item
date: 2020-04-06T16:48:00+00:00
description: 什么是面向切面编程官方：在软件业，AOP为Aspect Oriented Programming的缩写，意为：面向切面编程，通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续，是软件开发中的一个热点，也是Spring框架中的一个重要内容，是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离，从而使得业务逻辑各部分之间的耦合度降低，提高程序的可重用性，同时提高了开发的效率个人理解：面向切面编程旨在较少冗余代码，使用的是一种代码横向抽取（举例：不同的方法拥有三句同样的代码，那这个代码就可以抽取出来，但使用父类、接口、继承、实现会极大的提高代码的耦合度，因此我们采用面向切面编程，把这三句代码全部抽取到一个方法当中）xml配置版实例代码接口：public interface Hello { void sayHello(); } 实现类public class HelloImpl implements Hello { @Override public void sayHello() { System.out.println("hello"); } }增强（相当于抽取出来的部分代码）public class BuildHello { void beforeBuilder(){ System.out.println("start..."); } void afterBuilder(){ System.out.println("ending..."); } } xml中bean实例的配置 <bean id="hello" class="com.soft1851.spring.aop.hello.HelloImpl"/> <bean id="beforeAdvice" class="com.soft1851.spring.aop.hello.BuildHello"/> <aop:config > <aop:aspect id="before" ref="beforeAdvice"> <aop:pointcut id="beforeCut" expression="execution(* com.soft1851.spring.aop.hello..*.*(..))"/> <aop:before method="beforeBuilder" pointcut-ref="beforeCut"/> </aop:aspect> <aop:aspect id="after" ref="beforeAdvice"> <aop:pointcut id="afterCut" expression="execution(* com.soft1851.spring.aop.hello..*.*(..))"/> <aop:after-returning method="afterBuilder" pointcut-ref="afterCut"/> </aop:aspect> </aop:config>注意要点：aop-config是配置整体的切面编程，而aop-aspect是设置切点和增强的容器，aop-pointcun用于设置切点，aop:before用于设置前置增强，aop:after-returning用于设置后置增强注解版实例代码dao底层代码@Repository public class ForumDaoImpl implements ForumDao { private JdbcTemplate jdbcTemplate; public ForumDaoImpl(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @Override public List<Forum> selectAll() { String sql = "SELECT * FROM t_forum "; System.out.println(jdbcTemplate); return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Forum.class)); } @Override public int insert(Forum forum) { System.out.println("开始插入数据"); String sql = "INSERT INTO t_forum VALUES (Null,?)"; Object[] args = {forum.getForumName()}; return jdbcTemplate.update(sql, args); } @Override publ…