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

基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【二】【整合springSecurity】

1、创建数据库
注意:mysql默认字符集为utf8,默认排序规则为utf8_general_ci。一般我们也会选择字符集为utf-8
MySQL在5.5.3之后增加了这个utf8mb4的编码,utf8mb4完全向下兼容utf8,为了节省空间,一般情况下使用utf8也就够了,我这边没有utf8。所以选择了utf8mb4 。
在这里插入图片描述
2、建表
若需要整合我们的springSecurity,一种是直接使用springSecurity自带的权限架构,另外一种是使用我们自己设计的数据架构,本文所阐述的就是使用自己设计的RBAC权限架构,因此我们要事先设计好用户权限架构的PDM如下图所示,并创建我们的数据库:数据库名:hyll_springboot,以及我们的三张表:user、user_role、user_associate_role:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
接着打开我们的工程新建如下工程的目录:
在这里插入图片描述

接着在我们的sys包底下新建entity和dao这两个包:
在这里插入图片描述
同时打开我们的pom.xml引入该工程所需要的所有依赖,接着我们的IDEA会弹出一个框,我们点击import就自动会去maven给我们下载依赖,若你有自己的私有maven则将其指向自己的私有maven,若这边有缺少不懂的直接去我的第一章的github上的源代码中自己去copy下来:

<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><mysql.version>5.1.41</mysql.version><guava.version>18.0</guava.version><org.mapstruct.version>1.1.0.Final</org.mapstruct.version></properties><dependencies><!-- 集成Druid数据库连接池和监控 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.3</version></dependency><!-- 引入mybatis的支持 --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.1</version></dependency><!-- 引入mapstruct的支持 --><dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct-jdk8</artifactId><version>${org.mapstruct.version}</version></dependency><dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>${org.mapstruct.version}</version></dependency><!--  Java EE 6 规范 JSR 330 --><dependency><groupId>javax.inject</groupId><artifactId>javax.inject</artifactId><version>1</version></dependency><!-- 引入json的依赖 classifier必须要加这个是json的jdk的依赖--><dependency><groupId>net.sf.json-lib</groupId><artifactId>json-lib</artifactId><version>2.4</version><classifier>jdk15</classifier></dependency><!-- 开启spring-websocket的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><!-- 开启spring-security的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- 开启thymeleaf的spring-security的支持 --><dependency><groupId>org.thymeleaf.extras</groupId><artifactId>thymeleaf-extras-springsecurity4</artifactId></dependency><!-- 表示对thymeleaf模板不再是用默认的HTML5标准来做严格限制 --><dependency><groupId>net.sourceforge.nekohtml</groupId><artifactId>nekohtml</artifactId><version>1.9.22</version></dependency><!-- 添加对spring-redis的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-redis</artifactId><version>1.3.8.RELEASE</version></dependency><!-- 添加对spring-cache的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache</artifactId></dependency><!-- 添加对spring-data-rest的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-rest</artifactId></dependency><!-- 添加对spring-jpa的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>${guava.version}</version></dependency><!-- 添加对thymeleaf的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!-- 添加对websocket的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><version>1.3.5.RELEASE</version><scope>provided</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional><!-- optional=true,依赖不会传递,该项目依赖devtools;之后依赖myboot项目的项目如果想要使用devtools,需要重新引入 --></dependency><dependency><groupId>com.xiaoleilu</groupId><artifactId>hutool-all</artifactId><version>3.0.9</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.6.1</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.6.1</version></dependency><dependency><groupId>com.vaadin.external.google</groupId><artifactId>android-json</artifactId><version>0.0.20131108.vaadin1</version></dependency></dependencies>

同时在我们的entity包底下新建我们刚刚的三个实体:
在这里插入图片描述
UserRole 的代码部分

