Spring Security——基于MyBatis
目录
项目总结
新建一个项目
pom.xml
application.properties配置文件
User实体类
UserMapper映射接口
UserService访问数据库中的用户信息
WebSecurityConfig配置类
MyAuthenticationFailureHandler登录失败后
MyAuthenticationSuccessHandlerw登录成功后
WebSecurityController控制器
home.html主页
login.html登录页面
resource.html资源页面
SpringSecurityApplication启动类
SpringSecurityApplicationTests测试类
项目测试
参考文章:
- 1、http://t.csdnimg.cn/BRfSZ
- 国内目前常用的两个数据库操作框架:Spring Data JPA和MyBatis,只需掌握一个即可
- Spring Security整合MyBatis的特点:
1. 灵活性
- 自定义认证与授权逻辑:通过实现
UserDetailsService
接口,你可以完全控制用户认证和授权的逻辑,可以从数据库中加载用户信息并进行权限分配。- 自定义加密方式:Spring Security 提供了各种密码加密器,如
BCryptPasswordEncoder
,你可以选择或自定义适合项目的加密方式。2. 高效的数据访问
- MyBatis 的持久化层:利用 MyBatis 强大的 SQL 映射功能,可以高效地执行复杂的数据库查询和更新操作。MyBatis 支持动态 SQL,方便实现复杂的查询需求。
- 缓存机制:MyBatis 提供一级缓存和二级缓存机制,可以显著提高数据访问效率。
3. 安全性
- 强大的安全功能:Spring Security 提供了全面的安全解决方案,包括认证、授权、攻击防护(如 CSRF、Session Fixation)、安全策略配置等。
- 细粒度的权限控制:通过 Spring Security,可以对 URL 路径、方法调用、领域对象等进行细粒度的权限控制,确保应用的各个部分都得到充分保护。
4. 良好的扩展性
- 插件支持:MyBatis 支持多种插件,可以轻松扩展功能,比如分页插件、日志插件等。
- Spring Security 的过滤器链:Spring Security 的过滤器链机制允许你自定义和扩展安全过滤器,满足特定需求。
5. 简化开发
- 注解支持:使用注解可以大大简化配置,如
@Mapper
注解用于 MyBatis 的 Mapper,@EnableWebSecurity
用于启用 Spring Security。- 配置简洁:结合 Spring Boot,可以通过少量的配置文件(如
application.properties
)快速集成 Spring Security 和 MyBatis。6. 性能优化
- 懒加载:MyBatis 支持懒加载,可以在需要时才加载关联数据,减少不必要的数据传输。
- 批量操作:MyBatis 支持批量插入、更新和删除操作,提升数据库操作性能。
项目总结
- 项目特点:
- 多用户认证与授权:用户信息存储在数据库里,有用户登录时,调取数据库里的用户信息进行验证
- 密码加密
- 保护资源:登录成功后才能访问指定资源
- 运行流程:
1、用户请求登录页面:
- 用户访问
/login
URL,Spring Security 自动处理这个请求并返回登录页面。2、用户提交登录表单:
- 用户在登录页面输入用户名和密码,然后提交表单。
- 表单提交到
/login
(默认 URL),由 Spring Security 处理。3、Spring Security 处理认证请求:
- Spring Security 捕获表单提交请求,提取用户名和密码。
- 使用配置的
UserDetailsService
加载用户信息。4、UserService 加载用户信息:
- UserService 调用
UserMapper
从数据库中查询用户信息。- 如果找到用户,将数据封装到
User
对象中返回给 Spring Security。5、密码验证:
- Spring Security 使用配置的
PasswordEncoder
对用户提交的密码进行加密,并与数据库中的加密密码进行比对。- 如果密码匹配,认证成功;否则,认证失败。
6、授权过程:
- 认证成功后,Spring Security 根据配置的权限规则(如 URL 访问控制)决定用户可以访问哪些资源。
- 如果用户尝试访问受保护的资源,Spring Security 会检查用户是否具有相应的权限。
7、处理用户请求:
- 如果用户有权限访问请求的资源,Spring Security 将请求转发给相应的控制器。
- 控制器处理请求,执行相应的业务逻辑,并返回视图或数据。
8、返回响应:
- 控制器返回的结果通过视图解析器或直接以 JSON 格式返回给用户。
- 最终用户在浏览器中看到响应结果。
新建一个项目
项目结构:
创建数据库、表
CREATE DATABASE security;
USE security;
CREATE TABLE `t_users`(`id` INT AUTO_INCREMENT NOT NULL,`username` VARCHAR(50) NOT NULL,`password` VARCHAR(512) NOT NULL,`enabled` TINYINT(1) NOT NULL DEFAULT '1',`locked` TINYINT(1) NOT NULL DEFAULT '0',`mobile` VARCHAR(11) NOT NULL,`roles` VARCHAR(500),PRIMARY KEY(id)
);
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.12.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.study</groupId><artifactId>spring_security</artifactId><version>0.0.1-SNAPSHOT</version><name>spring_security</name><description>Demo project for Spring Boot</description><properties><java.version>8</java.version></properties><dependencies><!--添加MySQL数据库驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.2</version></dependency><!--为了使用@Data注解--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--以便 Thymeleaf 能够处理 Spring Security 标签--><dependency><groupId>org.thymeleaf.extras</groupId><artifactId>thymeleaf-extras-springsecurity5</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
application.properties配置文件
# 配置视图解析器,表示到resources/templates目录寻找后缀为.html,并且名字和视图名称一致的文件,springboot自动帮你配好了
#spring.mvc.view.prefix=classpath:/templates/
#spring.mvc.view.suffix=.html# 数据库的连接配置
spring.datasource.url=jdbc:mysql://localhost:3306/security?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
User实体类
package com.study.spring_security.entity;import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;import java.util.Collection;/*** UserDetails是一个用于提供核心用户信息的接口*/
@Data
public class User implements UserDetails {private Long id;private String username;private String password;private boolean enabled;private boolean locked;private String mobile;private String roles;/*** 返回授予用户的权限,该方法不能返回null* AuthorityUtils是一个工具类,该类的静态方法commaSeparatedStringToAuthorityList()* 可以将以逗号分隔的字符串表示形式的权限转换为GrantedAuthority对象数组*/@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return AuthorityUtils.commaSeparatedStringToAuthorityList(roles);}/*** 指示用户账户是否已过期,过期的账户无法进行身份验证*/@Overridepublic boolean isAccountNonExpired() {return true;}/*** 指示用户是否被锁定或解锁,无法对被锁定的用户进行身份验证*/@Overridepublic boolean isAccountNonLocked() {return !locked;}/*** 指示用户的凭据(密码)是否已过期,过期的凭据阻止身份验证*/@Overridepublic boolean isCredentialsNonExpired() {return true;}/*** 指示用户是被启用还是被禁用,无法对被禁用的用户进行身份验证*/@Overridepublic boolean isEnabled() {return enabled;}
}
UserMapper映射接口
package com.study.spring_security.mapper;import com.study.spring_security.entity.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Select;@Mapper//标注该接口为MyBatis映射器
public interface UserMapper {@Select("select * from t_users where username=#{username}")User getByUsername(String username);@Insert("insert into t_users(username,password,mobile,roles)"+" values (#{username},#{password},#{mobile},#{roles})")//插入数据后,获取自增长的主键值@Options(useGeneratedKeys = true,keyProperty = "id")int saveUser(User user);
}
UserService访问数据库中的用户信息
package com.study.spring_security.service;import com.study.spring_security.entity.User;
import com.study.spring_security.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;/*** 在loadUserByUsername()方法中访问自定义数据库的用户表和角色表,然后返回一个UserDetails对象即可*/
@Service
public class UserService implements UserDetailsService {@Autowiredprivate UserMapper userMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {User user = userMapper.getByUsername(username);//该方法不允许返回空,如果没有找到用户,或者用户没有授予的权限,则抛出异常if(user==null){throw new UsernameNotFoundException("用户不存在!");}return user;}
}
WebSecurityConfig配置类
package com.study.spring_security.config;import com.study.spring_security.config.handler.MyAuthenticationFailureHandler;
import com.study.spring_security.config.handler.MyAuthenticationSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;@EnableWebSecurity//声明这是一个Spring Security安全配置类,无需再另加注解@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate MyAuthenticationSuccessHandler authenticationSuccessHandler;@Autowiredprivate MyAuthenticationFailureHandler authenticationFailureHandler;//配置当前项目的登录和拦截信息@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests()//允许所有用户访问/home,/login.antMatchers("/home","/login").permitAll().anyRequest().authenticated().and().formLogin().loginPage("/login")//指定登录页面.successHandler(authenticationSuccessHandler)//验证成功的处理器.failureHandler(authenticationFailureHandler)//验证失败的处理器//身份验证成功后默认重定向的页面.defaultSuccessUrl("/home",true).permitAll().and().logout().permitAll();}/*** 密码编码器* 当用户登录时,应用程序会获取用户输入的明文密码,并使用相同的 PasswordEncoder 对其进行编码,然后与存储在数据库中的哈希值进行比较。* 由于密码是用不可逆的哈希算法进行编码的,因此即使有人获取了哈希值,也无法轻易地反推出原始密码。* 这种设计提高了密码存储的安全性。*/@Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}
}
MyAuthenticationFailureHandler登录失败后
package com.study.spring_security.config.handler;import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/*** 身份验证失败后的处理*/
@Component
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {response.setContentType("application/json;charset=UTF-8");response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);PrintWriter out = response.getWriter();out.write("登录失败!");out.close();}
}
MyAuthenticationSuccessHandlerw登录成功后
package com.study.spring_security.config.handler;import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;/*** 身份验证成功后的处理*/
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {response.setContentType("application/json;charset=UTF-8");PrintWriter out = response.getWriter();out.write("登录成功!");out.close();}
}
WebSecurityController控制器
package com.study.spring_security.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;/*** 1.将configure(HttpSecurity http)方法中设置的不同的URL映射到不同的页面* 2.方法返回的是视图名称,需要视图解析器将视图名称解析成实际的HTML文件* 然后访问url就可以跳转到HTML页面了,否则返回的只是一个字符串* 3.在application.properties配置文件中配置视图解析器,springboot已经默认配置好了,你不用写了*/
@Controller
public class WebSecurityController {/*** 登录后跳转到home.html页面*/@GetMapping("/home")public String home(){return "home";}/*** 登录页面*/@GetMapping("/login")public String login(){return "login";//login.html}/*** 当访问/resource时,会重定向到/login,登录后才可以访问受保护的页面resource.html*/@GetMapping("/resource")public String resource(){return "resource";//resource.html}
}
home.html主页
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>首页</title>
</head>
<body>
<h2>这是首页!</h2>
</body>
</html>
login.html登录页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>登录页面</title>
</head>
<body><div><!--当Spring Security验证失败时,会在URL上附加error查询参数,形式为:http://localhost:8080/login?error--><div class="error" th:if="${param.error}">用户名或密码错误</div><form th:action="@{/login}" method="post"><div><inputname="username"placeholder="请输入用户名"type="text"/></div><div><inputname="password"placeholder="请输入密码"type="password"/></div><div class="submit"><input type="submit" value="登录"/></div></form>
</div>
</body>
</html>
resource.html资源页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head><meta charset="UTF-8"><title>资源页面</title>
</head>
<body>
<h2>欢迎用户<span sec:authentication="name"></span></h2>
<form th:action="@{/logout}" method="post"><input type="submit" value="退出"/>
</form>
</body>
</html>
SpringSecurityApplication启动类
package com.study.spring_security;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@SpringBootApplication
public class SpringSecurityApplication {public static void main(String[] args) {SpringApplication.run(SpringSecurityApplication.class, args);}}
SpringSecurityApplicationTests测试类
package com.study.spring_security.mapper;import com.study.spring_security.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;/*** 单元测试类的包结构与UserMapper接口一致,* 前者为test/java/com/study/spring_security/mapper* 后者为main/java/com/study/spring_security/mapper*/
@SpringBootTest
class SpringSecurityApplicationTests {@Autowiredprivate UserMapper userMapper;/*** 创建两个用户zhang和admin*/@Testvoid saveUser(){User user = new User();user.setUsername("zhang");//使用BCryptPasswordEncoder对提交的密码加密user.setPassword(new BCryptPasswordEncoder().encode("1234"));user.setMobile("18323415151");user.setRoles("ROLE_USER");userMapper.saveUser(user);user=new User();user.setUsername("admin");user.setPassword(new BCryptPasswordEncoder().encode("1234"));user.setMobile("16813512343");user.setRoles("ROLE_USER,ROLE_ADMIN");userMapper.saveUser(user);}}
项目测试
- 先登录mysql,
- 创建数据库、表
- 启动测试类,往数据库添加两条用户信息
- 启动启动类,访问网址:http://localhost:8080/login
- 使用用户信息登录
- 若登录失败,则返回
- 若登录成功,跳转到主页
- 访问资源页面:http://localhost:8080/resource,打印出了用户名,点击退出按钮,退出登录,资源页面受保护,必须登录成功后才能访问
相关文章:
Spring Security——基于MyBatis
目录 项目总结 新建一个项目 pom.xml application.properties配置文件 User实体类 UserMapper映射接口 UserService访问数据库中的用户信息 WebSecurityConfig配置类 MyAuthenticationFailureHandler登录失败后 MyAuthenticationSuccessHandlerw登录成功后 WebSecur…...
Qt——升级系列(Level Four):控件概述、QWidget 核心属性、按钮类控件
目录 控件概述 QWidget 核心属性 核心属性概览 enabled geometry windowTitle windowIcon windowOpacity cursor font toolTip focusPolicy styleSheet 按钮类控件 Push Button Radio Buttion Check Box Tool Button 控件概述 Widget 是 Qt 中的核⼼概念. 英⽂原义是 "…...
品质卓越为你打造App UI 风格
品质卓越为你打造App UI 风格...
ei期刊和sci期刊的区别
ei期刊和sci期刊的区别 ei期刊和sci期刊的区别是什么?Sci和ei都属于国际期刊的一种,但是二者之间存在一些区别,选择期刊投稿时需要注意这些区别。EI期刊刊物的审查周期短,SCI学术期刊的审查期长。难度要求不同,SCI期刊比EI期刊对…...
从零手写实现 nginx-20-placeholder 占位符 $
前言 大家好,我是老马。很高兴遇到你。 我们为 java 开发者实现了 java 版本的 nginx https://github.com/houbb/nginx4j 如果你想知道 servlet 如何处理的,可以参考我的另一个项目: 手写从零实现简易版 tomcat minicat 手写 nginx 系列 …...
leetcode290:单词规律
题目链接:290. 单词规律 - 力扣(LeetCode) class Solution { public:bool wordPattern(string pattern, string s) {unordered_map<char, string> s2t;unordered_map<string, char> t2s;int len pattern.size();int CountSpace…...
IDEA 2022
介绍 【尚硅谷IDEA安装idea实战教程(百万播放,新版来袭)】 jetbrains 中文官网 IDEA 官网 IDEA 从 IDEA 2022.1 版本开始支持 JDK 17,也就是说如果想要使用 JDK 17,那么就要下载 IDEA 2022.1 或之后的版本。 公司…...
Vue TypeScript 实战:掌握静态类型编程
title: Vue TypeScript 实战:掌握静态类型编程 date: 2024/6/10 updated: 2024/6/10 excerpt: 这篇文章介绍了如何在TypeScript环境下为Vue.js应用搭建项目结构,包括初始化配置、创建Vue组件、实现状态管理利用Vuex、配置路由以及性能优化的方法&#x…...
Hudi extraMetadata 研究总结
前言 研究总结 Hudi extraMetadata ,记录研究过程。主要目的是通过 extraMetadata 保存 source 表的 commitTime (checkpoint), 来实现增量读Hudi表写Hudi表时,保存增量读状态的事务性,实现类似于流任务中的 exactly-once 背景需求 有个需求:增量读Hudi表关联其他Hudi…...
Vue31-自定义指令:总结
一、自定义函数的陷阱 1-1、自定义函数名 自定义函数名,不能用驼峰式!!! 示例1: 示例2: 1-2、指令回调函数的this 【回顾】: 所有由vue管理的函数,里面的this直接就是vm实例对象。…...
Windows环境如何使用Flutter Version Manager (fvm)
Windows环境如何使用Flutter Version Manager (fvm) Flutter Version Manager (fvm) 是一个用于管理多个 Flutter SDK 版本的命令行工具,它允许开发者在不同项目之间轻松切换 Flutter 版本。这对于需要维护多个使用不同 Flutter 版本的项目的开发人员来说非常有用。…...
优化Elasticsearch搜索性能:查询调优与索引设计
在构建基于 Elasticsearch 的搜索解决方案时,性能优化是关键。本文将深入探讨如何通过查询调优和索引设计来优化 Elasticsearch 的搜索性能,从而提高用户体验和系统效率。 查询调优 优化查询是提高 Elasticsearch 性能的重要方法。以下是一些有效的查询…...
STM32-17-DAC
STM32-01-认识单片机 STM32-02-基础知识 STM32-03-HAL库 STM32-04-时钟树 STM32-05-SYSTEM文件夹 STM32-06-GPIO STM32-07-外部中断 STM32-08-串口 STM32-09-IWDG和WWDG STM32-10-定时器 STM32-11-电容触摸按键 STM32-12-OLED模块 STM32-13-MPU STM32-14-FSMC_LCD STM32-15-DMA…...
一杯咖啡的艺术 | 如何利用数字孪生技术做出完美的意式浓缩咖啡?
若您对数据分析以及人工智能感兴趣,欢迎与我们一起站在全球视野关注人工智能的发展,与Forrester 、德勤、麦肯锡等全球知名企业共探AI如何加速制造进程, 共同参与6月20日由Altair主办的面向工程师的全球线上人工智能会议“AI for Engineers”…...
使用QT制作QQ登录界面
mywidget.cpp #include "mywidget.h"Mywidget::Mywidget(QWidget *parent): QWidget(parent) {/********制作一个QQ登录界面*********************/this->resize(535,415);//设置登录窗口大小this->setFixedSize(535,415);//固定窗口大小this->setWindowTi…...
代码随想录训练营第七天 344反转字符串 541反转字符串II 替换数字
第一题: 原题链接:344. 反转字符串 - 力扣(LeetCode) 思路: 双指针,一根指向字符串的头部,一根指向字符串的尾部。两个指针向中间移动,交换两根指针指向的值。 代码如下…...
【Python】数据处理:SQLite操作
使用 Python 与 SQLite 进行交互非常方便。SQLite 是一个轻量级的关系数据库,Python 标准库中包含一个名为 sqlite3 的模块,可以直接使用。 import sqlite3数据库连接和管理 连接到 SQLite 数据库。如果数据库文件不存在,则创建一个新数据库…...
NXP RT1060学习总结 - fsl_flexcan 基础CAN函数说明 -3
概要 CAN测试源码: https://download.csdn.net/download/qq_35671135/89425377 根据fsl_flexcan.h文件从文件末尾往前面梳理,总共30个基础CAN函数; 该文章只梳理常规CAN,增强型CAN后面再单独梳理。 使用的是RT1064开发板进行测试…...
2024年第三届数据统计与分析竞赛(B题)数学建模完整思路+完整代码全解全析
你是否在寻找数学建模比赛的突破点?数学建模进阶思路! 详细请查 作为经验丰富的数学建模团队,我们将为你带来2024年第三届数据统计与分析竞赛(B题)的全面解析。这个解决方案包不仅包括完整的代码实现,还有…...
高通Android 12 右边导航栏改成底部显示
最近同事说需要修改右边导航栏到底部,问怎么搞?然后看下源码尝试下。 1、Android 12修改代码路径 frameworks/base/services/core/java/com/android/server/wm/DisplayPolicy.java a/frameworks/base/services/core/java/com/android/server/wm/Display…...
2.6数据报与虚电路
数据报 当作为通信子网用户的端系统要发送一个报文时,在端系统中实现的高层协议先把报文拆成若干个带有序号的数据单元,并在网络层加上地址等控制信息后形成数据报分组(即网络层PDU)中间结点存储分组一段很短的时间,找到最佳的路由后&#x…...
小主机折腾记26
双独立显卡调用问题 前两天将tesla p4从x99大板上拆了下来,将880G5twr上的rx480 4g安装到了x99大板上,预计是dg1输出,rx480做3d运算。安装完驱动后,还想着按照之前tesla p4的设置方法去设置rx480,结果果然,…...
ArrayList浅析
目录 一、ArrayList源码1.1 迭代器1.1.1 Itr源码浅析1.1.2 ListItr源码浅析 1.2 常用方法1.3 System.arraycopy1.4 ArrayList 的创建方式 二、引申问题2.1 ArrayList的大小是如何增加的?2.2 什么情况下你会使用ArrayList2.3 在索引中ArrayList的增加或者删除某个对象…...
Spring Boot整合hibernate-validator实现数据校验
文章目录 概念基本概念常用校验注解 前置内容整合Hibernate Validator快速入门优雅处理参数校验异常其余注解校验自定义校验注解 参考来源 概念 基本概念 Hibernate Validator 是一个参数校验框架,可以非常方便地帮助我们校验应用程序的入参,实现了参数…...
Ubuntu系统中网易云音乐编译安装
项目地址: netease-cloud-music-gtk: Linux 平台下基于 Rust GTK 开发的网易云音乐播放器 目录 1.README.md中按照步骤来 2.安装git 3.报错 sudo apt install cmake sudo apt-get install libdbus-1-dev sudo apt install dnf sudo dnf install gettext 继…...
MPLS标签号
标签被压入在2层与3层之间 称为 2.5层 标签的格式----32 位4 个字节 前 20 位为标签号,2~20 个标签号;其中1-15号保留,作为特殊编号; 第 21-23位 exp,3位8个数,为优先级,用于Q0S 策略使用&a…...
OpenHarmony napi 编译 .so 并打包成 .har
一、前言 最近在搞公司标准产品适配OpenHarmony 平台, 按照行业上的常用方法,在Android 是将底层代码用c 封装成 xxx.so ,然后将其他一部分打包成 xxx.jar。 因此,在OpenHarmony 平台也是打算按照这个模式。正所谓,好…...
python 循环导入(circular imports)解决方法
在 Python 中,大部分人都应该都遇到过循环导入的问题。 循环导入是指两个文件各自尝试导入另一个文件(模块),当一个模块没有完全初始化时会导致失败。解决这种情况的最好方法是将代码分层组织,这样导入的关系就会自然…...
01、Linux网络设置
目录 1.1 查看及测试网络 1.1.1 查看网络配置 1、查看网络接口地址 2、查看主机状态 3、查看路由表条目 4、查看网络连接qing 1.1.2 测试网络连接 1.测试网络连接 2.跟踪数据包的路由路径 3.测试DNS域名解析 1.2 设置网络地址参数 1.2.1 使用网络配置命令 1.修改网卡…...
ssm160基于Java技术的会员制度管理的商品营销系统的设计与实现+vue
商品营销系统计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本商品营销系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理…...
网站整体配色方案/外贸公司一般怎么找客户
首先我们来看2个需要用到SubString()的地方: 1、 在C#中,我们时常需要缩减字符,并且用"..."取代被缩减的部分,通常我们使用的是(string).SubString(),然后我们可以这样缩减: str (str.Length>…...
wordpress 评论 姓名/下载优化大师
fopen fopen(打开文件) 相关函数 open,fclose 表头文件 #include<stdio.h> 定义函数 FILE * fopen(const char * path,const char * mode); 函数说明 參数path字符串包括欲打开的文件路径及文件名称,參数mode字符串则代表着…...
上海网站seoseodian/seo词库排行
Delphi Live Bindings 初探 Live Bindings,顾名思义,动态绑定。 1、绑定前: 2、点击数据源: 3、绑定连线:点击 蓝色区域, 按住 鼠标左键,一直移动到绿色区域,然后松掉鼠标左键。 系统…...
合肥城乡建设委员会网站/安徽网络seo
《MYSQL数据库mysql连接数设置操作方法(Too many connections)》要点:本文介绍了MYSQL数据库mysql连接数设置操作方法(Too many connections),希望对您有用。如果有疑问,可以联系我们。mysql在使用过程中,发现连接数超了~~~~MYSQL必读[rootli…...
wordpress如何应用插件下载失败/网络推广工作好干吗
欢迎访问我的个人博客查看文章:崩天的勾玉站 java自学群: 973140560 —————————————————————— Java自学no.1———带你初步认识java什么是JavaJava定位Java特点JRE和JDK开发环境配置集成开发工具IDEAidea安装及使用教程初次使用idea创建包和类…...
重庆南川网站制作公司哪家专业/免费二级域名建站
全球互联网大会-中外互联网领袖高峰对话-马云_雷军_李彦宏_刘强东_张朝阳 视频地址: http://v.pps.tv/play_3JTKKF.html 或者 http://v.pps.tv/play_3JTKKF.html...