若依-原理
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修饰 抽象类中可以没有抽象方法,包含抽象方法的类必是抽象类 如果子类没有实现父类中的全部…...
2026在线测评系统十大量表对比:信效度与场景全解析
【30s 核心摘要】2026 年在线测评成人才管理刚需,信效度与场景适配成选型核心。本文聚焦十大量表,从信度、效度、适配场景等维度深度对比,重点解析问卷星、北森、金数据等主流平台的量表能力与落地效果,为企业、高校及机构提供科学…...
AI赋能5G核心网故障诊断:从PCAP解析到智能根因分析的工程实践
1. 项目概述:当AI遇见5G核心网故障诊断在5G核心网的运维与测试一线干了这么多年,最头疼的莫过于面对海量的PCAP抓包文件。一个复杂的信令流程下来,动辄几千甚至上万个数据包,工程师需要像侦探一样,逐帧审视协议交互&am…...
从STM32迁移到普冉PY32F003:UART代码移植保姆级教程(附HAL库对比)
从STM32到普冉PY32F003的UART代码迁移实战指南 1. 国产MCU替代浪潮下的技术选择 近年来,半导体行业的供应链波动促使更多工程师将目光投向国产MCU解决方案。普冉PY32F003系列作为Cortex-M0内核的代表产品,以48MHz主频、64KB Flash和8KB RAM的配置&#x…...
小米MIMO最新邀请码
欢迎使用,各得10元体验金...
探索Windows 10上的Android世界:揭秘WSA-Windows-10项目的3个技术突破
探索Windows 10上的Android世界:揭秘WSA-Windows-10项目的3个技术突破 【免费下载链接】WSA-Windows-10 This is a backport of Windows Subsystem for Android to Windows 10. 项目地址: https://gitcode.com/gh_mirrors/ws/WSA-Windows-10 想象一下&#…...
基于IRS2092的200W D类功放设计:从PWM原理到保护电路实战
1. 项目概述与核心思路折腾音响功放,从经典的AB类玩到D类,感觉就像是从燃油车换到了电动车,动力响应和效率完全是两个维度。这次要聊的这块“200W Class-D Audio Power Amplifier [150115]”单板功放,就是一个非常典型的D类功放设…...
企业云盘签章技术方案:从数字签名原理到工程落地
背景 电子签章在企业云盘中的落地,不只是一个"上传盖章图片"的功能实现。本质上,它是一套涉及数字签名、PKI基础设施、文档完整性校验的综合性技术方案。本文从技术选型角度,说清楚企业云盘内置签章需要解决哪些问题、主流实现方案…...
Go开发者必备:circuitbreaker API全解析与最佳实践指南 [特殊字符]
Go开发者必备:circuitbreaker API全解析与最佳实践指南 🚀 【免费下载链接】circuitbreaker Circuit Breakers in Go 项目地址: https://gitcode.com/gh_mirrors/circ/circuitbreaker 作为一名Go开发者,你是否经常遇到远程服务调用失败…...
反向海淘站点常见配置故障复盘与数据一致性优化方案
摘要反向海淘独立站运行过程中,容易出现价格换算异常、页面语种错乱、商品同步失败、订单状态停滞、运费计算偏差等问题。多数故障并非系统底层缺陷,而是配置逻辑理解偏差、数据规范不统一引发。本文结合实际运维场景,汇总高频故障成因&#…...
CANN runtime:昇腾NPU 运行时的职责边界
个人主页:ujainu 文章目录前言为什么需要运行时这一层runtime管什么,不管什么Stream:并行的基本调度单位Event:跨Stream的同步锚点内存池化:少一次malloc就少一次卡顿任务队列:从计算图到硬件指令的最后一跳…...