package com.example.demo.sys.entity;/*** @author lj* @version 1.0* @date 2023/1/314:18* Description:com.example.demo.sys.entity*/
public class UserRole {private long id;private String name;private String roleName;public long getId() {return id;}public void setId(long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getRoleName() {return roleName;}public void setRoleName(String roleName) {this.roleName = roleName;}
}

User 代码部分

package com.example.demo.sys.entity;import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;/*** @author lj* @version 1.0* @date 2023/1/310:01* Description:com.example.demo.sys.entity*/
public class User implements UserDetails {private int id;private String login;private String password;private String userName;private String address;private String job;private long groupId;private Date birthDate;private String city;private String district;private String province;private String streetAddress;private String state;private String type;private Date lastLoginDate;// 用户角色信息private List<UserRole> roles;// 权限集合数据private String roleArray;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getLogin() {return login;}public void setLogin(String login) {this.login = login;}public void setPassword(String password) {this.password = password;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public String getJob() {return job;}public void setJob(String job) {this.job = job;}public long getGroupId() {return groupId;}public void setGroupId(long groupId) {this.groupId = groupId;}public Date getBirthDate() {return birthDate;}public void setBirthDate(Date birthDate) {this.birthDate = birthDate;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}public String getDistrict() {return district;}public void setDistrict(String district) {this.district = district;}public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public String getStreetAddress() {return streetAddress;}public void setStreetAddress(String streetAddress) {this.streetAddress = streetAddress;}public String getState() {return state;}public void setState(String state) {this.state = state;}public String getType() {return type;}public void setType(String type) {this.type = type;}public Date getLastLoginDate() {return lastLoginDate;}public void setLastLoginDate(Date lastLoginDate) {this.lastLoginDate = lastLoginDate;}public List<UserRole> getRoles() {return roles;}public void setRoles(List<UserRole> roles) {this.roles = roles;}public String getRoleArray() {return roleArray;}public void setRoleArray(String roleArray) {this.roleArray = roleArray;}@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();if (this.getRoles() != null) {List<UserRole> roles = this.getRoles();for (UserRole role : roles) {if (role.getName() != null) {auths.add(new SimpleGrantedAuthority(role.getName()));}}}return auths;}@Overridepublic String getPassword() {return null;}@Overridepublic String getUsername() {return null;}@Overridepublic boolean isAccountNonExpired() {return false;}@Overridepublic boolean isAccountNonLocked() {return false;}@Overridepublic boolean isCredentialsNonExpired() {return false;}@Overridepublic boolean isEnabled() {return false;}/*** 功能描述:组装角色数据集合** @param roleArray*/public void packagingRoles(String roleArray) {List<UserRole> roles = new ArrayList<UserRole>();if (roleArray != null) {UserRole userRole = null;for (String roleId : roleArray.split(",")) {if (!roleId.isEmpty()) {userRole = new UserRole();userRole.setId(Long.parseLong(roleId));roles.add(userRole);}}}this.setRoles(roles);}}

UserAssociateRole 代码部分

package com.example.demo.sys.entity;/*** @author lj* @version 1.0* @date 2023/1/314:26* Description:com.example.demo.sys.entity*/
public class UserAssociateRole {private int userId;private long roleId;public UserAssociateRole() {super();}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}public long getRoleId() {return roleId;}public void setRoleId(long roleId) {this.roleId = roleId;}
}

接着我们在dao包里面创建以下的接口:

package com.example.demo.sys.dao;import com.example.demo.sys.entity.User;/*** @author lj* @version 1.0* @date 2023/1/314:54* Description:com.example.demo.sys.dao*/
public interface UserDao {/*** 功能描述:根据账户获取用户信息** @param user* @return com.example.demo.sys.entity.User* @author: LJ* @date: 2023/1/3*/User findByLogin(String user);
}

接着我们引入我们的mybatis配置以及我们的security和快速切换环境配置,
首先在我们的application.properties底下增加以下配置:

spring.profiles.active=dev#配置放行的目录和方法
security.ignored=/api/*,/css/*,/js/*,/images/*,/fonts/*,/font-awesome/*
#表示对thymeleaf模板不再是用默认的HTML5标准来做严格限制
spring.thymeleaf.mode = LEGACYHTML5#配置mybatis的扫描的包的文件的入口
mybatis.config-locations=classpath:mybatis/mybatis-config.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

同时在我们的resources目录底下创建一个目录mybatis并在该目录底下创建一个文件mybatis-config.xml和mapper目录如下所示:
在这里插入图片描述

mybatis-config.xml代码如下所示

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><typeAliases><typeAlias alias="Integer" type="java.lang.Integer" /><typeAlias alias="Long" type="java.lang.Long" /><typeAlias alias="HashMap" type="java.util.HashMap" /><typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" /><typeAlias alias="ArrayList" type="java.util.ArrayList" /><typeAlias alias="LinkedList" type="java.util.LinkedList" /></typeAliases>
</configuration>

同时在我们的resource目录底下创建我们的application-dev.properties文件信息如下:

server.port = 8080
#数据库连接配置
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/hyll_springboot?characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=111111

接着我们在resource/mapper目录底下创建一个mybatis_user.xml内容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><typeAliases><typeAlias alias="Integer" type="java.lang.Integer" /><typeAlias alias="Long" type="java.lang.Long" /><typeAlias alias="HashMap" type="java.util.HashMap" /><typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" /><typeAlias alias="ArrayList" type="java.util.ArrayList" /><typeAlias alias="LinkedList" type="java.util.LinkedList" /></typeAliases>
</configuration>

同时在我们的resource目录底下创建我们的application-dev.properties文件信息如下

server.port = 8080
#数据库连接配置
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/hyll_springboot?characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=111111

接着我们在resource/mapper目录底下创建一个mybatis_user.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.sys.dao.UserDao"><!-- 包含角色信息的map --><resultMap type="com.example.demo.sys.entity.User" id="UserLoginMap"><id property="id" column="id"/><result property="login" column="login"/><result property="password" column="password"/><result property="userName" column="user_name"/><result property="address" column="address"/><result property="job" column="job"/><result property="groupId" column="group_id"/><result property="birthDate" column="birth_date"/><result property="city" column="city"/><result property="district" column="district"/><result property="province" column="province"/><result property="streetAddress" column="street_address"/><result property="state" column="state"/><result property="type" column="type"/><result property="lastLoginDate" column="last_login_date"/><collection property="roles"  ofType="com.example.demo.sys.entity.UserRole" javaType="java.util.ArrayList"><result column="user_role_id" property="id" jdbcType="VARCHAR" /><result column="name" property="name" jdbcType="VARCHAR" /><result column="role_name" property="roleName" jdbcType="VARCHAR" /></collection></resultMap><!-- 根据账号来获取用户信息 --><select id="findByLogin" parameterType="java.lang.String" resultMap="UserLoginMap">select u.*,ur.id as user_role_id,ur.name,ur.role_name from user u inner join user_associate_role uar on u.id = uar.user_id inner join user_role ur on uar.role_id = ur.id where u.login = #{login}</select></mapper>

接着开始我们的springsecurity的配置,找到我们的config包在该包底下我们创建一个security和mybatis包如下所示
在这里插入图片描述
接着在我们的security增加以下三个类分别是(CustomPasswordEncoder:密码加密类;CustomUserService:登陆逻辑重写类;WebSecurityConfig:security实现配置类):
注意maven的版本,如果版本高的话,就没有Md5PasswordEncoder的依赖

package com.example.demo.common.config.security;import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;/*** 功能描述:spring-security登陆的密码进行MD5加密传到数据库** @author: LJ* @date: 2023/1/3* @return*/public class CustomPasswordEncoder implements PasswordEncoder {@Overridepublic String encode(CharSequence rawPassword) {Md5PasswordEncoder encoder = new Md5PasswordEncoder();return encoder.encodePassword(rawPassword.toString(), "hyll");}@Overridepublic boolean matches(CharSequence rawPassword, String encodedPassword) {Md5PasswordEncoder encoder = new Md5PasswordEncoder();return encoder.isPasswordValid(encodedPassword, rawPassword.toString(), "hyll");}
}

注意,你得密码是经过md5加密得,所以比如我得密码是1,那么加密后得a2098ac42fe033111a1f678b8d621899,这个填入到数据库中对应user表得密码中,你可以根据自己的密码进行加密,加密后的结果放到数据库中

