当前位置: 首页 > news >正文

Spring Boot 3 集成 Spring Security(3)数据管理

文章目录

    • 准备工作
      • 新建项目
      • 引入MyBatis-Plus依赖
      • 创建表结构
      • 生成基础代码
    • 逻辑实现
      • `application.yml`配置
      • SecurityConfig 配置
      • 自定义 UserDetailsService
      • 创建测试
    • 启动测试

在前面的文章中我们介绍了 《Spring Boot 3 集成 Spring Security(1)认证》和 《Spring Boot 3 集成 Spring Security(2)授权》,这篇博客将介绍如何在 Spring Boot 3 项目中,整合 Spring Security 和 MyBatis-Plus ,轻松实现基于数据库的用户访问控制、权限管理。

准备工作

新建项目

springboot3-security-mysql-example 引入依赖

在这里插入图片描述

引入MyBatis-Plus依赖

MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

注意事项

版本 3.5.9+ 开始修改为可选依赖,具体查看下文 maven bom 部分。

  <mybatisplus.version>3.5.9</mybatisplus.version>
    <!-- MyBatis-Plus https://baomidou.com--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-jsqlparser</artifactId></dependency>
    <dependencyManagement><dependencies><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-bom</artifactId><version>${mybatisplus.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

创建表结构

这里我们定义三张表,来实现用户角色权限的操作

在这里插入图片描述

-- 用户表
CREATE TABLE `sys_user` (`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'ID',`username` VARCHAR ( 64 ) DEFAULT NULL COMMENT '用户名',`password` VARCHAR ( 64 ) DEFAULT NULL COMMENT '密码',`sex` CHAR ( 1 ) DEFAULT '0' COMMENT '性别 0 男 1 女 2 未知',`nick_name` VARCHAR ( 64 ) DEFAULT NULL COMMENT '昵称',`status` CHAR ( 1 ) DEFAULT '1' COMMENT '账号状态 0 禁用 1 启用',`valid` INT DEFAULT '1' COMMENT '有效状态 0 无效 1 有效',
PRIMARY KEY ( `id` ) 
) ENGINE = INNODB COMMENT = '用户';INSERT INTO `sys_user` (`id`, `username`, `password`, `sex`, `nick_name`, `status`, `valid`) VALUES (1, 'admin', '$2a$10$xZdonloiiL6YfoLZv6mrJuvxtD238uHPIKkVDpQKBuZxzMDpTf8uK', '0', '管理员张三', '1', 1);
INSERT INTO `sys_user` (`id`, `username`, `password`, `sex`, `nick_name`, `status`, `valid`) VALUES (2, 'user', '$2a$10$evM9SfvuN/E.ykWWOf6b3eTltPvuc6XjwW/qIhagSjlsTfi9l26Ba', '0', '用户李四', '1', 1);-- 角色表
CREATE TABLE `sys_role` (`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'ID',`name` VARCHAR ( 64 ) DEFAULT NULL COMMENT '角色名',`code` VARCHAR ( 64 ) DEFAULT NULL COMMENT '密码',`status` CHAR ( 1 ) DEFAULT '1' COMMENT '状态 0 禁用 1 启用',`valid` INT DEFAULT '1' COMMENT '有效状态 0 无效 1 有效',
PRIMARY KEY ( `id` ) 
) ENGINE = INNODB COMMENT = '角色';INSERT INTO `sys_role` (`id`, `name`, `code`, `status`, `valid`) VALUES (1, '管理员', 'ROOT', '1', 1);
INSERT INTO `sys_role` (`id`, `name`, `code`, `status`, `valid`) VALUES (2, '普通用户', 'USER', '1', 1);-- 用户角色关系表
CREATE TABLE `sys_user_role` (`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'ID',`user_id` bigint DEFAULT NULL COMMENT '用户ID',`role_id` bigint DEFAULT NULL COMMENT '角色ID',PRIMARY KEY (`id`) USING BTREE
) ENGINE = INNODB COMMENT = '用户角色关系表';INSERT INTO `sys_user_role` (`id`, `user_id`, `role_id`) VALUES (1, 1, 1);
INSERT INTO `sys_user_role` (`id`, `user_id`, `role_id`) VALUES (2, 2, 2);

默认设置账户密码123456,在数据库中使用加密后的密码,关于密码加密,可以使用下面的测试方法。

    public static void main(String[] args) {BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();String result = encoder.encode("123456");// 输出加密后的密码System.out.println(result);// 对比加密后的密码和明文密码System.out.println(encoder.matches("123456", result));}

生成基础代码

这里我用了代码生成器插件,以提高生产效率,想具体了解,可以去官网上搭建使用。这里就不多说啦

在这里插入图片描述

本地代码勾选,使用 mybatis-plus 3

在这里插入图片描述

在这里插入图片描述

准备工作到这里基本上就可以了,接下来开始实现从数据库中读取用户角色权限

逻辑实现

application.yml配置

spring:thymeleaf:# 设置Thymeleaf模板文件的前缀位置(默认是`src/main/resources/templates`)prefix: classpath:/templates/# 设置模板文件的后缀(默认是`.html`)suffix: .html# 设置模板模式(默认是HTML5,Thymeleaf 3中为`HTML`)mode: HTML# 开启模板缓存(开发时建议关闭,生产时开启)cache: falsedatasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/security_data?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghaiusername: rootpassword: root#mybatis
mybatis-plus:mapper-locations: classpath*:/mapper/**/*.xml#实体扫描,多个package用逗号或者分号分隔typeAliasesPackage: cn.harry.*.domainglobal-config:#数据库相关配置db-config:#主键类型  AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";id-type: AUTO# 逻辑删除全局属性名(驼峰和下划线都支持)logic-delete-field: validlogic-delete-value: 0 # 逻辑已删除值(默认为 1)logic-not-delete-value: 1 # 逻辑未删除值(默认为 0)banner: false#原生配置configuration:map-underscore-to-camel-case: truecache-enabled: falsecall-setters-on-nulls: truejdbc-type-for-null: 'null'# 这个配置会将执行的sql打印出来,在开发或测试的时候可以用log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

SecurityConfig 配置

要使用 Spring Security 进行用户认证,我们需要配置 SecurityConfig,并实现自定义的 UserDetailsService 来与数据库中的用户信息进行集成。


/*** @author harry* @公众号 Harry技术*/
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(securedEnabled = true) // 开启方法级别的权限控制
@RequiredArgsConstructor
public class SecurityConfig {// 通过构造函数注入自定义UserDetailsServiceprivate final UserDetailsService userDetailsService;@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(auth -> auth// 公开访问.requestMatchers("/").permitAll()// 其他接口需认证.anyRequest().authenticated()).userDetailsService(userDetailsService)
//                .exceptionHandling(exception -> exception
//                        .authenticationEntryPoint(restAuthenticationEntryPoint)
//                        .accessDeniedHandler(restfulAccessDeniedHandler)
//                )// 开启基于表单的登录.formLogin(Customizer.withDefaults())//                // 开启注销功能
//                .logout(Customizer.withDefaults())
//                // 开启 HTTP Basic 认证
//                .httpBasic(Customizer.withDefaults())
//                // 开启 CSRF 防护
//                .csrf(Customizer.withDefaults())
//                // 开启跨域资源共享
//                .cors(Customizer.withDefaults());return http.build();}@Beanpublic PasswordEncoder passwordEncoder() {// 使用 BCrypt 进行密码加密return new BCryptPasswordEncoder();}

自定义 UserDetailsService

想从数据库加载用户信息,就需要创建一个自定义的 UserDetailsService 实现类,它的主要作用:

用户认证:
UserDetailsService 负责从数据源(如数据库、LDAP等)中加载用户特定的安全信息,包括用户名、密码和权限(角色)。
Spring Security 使用 UserDetailsService 来验证用户提供的凭据是否正确。
用户授权:
加载用户的权限信息,以便在认证成功后进行授权检查。
权限信息通常包括用户的角色(如 ROLE_ADMIN, ROLE_USER 等),这些角色用于控制用户可以访问的资源和操作。

/*** 系统用户认证  service** @author harry* @公众号 Harry技术*/
@Slf4j
@Service
@RequiredArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {private final SysUserMapper sysUserMapper;private final SysUserRoleMapper sysUserRoleMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {try {// 获取登录用户信息SysUser user = sysUserMapper.selectByUsername(username);// 用户不存在、用户停用 等校验 TODOLong useId = user.getId();// 获取角色Set<String> roles = sysUserRoleMapper.listRoleKeyByUserId(useId);return new SysUserDetails(user, roles, username);} catch (Exception e) {log.error("loadUserByUsername error", e);}return null;}
}

我们根据数据库中的用户信息加载用户,并将角色转换为 Spring Security 能识别的格式。我们写一个SysUserDetails类来实现自定义Spring Security 用户对象。


/*** 自定义 Spring Security 用户对象** @author harry* @公众号 Harry技术*/
@Data
@NoArgsConstructor
public class SysUserDetails implements UserDetails {private String username;private SysUser sysUser;private Collection<SimpleGrantedAuthority> authorities;public SysUserDetails(SysUser user, Set<String> roles, String username) {this.sysUser = user;Set<SimpleGrantedAuthority> authorities;if (CollectionUtil.isNotEmpty(roles)) {// 标识角色 前面加上 ROLE_authorities = roles.stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role)).collect(Collectors.toSet());} else {authorities = Collections.emptySet();}this.authorities = authorities;this.username = username;}@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {// 返回当前用户的权限return authorities;}@Overridepublic String getPassword() {return sysUser.getPassword();}@Overridepublic String getUsername() {return this.username;}/*** 是否可用 ,禁用的用户不能身份验证** @return 是否可用*/@Overridepublic boolean isEnabled() {return StatusEnums.ENABLE.getKey().equals(sysUser.getStatus());}
}

创建测试

  • 页面
  <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title><style>.content {width: 800px;height: 800px;text-align: center;line-height: 100px;font-size: 20px;flex: 1;flex-direction: column;display: flex;justify-content: center;align-items: center;}</style></head><body><div class="content"><!--去登陆 --><a href="/login">去登陆</a><!-- admin/info 接口 --><a href="/admin/info">访问 admin/info 接口</a><!-- 去首页 --><a href="/user/info">访问 user/info 接口</a><!--退出--><a href="/logout">退出</a></div></body></html>
  • 接口

    改写接口admin/info,并配置 @PreAuthorize("hasRole('ROOT')")只有 ADMIN 角色才能访问

  /*** @author harry* @公众号 Harry技术* Spring Boot 3 集成 Spring Security(2) 授权: https://mp.weixin.qq.com/s/HzzcYIQLnch_7r7wdUarew*/@Slf4j@RestControllerpublic class AdminController {@GetMapping("/admin/info")@PreAuthorize("hasRole('ROOT')")  // 只有 ADMIN 角色才能访问public SysUserDetails adminInfo() {// 获取当前登录的用户信息SysUserDetails user = (SysUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();log.info("当前登录的用户信息:{}", user.toString());return user;}}

改写接口user/info,并配置 @PreAuthorize("hasRole('USER')")只有 USER 角色才能访问

      @Slf4j@RestControllerpublic class UserController {@GetMapping("/user/info")@PreAuthorize("hasRole('USER')")  // 只有 user 角色才能访问public SysUserDetails userInfo() {// 获取当前登录的用户信息SysUserDetails user = (SysUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();log.info("当前登录的用户信息:{}", user.toString());return user;}}

启动测试

  • 1.登录admin账户

访问 admin/info 接口

在这里插入图片描述

访问 user/info 接口

在这里插入图片描述

  • 2.登录user用户

访问 admin/info 接口

在这里插入图片描述

访问 user/info 接口

在这里插入图片描述

通过上面的测试用例,通过定义用户和角色实体、实现自定义的 UserDetailsService,实现了数据库驱动的用户认证和基于角色的授权机制。这种结合方式不仅在安全性上提供了极大的灵活性,也让数据管理变得更加简洁高效。

关注我,在后续的文章中,我们进一步探讨如果使用JWT、OAuth2 等机制、使用Redis作为缓存来强化认证与授权的实现。

示例源码:关注公众号“Harry技术”,回复 security 获取源码地址。

相关文章:

Spring Boot 3 集成 Spring Security(3)数据管理

文章目录 准备工作新建项目引入MyBatis-Plus依赖创建表结构生成基础代码 逻辑实现application.yml配置SecurityConfig 配置自定义 UserDetailsService创建测试 启动测试 在前面的文章中我们介绍了 《Spring Boot 3 集成 Spring Security&#xff08;1&#xff09;认证》和 《…...

书生大模型实战营第四期-入门岛-4. maas课程任务

书生大模型实战营第四期-入门岛-4. maas课程任务 任务一、模型下载 任务内容 使用Hugging Face平台、魔搭社区平台&#xff08;可选&#xff09;和魔乐社区平台&#xff08;可选&#xff09;下载文档中提到的模型&#xff08;至少需要下载config.json文件、model.safetensor…...

Spring ApplicationListener监听

【JavaWeb】Spring ApplicationListener-CSDN博客 ApplicationEvent以及Listener是Spring为我们提供的一个事件监听、订阅的实现&#xff0c;内部实现原理是观察者设计模式&#xff0c;设计初衷也是为了系统业务逻辑之间的解耦&#xff0c;提高可扩展性以及可维护性。事件发布…...

K8s调度器扩展(scheduler)

1.K8S调度器 筛选插件扩展 为了熟悉 K8S调度器扩展步骤&#xff0c;目前只修改 筛选 插件 准备环境&#xff08;到GitHub直接下载压缩包&#xff0c;然后解压&#xff0c;解压要在Linux系统下完成&#xff09; 2. 编写调度器插件代码 在 Kubernetes 源代码目录下编写调度插件…...

IntelliJ IDEA 中,自动导包功能

在 IntelliJ IDEA 中&#xff0c;自动导包功能可以极大地提高开发效率&#xff0c;减少手动导入包所带来的繁琐和错误。以下是如何在 IntelliJ IDEA 中设置和使用自动导包功能的详细步骤&#xff1a; 一、设置自动导包 打开 IntelliJ IDEA&#xff1a; 启动 IntelliJ IDEA 并打…...

Spring事务笔记

目录 1.Spring 编程式事务 2.Transactional 3.事务隔离级别 4.Spring 事务传播机制 什么是事务? 事务是⼀组操作的集合, 是⼀个不可分割的操作. 事务会把所有的操作作为⼀个整体, ⼀起向数据库提交或者是撤销操作请求. 所以这组操作要么同时成 功, 要么同时失败 1.Spri…...

SQLite 管理工具 SQLiteStudio 3.4.5 发布

SQLiteStudio 3.4.5 版本现已发布&#xff0c;它带来了大量的 bug 修复&#xff0c;并增加了一些小功能。SQLiteStudio 是一个跨平台的 SQLite 数据库的管理工具。 具体更新内容包括&#xff1a; 现在可以使用 Collations Editor 窗口在数据库中注册 Extension-based collatio…...

QT 实现组织树状图

1.实现效果 在Qt中使用QGraphicsItem和QGraphicsScene实现树状图,你需要创建自定义的QGraphicsItem类来表示树的节点,并管理它们的位置和连接,以下是实现效果图。 2.实现思路 可以看见,上图所示,我们需要自定义连线类和节点类。 每个节点类Node,需要绘制矩形框体文字…...

go-学习

文章目录 简介标识符字符串的拼接&#xff0c;关键字数据类型声明变量常量算术运算符关系运算符逻辑运算符位运算赋值运算符其他运算符 简介 Go 语言的基础组成有以下几个部分&#xff1a; 1.包声明 2.引入包 3.函数 4.变量 5.语句 & 表达式 6.注释 package main import &q…...

【面试分享】主流编程语言的内存回收机制及其优缺点

以下是几种主流编程语言的内存回收机制及其优缺点&#xff1a; 一、Java 内存回收机制&#xff1a; Java 使用自动内存管理&#xff0c;主要通过垃圾回收器&#xff08;Garbage Collector&#xff0c;GC&#xff09;来回收不再被使用的对象所占用的内存。Java 的垃圾回收器会定…...

STM32-- 串口发送数据

while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)RESET);&#xff1f;&#xff1f; 答&#xff1a; 这行代码&#xff1a; while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) RESET);的作用是等待串口 USART2 的发送数据寄存器&#xff08;TXE&#xff0c;Transmit Dat…...

数据结构 (13)串的应用举例

前言 数据结构中的串&#xff08;String&#xff09;&#xff0c;也称为字符串&#xff0c;是一种常见且重要的数据结构&#xff0c;在计算机科学中被广泛应用于各种场景。 一、文本处理 文本编辑器&#xff1a;在文本编辑器中&#xff0c;字符串被用来表示和存储用户输入的文本…...

qt-- - 版本和下载介绍

qt版本很多&#xff0c;每个大版本都有几个版本是长期支持的&#xff08;LTS&#xff09;&#xff0c;最好使用长期支持的。 例如qt5.15 qt6.2 qt6.8 都是LTS版本的。 qt在线安装需要提供账号&#xff0c;之前安装qt6.8因为账号问题试了很长时间&#xff0c;密码错了。 …...

解锁 Vue 项目中 TSX 配置与应用简单攻略

在 Vue 项目中配置 TSX 写法 在 Vue 项目中使用 TSX 可以为我们带来更灵活、高效的开发体验&#xff0c;特别是在处理复杂组件逻辑和动态渲染时。以下是详细的配置步骤&#xff1a; 一、安装相关依赖 首先&#xff0c;我们需要在命令行中输入以下命令来安装 vitejs/plugin-v…...

ShuffleNet:一种为移动设备设计的极致高效的卷积神经网络

摘要 https://arxiv.org/pdf/1707.01083 我们介绍了一种名为ShuffleNet的计算效率极高的卷积神经网络&#xff08;CNN&#xff09;架构&#xff0c;该架构专为计算能力非常有限的移动设备&#xff08;例如10-150 MFLOPs&#xff09;而设计。新架构利用两种新操作&#xff1a;逐…...

yum源问题的解决方案

linux课堂作业 问题描述 yum 直接安装tree的问题截图 这个错误表明你的系统没有正确注册到 Red Hat Subscription Management&#xff08;这个问题不用管&#xff09;&#xff0c;也没有配置有效的 YUM 软件仓库&#xff0c;因此无法安装或更新软件包。 解决方案&#xff08…...

在Linux中备份msyql数据库和表的详细操作

目录 前情提要 一、备份mysql数据库 原库展示 (一)新建一个数据库 (二)在linux根目录下找个位置暂时存放 (三)临时sql还原真正存放到库中 (四)查看是否备份成功 备份库成功展示 二、备份表的操作 ​编辑 原表emp展示 (一)快速新建一个原结构相同的表 (二)原表所…...

实时数仓Kappa架构:从入门到实战

引言 随着大数据技术的不断发展&#xff0c;企业对实时数据处理和分析的需求日益增长。实时数仓&#xff08;Real-Time Data Warehouse, RTDW&#xff09;应运而生&#xff0c;其中Kappa架构作为一种简化的数据处理架构&#xff0c;通过统一的流处理框架&#xff0c;解决了传统…...

【老白学 Java】Warship v2.0(四)

Warship v2.0&#xff08;四&#xff09; 文章来源&#xff1a;《Head First Java》修炼感悟。 上一篇文章中&#xff0c;老白仔细分析了 v2.0 的设计思路以及实现手段&#xff0c;如果大家有好的设计方案也可以自行尝试。 本篇文章的主要内容是对 Warship 类进行最后的修改&a…...

LLM之学习笔记(一)

前言 记录一下自己的学习历程&#xff0c;也怕自己忘掉了某些知识点 Prefix LM 和 Causal LM区别是什么&#xff1f; Prefix LM &#xff08;前缀语⾔模型&#xff09;和 Causal LM&#xff08;因果语言模型&#xff09;是两者不同类型的语言模型&#xff0c;它们的区别在于生…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

若依项目部署--传统架构--未完待续

若依项目介绍 项目源码获取 #Git工具下载 dnf -y install git #若依项目获取 git clone https://gitee.com/y_project/RuoYi-Vue.git项目背景 随着企业信息化需求的增加&#xff0c;传统开发模式存在效率低&#xff0c;重复劳动多等问题。若依项目通过整合主流技术框架&…...