若依-原理
1.代码生成器
1.1源码分析
代码生成器分为两个部分:
第一部分涉及将业务表结构导入到系统中
第二部分是点击生成按钮,系统将根据表结构生成相应的前后端代码,并提供下载。
1.表结构说明
gen_table
:存储业务表的基本信息 ,它对应于配置代码基本信息和生成信息的页面
gen_table_column
:存储业务表的字段信息 它对应于配置代码字段信息的页面。
这两张表是一对多的关系,一张业务表可以有多个字段的信息,所以在字段信息表中有个外键table_id指向
2.目录结构
3.查询数据库列表
当管理员在界面上点击导入按钮时,会弹出一个对话框,此时,前端需要向后端发送请求,查询数据库并返回到前端,展示当前项目库中所有待导入的业务表。
<select id="selectDbTableList" parameterType="GenTable" resultMap="GenTableResult">select table_name, table_comment, create_time, update_time from information_schema.tableswhere table_schema = (select database())AND table_name NOT LIKE 'qrtz_%' AND table_name NOT LIKE 'gen_%'AND table_name NOT IN (select table_name from gen_table)<if test="tableName != null and tableName != ''">AND lower(table_name) like lower(concat('%', #{tableName}, '%'))</if><if test="tableComment != null and tableComment != ''">AND lower(table_comment) like lower(concat('%', #{tableComment}, '%'))</if><if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->AND date_format(create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')</if><if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->AND date_format(create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')</if>order by create_time desc</select>
4.导入表结构
当管理员对话框中选中需要导入的业务表,点击确定按钮,此时,前端需要向后端发送请求,保存业务表的基本信息和字段信息
5.生成代码
6.问题分析
(1)每次生成代码都需要修改作者,去除实体类前缀过于繁琐,现在我们可以修改generator.yml
配置文件来调整为自己项目的
(2)实体类支持Lombok,Controller类支持Swagger
需要Velocity模板引擎
1.2Velocity模版引擎
Velocity是一个基于Java的模板引擎,可以通过特定的语法获取在java对象的数据 , 填充到模板中,从而实现界面和java代码的分离 !
1.基础语法
Velocity中的变量有两类
-
在模板中定义变量:
#set
开头,比如#set($name = "velocity")
-
获取变量的的值:
$name
或者${name}
获取对象中的数据
循环
循环遍历普通集合
循环遍历对象
if判断
在条件判断中,velocity支持常见的关系操作符,比如:&&(与), ||(或), !(非)
2.Lombok集成
(1)导入坐标(已完成)
在dkd-common
模块的pom.xml
中添加lombok坐标
(2)修改模板
在dkd-generator
模块的domain.java.vm
模板中添加lombok注解
修改完成之后,重启项目,找到代码生成的功能,通过代码预览可以查看实体类的代码:
3.Swagger集成
(1)修改模板
在dkd-generator
模块的 controller.java.vm
模板中添加Swagger注解
返回结果改为R<>
2.RBAC权限控制
Spring Security是一个功能强大的Java安全框架,它提供了全面的安全认证和授权的支持。
1)认证(Authentication) 在Spring Security的世界里,认证就像用户登录时提交的用户名和密码,系统通过这些信息来验证“你是谁”。
2)授权(Authorization) 授权是确认用户在通过认证之后,是否有权限执行某些操作或访问特定资源。
2.1SpringSecurity配置
Spring Security的配置类是实现安全控制的核心部分
开启Spring Security各种功能,以确保Web应用程序的安全性,包括认证、授权、会话管理、过滤器添加等。
2.2用户登录流程
在ruoyi-framework
模块中com.ruoyi.framework.web.service.SysLoginService
类的login
方法处理登录逻辑
-
验证码校验
-
登录前置校验
-
SS认证管理器用户校验,调用执行UserDetailsServiceImpl.loadUserByUsername
-
认证通过后,创建登录用户对象LoginUser包括用户ID、部门ID、用户信息和用户权限信息
-
-
登录成功,记录日志
-
修改用户表更新登录信息
-
生成token
2.3获取用户角色和权限
在ruoyi-framework
模块中com.ruoyi.framework.web.service.SysPermissionService
类
-
getRolePermission查询该用户角色集合
-
getMenuPermission查询该用户权限(菜单)集合用set集合,一个用户可能有多个角色,多个角色的权限可能有重复的
页面权限
2.4获取动态菜单路由
2.5权限注解
1.源码分析
在若依框架中,权限的验证最核心的是使用的Spring Security的提供的权限注解`@PreAuthorize `
- @PreAuthorize 是 Spring Security 框架中提供的一个安全注解,用于实现基于注解的访问控制。它允许开发者在**方法级别**上声明特定的安全约束,以确保只有满足指定条件的用户才能调用该方法
- 当 @PreAuthorize 注解被应用于某个方法时,Spring Security 在**该方法执行前**会先对当前认证的用户进行权限检查。如果检查通过,方法调用得以继续;否则,框架会抛出相应的权限异常(如 AccessDeniedException),阻止方法执行。
2.权限方法
3.公开接口
如果有些接口是不需要验证权限可以公开访问的,这个时候就需要我们给接口放行。
使用注解方式,只需要在Controller
的类或方法上加入@Anonymous
该注解即可
3.异步任务管理器
主要用于处理一些不需要即时返回结果的后台任务,从而提高应用程序的整体性能
// 多线程执行任务me()创建单例对象(饿汉式)
AsyncManager.me().execute(AsyncFactory.createTimerTask());
若依异步任务管理器是一个单例对象使用了线程池+异步工厂(产生任务用)
-
com.dkd.framework.manager.AsyncManager 异步任务管理器
-
com.dkd.framework.manager.factory.AsyncFactory 异步线程工厂
1、 AsyncManager.me()获取AsyncManager对象
2、调用execute方法,执行TimerTask任务(记录登录日志),它实现了runnable接口,由线程Thread去执行
3、execute方法内部调用ScheduledExecutorService异步操作任务调度线程池的schedule方法用于延迟10毫秒执行一个任务
4.操作日志
在需要被记录日志的controller
方法上添加@Log
注解,使用方法如下:
@Log(title = "订单管理", businessType = BusinessType.INSERT)
public AjaxResult add(...)
{return toAjax(...);
}
若依操作日志使用了自定义注解+AOP切面+异步任务管理器
-
com.ruoyi.common.annotation.Log 自定义注解
-
com.ruoyi.framework.aspectj.LogAspect 在一个aop切面类
-
通过实现AOP切面编程,对目标方法进行拦截(标注Log注解的方法),实现了操作日志的自动记录
-
异步任务管理器来将任务(记录操作日志到数据库)交给线程池来完成
-
5.定时任务
5.1源码分析
1.表结构说明
sys_job
表(一):这是核心的定时任务表,用于存储定时任务的配置信息,如任务名称、任务组、执行的类全名、执行的参数、cron表达式等
sys_job_log
表(多):用于记录定时任务的执行日志,包括任务的开始执行时间、结束执行时间、执行结果等
2.Quartz体系结构
3.Quartz核心API
4.定时任务执行
5.添加定时任务
6.定时任务状态修改
刚才我们分析新增定时任务的源码时,发现了任务在初始化时是处于暂停状态的。
如果要启动任务,可以在页面进行任务状态的开关控制,所以接下来我们对此功能的源码进行分析
5.2集群模式
首先我们来聊下为什么需要quartz集群
在单机模式下,默认所有的jobDetail
和trigger
都存储在内存中。这样做的好处是读取速度快,但缺点也很明显:一旦服务器故障,所有的任务数据就会丢失,这就是所谓的单点故障问题。
还有如果在一个高峰时段,比如上午9点,需要触发500个任务,这将给服务器带来巨大的负载压力。这不仅影响性能,还可能引发服务中断。
缺点:单点故障、负载压力大
为了解决这些问题,我们可以部署多个服务器节点,将任务信息存储到数据库中。这样,多个节点就可以通过共享数据库来协调任务的执行,形成Quartz集群模式。
这种方式不仅解决了单点故障问题,还能通过负载均衡提升效率。
集群模式的优势
-
高可用性:即使某个节点出现问题,其他节点仍然可以正常运行。
-
负载均衡:将任务分散到不同的节点执行,避免单个节点过载。
实现
1.导入sql
将若依提供的quartz.sql
导入到数据库中
2.开启配置
打开dkd-quartz
模块中ScheduleConfig
配置类注释
3.节点复制
首先修改当前SpringBoot的启动类的名称
我们再添加(复制)一个SpringBoot的启动配置
-Dserver.port=8081
4.观察数据库
重启项目即可,观察数据库,已存入jobDetail和trigger,多个服务器节点可以实现共享
6.数据权限
在系统中,权限的分配和控制主要依赖于角色。每个角色可以被赋予不同的菜单权限和数据权限,用户则通过他们的角色来继承这些权限,进而决定他们能访问哪些系统资源。
目前,系统支持以下五种数据权限类型:
-
全部数据权限:无限制访问所有数据,相当于拥有最高权限的通行证。
-
自定数据权限:用户可以根据自己的需求设定访问特定数据的规则。
-
部门数据权限:只能访问自己所在部门的数据,限制在本部门范围内。
-
部门及以下数据权限:可以访问自己部门及下属部门的数据,适用于管理层级。
-
仅本人数据权限:只能访问和操作自己的数据,保障个人隐私和数据隔离。
1.源码
1、若依系统的数据权限设计主要通过用户、角色、部门表建立关系,实现对数据的访问控制:
2、在需要数据权限控制方法上添加@DataScope
注解,其中d
和u
用来表示表的别名
3、在mybatis
查询底部标签添加数据范围过滤
其作用就是相当于在一个 select 语句后面拼接一个 and 条件语句,来实现查询限制
若依数据权限底层使用了自定义注解+AOP切面+SQL拼接
-
com.dkd.common.annotation.DataScope 自定义注解
-
com.ruoyi.framework.aspectj.DataScopeAspect:切面类
-
通过实现AOP编程,对目标方法进行拦截(标注DataScope 注解的方法),实现了构建数据范围SQL过滤条件
-
仅实体继承`BaseEntity`才会进行处理,`SQL`语句会存放到`BaseEntity`对象中的`params`属性中,然后在`xml`中通过`${params.dataScope}`获取拼接后的语句。
2.改造
需求
我们有一个系统登录日志,里面记录了所有用户的登录信息。
但是,并不是所有人都应该看到所有的日志数据。所以,我们需要根据用户的角色来控制他们能查看的数据范围。
(1)添加权限注解
在dkd-system
模块的com.dkd.system.service.impl.SysLogininforServiceImpl
在服务层的方法上使用 @DataScope
注解
(2)添加表字段
如果sys_logininfo
业务表需要实现数据权限,需要有dept_id
和user_id
这两个字段。
(3)添加实体属性
在dkd-system
模块的com.dkd.system.domain.SysLogininfor
实体类中,需要有deptId
和userId
这两个属性。
(4)修改映射文件
在dkd-system
模块的com.dkd.system.domain.SysLogininforMapper.xml
映射文件中,通过动态拼接 SQL,实现数据范围的过滤
(5)异步工厂调整
在dkd-framework
模块的com.dkd.framework.manager.factory.AsyncFactory
异步工厂创建登录日志任务时,需要有deptId
和userId
这两个属性。
相关文章:

若依-原理
1.代码生成器 1.1源码分析 代码生成器分为两个部分: 第一部分涉及将业务表结构导入到系统中 第二部分是点击生成按钮,系统将根据表结构生成相应的前后端代码,并提供下载。 1.表结构说明 gen_table:存储业务表的基本信息 &am…...

台球厅灯控系统如何布线 佳易王桌球计时计费管理系统操作教程
一、前言 台球厅灯控系统如何布线 佳易王桌球计时计费管理系统操作教程 佳易王台球灯控系统可外接灯控设备,用软件来控制灯的开关 开始计时的时候灯点亮,结账后灯自动关闭 二、计时灯控电路图 佳易王计时计费软件配套的灯控设备布线图,如上…...
安卓将本地日志上传到服务器
在安卓开发中,将本地日志上传到服务器是一个常见的需求,特别是在开发需要远程监控或调试的应用时。以下是一个基本的步骤和示例,说明如何实现这一功能: 1 本地日志上传到服务器 1.1 准备服务器 首先,你需要在服务器…...

FloodFill(洪水灌溉)算法专题——DFS深搜篇
目录 1、图像渲染 1.1 算法原理 1.2 算法代码 2、岛屿数量 2.1 算法原理 2.2 算法代码 3、岛屿的最大面积 3.1 算法原理 3.2 算法代码 4、被围绕的区域 4.1 算法原理 4.2 算法代码 5、太平洋大西洋水流问题 5.1 算法原理 5.2 算法代码 6、扫雷游戏 6.1 算法原理…...