  public static void main(String[] args) {Md5PasswordEncoder encoder = new Md5PasswordEncoder();System.out.println(encoder.encodePassword("1", "hyll"));System.out.println( encoder.isPasswordValid("a2098ac42fe033111a1f678b8d621899","1", "hyll"));}

在这里插入图片描述

package com.example.demo.common.config.security;import com.example.demo.sys.dao.UserDao;
import com.example.demo.sys.entity.User;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;import javax.annotation.Resource;/*** @author lj* @version 1.0* @date 2023/1/510:51* Description:com.example.demo.common.config.security*/
public class CustomUserService implements UserDetailsService {@Resourceprivate UserDao userDao;@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {User user = userDao.findByLogin(s);if (user == null) {throw new UsernameNotFoundException("用户名不存在");}
// 自定义错误的文章说明的地址:http://blog.csdn.net/z69183787/article/details/21190639?locationNum=1&fps=1if (user.getState().equalsIgnoreCase("0")) {throw new LockedException("用户账号被冻结,无法登陆请联系管理员!");}return user;}
}
package com.example.demo.common.config.security;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;/*** @author lj* @version 1.0* @date 2023/1/513:34* 实现Security的配置*/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
//当我们想要开启spring方法级安全时,只需要在任何 @Configuration实例上使用 @EnableGlobalMethodSecurity 注解就能达到此目的
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@BeanUserDetailsService customUserService() {return new CustomUserService();}@BeanPasswordEncoder passwordEncoder() {return new CustomPasswordEncoder();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(customUserService()).passwordEncoder(passwordEncoder());}@Overrideprotected AuthenticationManager authenticationManager() throws Exception {return super.authenticationManager();}/*** 功能描述: csrf().disable()为了关闭跨域访问的限制,若不关闭则websocket无法与后台进行连接** @param http* @return void* @author: LJ* @date: 2023/1/5*/@Overrideprotected void configure(HttpSecurity http) throws Exception {http.headers().frameOptions().disable();http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().formLogin().loginPage("/login").defaultSuccessUrl("/main").failureUrl("/login?error=true").permitAll().and().logout().logoutSuccessUrl("/login").permitAll();}
}

接着我们在mybatis包底下新增MyBatisConfig 配置类如下所示 MapperScan扫描的是我们的dao接口的存放路径,因此此处大家一定要注意自己的dao包的路径是否正确,否则会导致调用dao方法出错】

package com.example.demo.common.config.mybatis;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;/*** @author lj* @version 1.0* @date 2023/1/2520:15* Description:com.example.demo.common.config.mybatis*/
@Configuration
@MapperScan("com.example.demo.*.dao")
public class MyBatisConfig {
}

接着在我们的config目录底下创建我们的WebMvcConfig配置文件如下所示:

package com.example.demo.common.config;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;/*** @author lj* @version 1.0* @date 2023/1/2520:21* Description:com.example.demo.common.config*/
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {/*** 重写方法描述:实现在url中输入相应的地址的时候直接跳转到某个地址** @param registry*/@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/login").setViewName("login");registry.addViewController("/main").setViewName("main");registry.addViewController("/error").setViewName("error");}}

相关文章:

基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【二】【整合springSecurity】

1、创建数据库 注意&#xff1a;mysql默认字符集为utf8&#xff0c;默认排序规则为utf8_general_ci。一般我们也会选择字符集为utf-8 MySQL在5.5.3之后增加了这个utf8mb4的编码&#xff0c;utf8mb4完全向下兼容utf8&#xff0c;为了节省空间&#xff0c;一般情况下使用utf8也就…...

字节6面,成功唬住面试官拿了27K,软件测试面试也没有传说中那么难吧....

字节的面试挺独特&#xff0c;每轮面试都没有 HR 约时间&#xff0c;一般是晚上 8 点左右面试官来一个电话&#xff0c;问是否能面试&#xff0c;能的话开始面&#xff0c;不能就约一个其它时间。全程 6 面&#xff0c;前五面技术面&#xff0c;电话面试&#xff0c;最后一面是…...

Qt扫盲-QMake 语言概述

QMake 语言概述一、概述二、变量三、替换函数四、测试函数一、概述 这里主要就是记录一下如何使用 qmake Manual&#xff0c;里面关于我对 qmake的理解&#xff0c;以及如何配置这个 qt 工程文件&#xff0c;通过配置工程文件&#xff0c;来构建出&#xff0c;APP&#xff0c;…...

代码随想录二刷Day02链表:203.移除链表元素,707.设计链表,206.反转链表

203.移除链表元素&#xff08;写if的时候&#xff0c;要考虑要不要写else语句&#xff09; 文章链接&#xff1a;代码随想录 (programmercarl.com) 思路&#xff1a; &#xff08;1&#xff09;要操作链表的话&#xff0c;可以设置一个虚拟头节点&#xff0c;从而方便操作 …...

Zabbix 3.0 从入门到精通(zabbix使用详解)

Zabbix 3.0 从入门到精通(zabbix使用详解) 第1章 zabbix监控 1.1 为什么要监控 在需要的时刻&#xff0c;提前提醒我们服务器出问题了 当出问题之后&#xff0c;可以找到问题的根源 网站/服务器 的可用性 1.1.1 网站可用性 在软件系统的高可靠性&#xff08;也称为可用性…...

基于JDBC框架的事务管理

事务: Transaction, 是数据库中的一种能够保证多个写操作要么全部成功, 要么全部失败的机制在基于Spring JDBC的数据库编程中, 在业务方法上添加Transactional注解, 即可使得这个业务方法是事务性的举例, 一个银行转账操作, 转账时需要执行的sql语句大致是:UPDATE 存款表 SET 余…...

使用IPV6+DDNS连接内网主机

0、前言 IPV6已经普及多年&#xff0c;但是作为互联网用户好像并没有在实用性上有更多感受&#xff0c;或者说IPV6并没有让普通用户感觉到改变。我作为网络从业者其实也没有过多关注。在工作中普遍遇到的还是基于IPV4的网络&#xff0c;比如各个行业的网络、单位的内网区域和互…...

【新2023】华为OD机试 - 高效的任务规划(Python)

华为 OD 清单查看地址:blog.csdn.net/hihell/category_12199275.html 高效的任务规划 题目 你有 n 台机器编号为1-n,每台都需要完成一项工作, 机器经过配置后都能独立完成一项工作。 假设第i台机器你需要花 Bi 分钟进行设置, 然后开始运行,Ji分钟后完成任务。 现在,你…...

sql复习(数据处理、约束)

一、DML&#xff08;数据操纵语言&#xff09; DML(Data Manipulation Language – 数据操纵语言) 可以在下列条件下执行&#xff1a; –向表中插入数据 –修改现存数据 –删除现存数据 事务是由完成若干项工作的DML语句组成的 1.insert语句 使用 INSERT 语句向表中插入数据…...

前端入门~

我们应该怎样理解前端呢&#xff1f;前端即网站前台部分&#xff0c;运行在PC端&#xff0c;移动端等浏览器上展现给用户浏览的网页。随着互联网技术的发展&#xff0c;HTML5&#xff0c;CSS3&#xff0c;前端框架的应用&#xff0c;跨平台响应式网页设计能够适应各种屏幕分辨率…...

工业网关控制器CK-GW06-E01与欧姆龙 PLC配置说明

工业网关控制器CK-GW06-E01是一款工业级网关控制器&#xff0c;以太网通信接口&#xff0c;支持 EtherNet IP|Modbus TCP 工业协议。可实现一拖六&#xff0c;同时带有六组输入 检测 IO 和六组输出控制 IO。 本文将重点介绍工业网关控制器CK-GW06-E01与欧姆龙 PLC配置说明。 工…...

uni-app前端H5页面底部内容被tabbar遮挡

如果你想在原生 tabbar 上方悬浮一个菜单&#xff0c;之前写 bottom:0。这样的写法编译到 h5 后&#xff0c;这个菜单会和 tabbar 重叠&#xff0c;位于屏幕底部。 原码&#xff1a; <view style"position: fixed;bottom:0;left: 0;background-color: #007AFF;right: …...

昇腾CANN算子开发揭秘

开发者在利用昇腾硬件进行神经网络模型训练或者推理的过程中&#xff0c;可能会遇到以下场景&#xff1a;1、训练场景下&#xff0c;将第三方框架&#xff08;例如TensorFlow、PyTorch等&#xff09;的网络训练脚本迁移到昇腾AI处理器时遇到了不支持的算子。2、推理场景下&…...

华为OD机试注意事项,备考思路,刷题要点,答疑,od Base 提供

华为 OD 机试是华为公司用于招聘岗位的一种在线编程测试&#xff0c;通常要求应聘者在规定的时间内完成一定数量的编程题目&#xff0c;以测试其编程能力和解决问题的能力。 本篇博客就华为 OD 机试注意事项&#xff0c;备考思路&#xff0c;刷题要点&#xff0c;答疑为大家一一…...

Python 自己简单地造一个轮子.whl文件

造轮子引言准备文件原始文件打包轮子文件运行验证引言 平时使用的python第三方库很顺手&#xff0c;这第三方库一般都是大家一起努力的结果&#xff0c;那我们是不是也可以贡献一点力量呢&#xff1f;首先从造一个本地的.whl文件开始。 在python中&#xff0c;引用第三方库时…...

NVIDIA Tesla V100部署与使用

在先前的实验过程中&#xff0c;使用了腾讯云提供的nvidia T4GPU&#xff0c;尽管其性能较博主的笔记本有了极大提升&#xff0c;但总感觉仍有些美中不足&#xff0c;因此本次博主租赁了nvidia V100 GPU&#xff0c;看看它的性能表现如何。 和先前一样&#xff0c;只需要将服务…...

网络知识点梳理与总结

作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页​​​​​​ 目录 前言 一.知识点梳理 前言 本章将会对高级网络应用一些知识点进行梳理。 一.知识点梳理 1.单臂的缺陷有哪些?...

我工作5年测试才8K,应届生刚毕业就拿16K?凭什么

我从事手工测试五年了&#xff0c;还拿着8K的死工资&#xff0c;家里还几张嘴需要喂养&#xff0c;我很累&#xff0c;也很迷茫…【某个粉丝跟我的诉说】 为什么手工测试会迷茫呢&#xff1f; 自动化测试、性能测试倒是不会迷茫。 我认为手工测试的迷茫基于两个原因&#xf…...

【QT】UDP通信QUdpSocket(单播、广播、组播)

目录1. UDP通信概述2. UDP消息传送的三种模式3. QUdpSocket类的接口函数4. UDP单播和广播代码示例4.1 测试说明4.2 MainWindow.h4.3 MainWindow.cpp4.4 界面展示5. UDP组播代码示例5.1 组播的特性5.2 MainWindow.h5.3 MainWindow.cpp5.4 界面展示1. UDP通信概述 UDP是无连接、…...

【Java】properties 和 yml 的区别

文章目录properties和yml的区别① 定义和定位不同② 语法不同③ yml更好的配置多种数据类型④ yml可以跨语言⑤ 总结properties和yml的区别 这几天刚好看到Spring Boot当中有两种配置文件的方式&#xff0c;但是这两种配置方式有什么区别呢&#xff1f; properties和yml都是S…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...