直播标准权威发布,阿里云RTS获首批卓越级评估认证
近期举办的2024“可信云大会”上,中国信通院正式发布了2024年上半年音视频领域最新评估结果。阿里云超低延时直播,以首批卓越级,通过中国信通院超低延时直播性能及服务质量分级测试。 标准发布,权威量化直播体验质量 从直播元年发…...

iOS 知识点记录
王巍 博客地址:OneVs Den git地址:onevcat (Wei Wang) GitHub 江湖人称喵神,目前就职于line。喵神的博客涉及方面比较广, 有Obejctive-C, Swift, SwiftUI, Unity等等。博客内容很有深度,非常值得关注。 戴铭 博客地址:戴铭的博客 git地址:ming1016 (戴铭) GitHub 《i…...
C++系列-STL中搜索相关算法
STL中search相关算法 💢search相关算法💢💢search算法举例💢💢search_n算法举例💢💢binary_search算法举例 💢 lower_bound💢 upper_bound💢 lower_bound和up…...
5.C++程序中的注释
我们来看上节所写的程序 #include <iostream> using namespace std;void prnt() //打印A {cout << "printA" << endl; }int main() {prnt();return 0; } 上面的程序中“//打印A”,表示说明当前函数是打印内容的函数,具体…...
com.kingbase8.util.KSQLException: ERROR: permission denied for table xxx
前言 在信创改造中,数据库替换为国产数据库是不可缺少的一部分。而可替换选项中多数选项无非是人大金仓和达梦数据库二选一。本文将介绍人大金仓在使用过程的问题以及解决办法。 问题 在使用人大金仓数据库后,程序运行报错 com.kingbase8.util.KSQLEx…...

开发小程序
由于之前购入的阿里云ECS放着落灰,碰巧又看到个有趣的项目,于是就做了个生成头像的小程序…由于第一次完整发布小程序,记录一下遇到的问题 小程序名称:靓仔创意头像 😂 关于小程序 接口请求,在开发过程中…...
JS考核答案
1.请简述var, let, const的区别? (1)块级作用域:块作用域由 { }包括,let和const具有块级作用域,var不存在块级作用域。块级作用域解决了ES5中的两个问题: 内层变量可能覆盖外层变量 用来计数的…...

高德地图2.0 绘制、编辑多边形覆盖物(电子围栏)
1. 安装 npm i amap/amap-jsapi-loader --save移步:官方文档 2. map组件封装 <script lang"ts" setup> import AMapLoader from amap/amap-jsapi-loader import { onMounted, ref } from vue import { propTypes } from /utils/propTypesdefineO…...

MySQL底层为什么选择用B+树作为索引
首先,我们来想想为什么这么多数据结构,为什么要用树这种数据结构? 众多的数据结构在逻辑层面可分为:线性结构 和 非线性结构。 线性结构有:数组、链表,基于它们衍生出的有哈希表(哈希表也称散…...

MATLAB系列05:自定义函数
MATLAB系列05:自定义函数 5. 自定义函数5.1 MATLAB函数简介5.2 在MATLAB中传递变量:按值传递机制5.3 选择性参数5.4 用全局内存分享数据5.5 在函数两次调用之间本地数据的存储5.6 函数的函数(function functions)5.7 子函数和私有函数5.8 总结 5. 自定义…...

C++速通LeetCode简单第20题-多数元素
方法一:暴力解法,放multiset中排序,然后依次count统计,不满足条件的值erase清除。 class Solution { public:int majorityElement(vector<int>& nums) {int ans 0;multiset<int> s;for(int i 0;i < nums.s…...

回收站永久删除的文件还能恢复吗?教你恢复技巧
在数字时代,电脑是我们工作、学习和娱乐的重要工具。然而,随着我们对电脑的频繁使用,误删文件的情况也时有发生。当我们在回收站中不小心永久删除了某个重要文件时,内心可能会充满焦虑和疑惑:这些文件还能恢复吗&#…...
Python Web 微服务架构全面解析与实战指南
Python Web 微服务架构全面解析与实战指南 目录 🏗️ 微服务基础概念 微服务架构与单体架构的对比微服务的优点与挑战 🔄 服务间通信 使用REST、gRPC或消息队列实现服务通信API网关的使用(如Kong、Traefik) 🔍 服务…...

SEAFARING靶场漏洞攻略
寻找漏洞 一,我们打开页面 第一个漏洞 xss漏洞 1.在登录页面显示有弹窗 第二个漏洞 sql注入漏洞 1.在输入框的地方输入-1 union select 1,2,3#我们来查看他的回显点 2.查看数据库表名 -1 union select 1,database(),3# 3.查看表名 -1 union select 1,2,group…...

ROS 编程入门的介绍
2.1 创建 ROS 功能包 ROS(Robot Operating System)是一种开源的机器人软件框架,广泛用于机器人开发中。通过使用 ROS,开发者可以轻松创建和管理机器人应用程序。在本节中,我们将介绍如何创建一个 ROS 功能包并实现一些…...
第十一章 抽象类与接口
一、抽象类和抽象方法 抽象类:使用abstract修饰的类 抽象方法:在类中没有方法体的方法,称为抽象方法,抽象方法用abstract修饰 抽象类中可以没有抽象方法,包含抽象方法的类必是抽象类 如果子类没有实现父类中的全部…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...

【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...