Mybatis-Plus 多租户插件属性自动赋值
文章目录
- 1、Mybatis-Plus 多租户插件
- 1.1、属性介绍
- 1.2、使用多租户插件
- maven
- yml
- ThreadLocalUtil
- 实现 定义,注入租户处理器插件
- 测试
- domian
- service & ServiceImpl
- mapper
- 测试mapper.xml 方式
- 1.3、不使用多租户插件
- 2、实体对象的属性自动赋值
- 使用
- 1. 定义实体类
- 2. 实现 MetaObjectHandler
- 3. 配置自动填充处理器
- 注意事项
- 4.测试
- 新增
- 修改
1、Mybatis-Plus 多租户插件
TenantLineInnerInterceptor
是 MyBatis-Plus 提供的一个插件,用于实现多租户的数据隔离。通过这个插件,可以确保每个租户只能访问自己的数据,从而实现数据的安全隔离。其实就是一个拦截器,用于进行sql
增删改查
时自动添加租户字段
1.1、属性介绍
TenantLineInnerInterceptor
的关键属性是 tenantLineHandler
,它是一个 TenantLineHandler
接口的实例,用于处理租户相关的逻辑。
属性名 | 类型 | 默认值 | 描述 |
---|---|---|---|
tenantLineHandler | TenantLineHandler | 租户处理器( TenantId 行级 ) |
TenantLineHandler
接口定义了以下方法:
public interface TenantLineHandler {/*** 获取租户 ID 值表达式,只支持单个 ID 值** @return 租户 ID 值表达式*/Expression getTenantId();/*** 获取租户字段名* 默认字段名叫: tenant_id** @return 租户字段名*/default String getTenantIdColumn() {return "tenant_id";//默认}/*** 根据表名判断是否忽略拼接多租户条件* 默认都要进行解析并拼接多租户条件** @param tableName 表名* @return 是否忽略, true:表示忽略,false:需要解析并拼接多租户条件*/default boolean ignoreTable(String tableName) {return false;}/*** 忽略插入租户字段逻辑** @param columns 插入字段* @param tenantIdColumn 租户 ID 字段* @return*/default boolean ignoreInsert(List<Column> columns, String tenantIdColumn) {return columns.stream().map(Column::getColumnName).anyMatch(i -> i.equalsIgnoreCase(tenantIdColumn));}
}
1.2、使用多租户插件
比方我有一张表biz_archive_common
-- security_manager.biz_archive_common definitionCREATE TABLE `biz_archive_common` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '数据主键ID',`title_name` varchar(255) DEFAULT NULL COMMENT '题名',`secrecy_level_id` bigint(20) DEFAULT NULL COMMENT '密级id',`archive_num` varchar(510) DEFAULT NULL COMMENT '档号(照片号)',`roll_num` varchar(31) DEFAULT NULL COMMENT '案卷号(册号/带号)',`abandon` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否废弃 默认 0false/1true',`del` varchar(200) NOT NULL DEFAULT '0' COMMENT '是否删除 默认 0false/1true',`create_user` varchar(31) DEFAULT NULL COMMENT '创建者账户',`create_time` datetime DEFAULT NULL COMMENT '创建时间',`update_user` varchar(31) DEFAULT NULL COMMENT '更新者账户',`update_time` datetime DEFAULT NULL COMMENT '更新时间',`archive_company_id` bigint(20) DEFAULT NULL COMMENT '全宗单位ID',PRIMARY KEY (`id`) USING BTREE,KEY `indexArchiveCompanyId` (`archive_company_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='档案共有信息表';
maven
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--mybatisplus依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.6</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.8</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--lombok依赖--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies>
yml
server:port: 8001#address: 127.0.0.1
#spring数据源配置
spring:application:name: token #项目名# 数据源datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/security_manager?serverTimezone=GMT%2B8&useUnicode=true&useSSL=false&characterEncoding=utf-8username: rootpassword: rootdruid:initial-size: 20min-idle: 20max-active: 100max-wait: 10000time-between-eviction-0runs-millis: 60000min-evictable-idle-time-millis: 30000validation-query: SELECT 1 FROM DUALtest-while-idle: truetest-on-borrow: truetest-on-return: true# mybatis-plus配置
mybatis-plus:global-config:db-config:logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)logic-delete-value: 1 # 逻辑已删除值(默认为 1)logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)configuration:map-underscore-to-camel-case: true # 数据库下划线自动转驼峰标示关闭log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #日志配置mapper-locations: classpath*:/mapper/**/*.xml
ThreadLocalUtil
package cn.js.util;import java.util.HashMap;
import java.util.Map;/*** Description:** @Author Js* @Create 2024-11-17 14:12* @Version 1.0*/
public class ThreadLocalUtil {//1 初始化TreadLocalprivate static ThreadLocal<Map<String, Object>> RES = new ThreadLocal<Map<String, Object>>() {/*** 和继承ThreadLocal 类一样,也是一个方法的复写*/protected Map<String, Object> initialValue() {return new HashMap<String, Object>();};};/** 给线程里面设置一个值*/public static void set(String name, Object object) {Map<String, Object> map = RES.get(); // 取出来的map 集合位nullmap.put(name, object);}/*** 从线程里面取值*/public static Object get(String name) {Map<String, Object> map = RES.get();if (!map.containsKey(name)) {return null;}return map.get(name);}/*** 清空线程的值*/public static void clear() {Map<String, Object> map = RES.get();map.clear();map = null; // jvm 自动回收}}
实现 定义,注入租户处理器插件
package cn.js.config;import cn.js.util.ThreadLocalUtil;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.schema.Column;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.ArrayList;
import java.util.List;/*** @Author Js* @Description* @Date 2024-11-15 21:34* @Version 1.0**/
@Configuration
@AutoConfigureBefore(MybatisPlusAutoConfiguration.class)
public class PaginationInterceptorConfig {@Beanpublic MybatisPlusInterceptor addMybatisPlusInterceptor(){MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler()));return interceptor;}private class TenantLineHandler implements com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler{/*** 获取当前租户 ID。*/@Overridepublic Expression getTenantId() {Object id = ThreadLocalUtil.get("id");Long tenantId=Long.valueOf(String.valueOf(id));// 返回租户ID的表达式,LongValue 是 JSQLParser 中表示 bigint 类型的 classreturn new LongValue(tenantId);}/*** 表结构中那个字段用于拼接多租户条件*/@Overridepublic String getTenantIdColumn() {return "archive_company_id";}/*** 默认返回false:表示所有表都需要拼接多租户条件* tableName:表名称*/@Overridepublic boolean ignoreTable(String tableName) {//如果那些表不需要拼接多租户条件,List<String> tableList = new ArrayList<>();tableList.add("sql_version");tableList.add("User");tableList.add("Kf");if(tableList.contains(tableName)){//如果不需要添加的表名称在list中,就返回false,不用拼接租户条件return true;}return false;}/*** 获取租户 ID 字段名。*/@Overridepublic boolean ignoreInsert(List<Column> columns, String tenantIdColumn) {return com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler.super.ignoreInsert(columns, tenantIdColumn);}}}
测试
package cn.js.controller;import cn.js.domain.BizArchiveCommon;
import cn.js.service.BizArchiveCommonService;
import cn.js.util.ThreadLocalUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import java.util.List;/*** @Author Js* @Description* @Date 2024-11-15 21:26* @Version 1.0**/
@RequestMapping("/common")
@RestController
public class BizArchiveCommonController {@Resourceprivate BizArchiveCommonService bizArchiveCommonService;@GetMapping("/getAll")public List<BizArchiveCommon> getAll() {ThreadLocalUtil.set("id",1645);List<BizArchiveCommon> archiveCommons = bizArchiveCommonService.list();return archiveCommons;}}
domian
package cn.js.domain;import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.time.LocalDateTime;/*** @Author Js* @Description* @Date 2024-11-15 21:22* @Version 1.0**/
@Data
@TableName(value="biz_archive_common")
public class BizArchiveCommon {private Long id;private String titleName;private Long secrecyLevelId;private String archiveNum;private String rollNum;@TableLogic(value = "false", delval = "true")private Boolean abandon;/*** 创建人*/@TableField(fill = FieldFill.INSERT)private String createUser;/*** 创建时间*/@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;/*** 修改人*/@TableField(fill = FieldFill.UPDATE)private String updateUser;/*** 修改时间*/@TableField(fill = FieldFill.UPDATE)private LocalDateTime updateTime;/*** 是否逻辑删除,true:删除 false:未删除*/@TableLogic(value = "false", delval = "true")private Boolean del;/*** 全宗单位id*/private Long archiveCompanyId;}
service & ServiceImpl
package cn.js.service;import cn.js.domain.BizArchiveCommon;
import com.baomidou.mybatisplus.extension.service.IService;public interface BizArchiveCommonService extends IService<BizArchiveCommon> {
}package cn.js.service.impl;import cn.js.domain.BizArchiveCommon;
import cn.js.mapper.BizArchiveCommonMapper;
import cn.js.service.BizArchiveCommonService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;/*** @Author Js* @Description* @Date 2024-11-15 21:27* @Version 1.0**/
@Service
public class BizArchiveCommonServiceImpl extends ServiceImpl<BizArchiveCommonMapper, BizArchiveCommon> implements BizArchiveCommonService {
}
mapper
package cn.js.mapper;import cn.js.domain.BizArchiveCommon;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface BizArchiveCommonMapper extends BaseMapper<BizArchiveCommon> {
}
JDBC Connection [HikariProxyConnection@639980080 wrapping com.mysql.cj.jdbc.ConnectionImpl@7c12090] will not be managed by Spring
==> Preparing: SELECT id, title_name, secrecy_level_id, archive_num, roll_num, abandon, del, create_user, create_time, update_user, update_time, archive_company_id FROM biz_archive_common WHERE archive_company_id = 1645
==> Parameters:
<== Total: 0
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@38e12bd4]
测试mapper.xml 方式
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.js.mapper.BizArchiveCommonMapper"><select id="ones" resultType="cn.js.domain.BizArchiveCommon">select * from biz_archive_common where id=1</select>
</mapper>
@RequestMapping("/common")
@RestController
public class BizArchiveCommonController {@Resourceprivate BizArchiveCommonService bizArchiveCommonService;@GetMapping("/getOne")public BizArchiveCommon getOnes() {ThreadLocalUtil.set("id",1645);BizArchiveCommon archiveCommon = bizArchiveCommonService.getones();return archiveCommon;}}
JDBC Connection [HikariProxyConnection@1523711906 wrapping com.mysql.cj.jdbc.ConnectionImpl@6db5719b] will not be managed by Spring
==> Preparing: SELECT * FROM biz_archive_common WHERE id = 1 AND archive_company_id = 1645
==> Parameters:
<== Total: 0
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@70ef05c0]
1.3、不使用多租户插件
可能我们并不是所有的sql语句都需要拼接租户条件,那该如何解决,只需要在相应的mapper接口上面添加注解
@InterceptorIgnore(tenantLine = "true")
package cn.js.mapper;import cn.js.domain.BizArchiveCommon;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface BizArchiveCommonMapper extends BaseMapper<BizArchiveCommon> {@InterceptorIgnore(tenantLine = "true")BizArchiveCommon ones();
}
2、实体对象的属性自动赋值
比方说表中有这个4个字段,我们在新增,修改的时候能不能自动插入,而不是每次,操作的时候我们给他插入
使用
1. 定义实体类
在实体类中,你需要使用 @TableField
注解来标记哪些字段需要自动填充,并指定填充的策略。
public class User {@TableField(fill = FieldFill.INSERT)private String createTime;@TableField(fill = FieldFill.UPDATE)private String updateTime;// 其他字段...
}
2. 实现 MetaObjectHandler
创建一个类来实现 MetaObjectHandler
接口,并重写 insertFill
和 updateFill
方法。
package cn.js.config;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;/*** Description:** @Author Js* @Create 2024-11-17 15:39* @Version 1.0*/
@Component
@Slf4j
public class MetaObjectHandlerConfig implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {log.info("开始插入填充...");this.strictInsertFill(metaObject,"createTime", LocalDateTime.class,LocalDateTime.now());this.strictInsertFill(metaObject,"createUser", String.class,"张三");}@Overridepublic void updateFill(MetaObject metaObject) {log.info("开始更新填充...");this.strictUpdateFill(metaObject,"updateTime", LocalDateTime.class,LocalDateTime.now());this.strictUpdateFill(metaObject,"updateUser", String.class,"王五");}
}
3. 配置自动填充处理器
确保你的 MyMetaObjectHandler
实现类被 Spring 管理,可以通过 @Component
或 @Bean
注解来实现。
注意事项
- 自动填充是直接给实体类的属性设置值。
- 如果属性没有值,入库时会是
null
。 MetaObjectHandler
提供的默认方法策略是:如果属性有值则不覆盖,如果填充值为null
则不填充。- 字段必须声明
@TableField
注解,并设置fill
属性来选择填充策略。 - 填充处理器需要在 Spring Boot 中声明为
@Component
或@Bean
。 - 使用
strictInsertFill
或strictUpdateFill
方法可以根据注解FieldFill.xxx
、字段名和字段类型来区分填充逻辑。 - 如果不需区分,可以使用
fillStrategy
方法。 - 在
update(T entity, Wrapper<T> updateWrapper)
时,entity
不能为空,否则自动填充失效。 - 在
update(Wrapper<T> updateWrapper)
时不会自动填充,需要手动赋值字段条件。
4.测试
package cn.js.controller;import cn.js.domain.BizArchiveCommon;
import cn.js.service.BizArchiveCommonService;
import cn.js.util.ThreadLocalUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import java.util.List;/*** @Author Js* @Description* @Date 2024-11-15 21:26* @Version 1.0**/
@RequestMapping("/common")
@RestController
public class BizArchiveCommonController {@Resourceprivate BizArchiveCommonService bizArchiveCommonService;@GetMapping("/save")public Boolean save() {ThreadLocalUtil.set("id",1645);BizArchiveCommon bizArchiveCommon = new BizArchiveCommon();bizArchiveCommon.setTitleName("这是新增的");bizArchiveCommon.setSecrecyLevelId(123L);bizArchiveCommon.setArchiveNum("8080-25201-38245");bizArchiveCommon.setRollNum("25201");bizArchiveCommon.setAbandon(false);boolean archiveCommon = bizArchiveCommonService.save(bizArchiveCommon);return archiveCommon;}@GetMapping("/update")public Boolean update() {ThreadLocalUtil.set("id",1645);BizArchiveCommon bizArchiveCommon = new BizArchiveCommon();bizArchiveCommon.setId(1L);bizArchiveCommon.setTitleName("这是新增的,进行修改!");bizArchiveCommon.setSecrecyLevelId(123L);bizArchiveCommon.setArchiveNum("8080-25201-38245");bizArchiveCommon.setRollNum("25201");bizArchiveCommon.setAbandon(false);boolean b = bizArchiveCommonService.updateById(bizArchiveCommon);return b;}}
新增
JDBC Connection [HikariProxyConnection@1186756471 wrapping com.mysql.cj.jdbc.ConnectionImpl@22ef7a2e] will not be managed by Spring
==> Preparing: INSERT INTO biz_archive_common (id, title_name, secrecy_level_id, archive_num, roll_num, abandon, create_user, create_time, archive_company_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1645)
==> Parameters: 1858059911531872257(Long), 这是新增的(String), 123(Long), 8080-25201-38245(String), 25201(String), false(Boolean), 张三(String), 2024-11-17T16:09:38.650358300(LocalDateTime)
<== Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7b266740]
修改
JDBC Connection [HikariProxyConnection@724111921 wrapping com.mysql.cj.jdbc.ConnectionImpl@5db6c17a] will not be managed by Spring
==> Preparing: UPDATE biz_archive_common SET title_name = ?, secrecy_level_id = ?, archive_num = ?, roll_num = ?, abandon = ?, update_user = ?, update_time = ? WHERE id = ? AND del = false AND archive_company_id = 1645
==> Parameters: 这是新增的,进行修改!(String), 123(Long), 8080-25201-38245(String), 25201(String), false(Boolean), 王五(String), 2024-11-17T16:22:59.641094300(LocalDateTime), 1(Long)
<== Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5390448d]
相关文章:
Mybatis-Plus 多租户插件属性自动赋值
文章目录 1、Mybatis-Plus 多租户插件1.1、属性介绍1.2、使用多租户插件mavenymlThreadLocalUtil实现 定义,注入租户处理器插件测试domianservice & ServiceImplmapper 测试mapper.xml 方式 1.3、不使用多租户插件 2、实体对象的属性自动赋值使用1. 定义实体类2. 实现 Meta…...
AWTK-WIDGET-WEB-VIEW 实现笔记 (4) - Ubuntu
Ubuntu 上实现 AWTK-WIDGET-WEB-VIEW 开始以为很简单,后来发现是最麻烦的。因为 Ubuntu 上的 webview 库是 基于 GTK 的,而 AWTK 是基于 X11 的,两者的窗口系统不同,所以期间踩了几个大坑。 1. 编译 AWTK 在使用 Linux 的输入法时…...
Python入门(7)--高级函数特性详解
Python高级函数特性详解 🚀 目录 匿名函数(Lambda)装饰器的使用生成器与迭代器递归函数应用实战案例:文件批处理工具 1. 匿名函数(Lambda)深入解析 🎯 1.1 Lambda函数基础与进阶 1.1.1 基本…...
【数据库原理】理解数据库,基础知识
第一代:网状数据库;第二代:关系数据库;第三代:新一代数据库系统BigData 一、理解数据库 什么是数据:信息,对事物的存在方方式、运动状态及特征的描述。数据,记录信息的识别方式有数…...
VConsole——(H5调试工具)前端开发使用于手机端查看控制台和请求发送
因为开发钉钉H5微应用在手机上一直查看不到日志等,出现安卓和苹果上传图片一边是成功的,一边是失败的,所以找了这个,之前在开发微信小程序进行调试的时候能看到,之前没想到过,这次被人提点发现可以单独使用…...
论文分享 | FuzzLLM:一种用于发现大语言模型中越狱漏洞的通用模糊测试框架
大语言模型是当前人工智能领域的前沿研究方向,在安全性方面大语言模型存在一些挑战和问题。分享一篇发表于2024年ICASSP会议的论文FuzzLLM,它设计了一种模糊测试框架,利用模型的能力去测试模型对越狱攻击的防护水平。 论文摘要 大语言模型中…...
vmWare虚拟环境centos7安装Hadoop 伪分布式实践
背景:近期在研发大数据中台,需要研究Hadoop hive 的各种特性,需要搭建一个Hadoop的虚拟环境,本来想着使用dock ,但突然发现docker 公共仓库的镜像 被XX 了,无奈重新使用vm 搭建虚拟机。 大概经历了6个小时完…...
【C++入门(一)】半小时入门C++开发(深入理解new+List+范围for+可变参数)
目录 一.深入理解new 使用格式 二.List列表 定义一个列表 迭代器 添加元素 删除元素 排序 反转序列 三.范围for 四.可变参数 std::initializer_list 可变参数模板(variadic template) 一.深入理解new 类似于C语言中的malloc、calloc和reallo…...
Vue 3与TypeScript集成指南:构建类型安全的前端应用
在Vue 3中使用TypeScript,可以让你的组件更加健壮和易于维护。以下是使用TypeScript与Vue 3结合的详细步骤和知识点: 1. 环境搭建 首先,确保你安装了Node.js(推荐使用最新的LTS版本)和npm或Yarn。然后,安…...
MATLAB和Python发射光谱
在MATLAB和Python中,可以使用不同的库来生成发射光谱。以下是两种语言的简单示例: MATLAB: % 定义波长(nm)和强度(a.u.) wavelengths linspace(300, 1000, 1000); intensity sin(wavelengths / 500);…...
IEEE(常用)参考文献引用格式详解 | LaTeX参考文献规范(IEEE Trans、Conf、Arxiv)| 期刊会议名缩写查询
期刊 ** 期刊:已正式出版(有期卷号) ** 期刊:录用后在线访问即Early access(无期卷号)会议Arxiv论文 期刊 期刊:已正式出版(有期卷号) article{gu2024ai, title{{AI}-Enhanced Cloud-Edge-Terminal Collaborative Ne…...
第二十周:机器学习
目录 摘要 ABSTRACT 一、吴恩达机器学习exp2——逻辑回归 1、logistic函数 2、数据预处理 3、损失函数 4、梯度下降 5、设定评价指标 6、决策边界 7、正则化 二、动手深度学习pytorch——数据预处理 1、数据集读取 2、缺失值处理 3、转换为张量格式 总结 摘要…...
Elasticsearch面试内容整理-Elasticsearch 基础概念
Elasticsearch 是一个基于 Apache Lucene 的开源分布式搜索和分析引擎,提供强大的全文本搜索、实时数据分析、分布式存储等功能。以下是 Elasticsearch 的一些基础概念: 什么是 Elasticsearch? ● Elasticsearch 是一个用于全文搜索和实时分析的分布式搜索引擎。 ● 开源和可…...
机器学习算法模型系列——Adam算法
Adam是一种自适应学习率的优化算法,结合了动量和自适应学习率的特性。 主要思想是根据参数的梯度来动态调整每个参数的学习率。 核心原理包括: 动量(Momentum):Adam算法引入了动量项,以平滑梯度更新的方向…...
Qt按钮类-->day09
按钮基类 QAbstractButton 标题与图标 // 参数text的内容显示到按钮上 void QAbstractButton::setText(const QString &text); // 得到按钮上显示的文本内容, 函数的返回就是 QString QAbstractButton::text() const;// 得到按钮设置的图标 QIcon icon() const; // 给按钮…...
基于xr-frame实现微信小程序的手部、手势识别3D模型叠加和石头剪刀布游戏功能
前言 xr-frame是一套小程序官方提供的XR/3D应用解决方案,基于混合方案实现,性能逼近原生、效果好、易用、强扩展、渐进式、遵循小程序开发标准。xr-frame在基础库v2.32.0开始基本稳定,发布为正式版,但仍有一些功能还在开发&#…...
基于Kafka2.1解读Consumer原理
文章目录 概要整体架构流程技术名词解释技术细节coordinatorfetcherclientconsumer#poll的主要流程 全局总览小结 概要 继上一篇讲Producer原理的文章过去已经一个多月了,今天来讲讲Consumer的原理。 其实源码早就读了部分了,但是最近工作比较忙&#x…...
深度学习:ResNet每一层的输出形状
其中 /**在输出通道数为64、步幅为2的7 7卷积层后,接步幅为2的3 3的最大汇聚层,与GoogLeNet区别是每个卷积层后增加了批量规范层**/ b1 nn.Sequential(nn.Conv2d(1, 64, kernel_size7, stride2, padding3),nn.BatchNorm2d(64), nn.ReLU(),nn.MaxPool2d(kernel_s…...
国内几大网络安全公司介绍 - 网络安全
Posted by zhaol under 安全 , 电信 , 评论 , 中国 中国国内的安全市场进入“战国时期”,启明星辰、绿盟、天融信、安氏、亿阳、联想网御、华为等战国七雄拥有雄厚的客户资源和资金基础,帐前皆有勇猛善战之士,渐渐开始统领国内安全市场的潮流…...
修改Android Studio项目配置JDK路径和项目Gradle路径的GUI工具
概述 本工具提供了一个基于Python Tkinter的图形用户界面(GUI),用于帮助用户搜索并更新Android Studio项目中的config.properties文件里的java.home路径,以及workspace.xml文件中的last_opened_file_path路径。该工具旨在简化手动…...
✅DAY30 贪心算法 | 452. 用最少数量的箭引爆气球 | 435. 无重叠区间 | 763.划分字母区间
452. 用最少数量的箭引爆气球 解题思路:首先把原数组按左边界进行排序。然后比较[i-1]的右边界和[i]的左边界是否重叠,如果重叠,更新当前右边界为最小右边界和[i1]的左边界判断是重叠。 class Solution:def findMinArrowShots(self, points:…...
关于Redis单线程模型以及IO多路复用的理解
IO多路复用 -> redis主线程 -> 事件队列 -> 事件处理器 1.IO多路复用机制的作用: 操作系统的多路复用机制(如 epoll、select)负责监听多个文件描述符(如客户端连接)上的事件。 当某个文件描述符上的事件就绪…...
学习ASP.NET Core的身份认证(基于Cookie的身份认证1)
B/S架构程序可通过Cookie、Session、JWT、证书等多种方式认证用户身份,虽然之前测试过用户登录代码,也学习过开源项目中的登录认证,但其实还是对身份认证疑惑甚多,就比如登录验证后用户信息如何保存、客户端下次连接时如何获取用户…...
奇门遁甲中看债务时用神该怎么取?
奇门遁甲中看债务的用神 一、值符 值符在债务关系中可代表债权人(放贷人)。例如在预测放贷时,以值符为放贷人,如果值符克天乙(借贷人)或者天乙生值符,这种情况下可以放贷;反之&#…...
Redis 集群主要有以下几种类型
Redis 集群主要有以下几种类型: 主从复制模式: 这种模式包含一个主数据库实例(master)与一个或多个从数据库实例(slave)。客户端可以对主数据库进行读写操作,对从数据库进行读操作,主…...
使用 Axios 拦截器优化 HTTP 请求与响应的实践
目录 前言1. Axios 简介与拦截器概念1.1 Axios 的特点1.2 什么是拦截器 2. 请求拦截器的应用与实践2.1 请求拦截器的作用2.2 请求拦截器实现 3. 响应拦截器的应用与实践3.1 响应拦截器的作用3.2 响应拦截器实现 4. 综合实例:一个完整的 Axios 配置5. 使用拦截器的好…...
mini-lsm通关笔记Week2Day5
项目地址:https://github.com/skyzh/mini-lsm 个人实现地址:https://gitee.com/cnyuyang/mini-lsm Summary 在本章中,您将: 实现manifest文件的编解码。系统重启时从manifest文件中恢复。 要将测试用例复制到启动器代码中并运行…...
mybatis的动态sql用法之排序
概括 在最近的开发任务中,涉及到了一些页面的排序,其中最为常见的就是时间的降序和升序。这个有的前端控件就可以完成,但是对于一些无法用前端控件的,只能通过后端来进行解决。 后端的解决方法就是使用mybatis的动态sql拼接。 …...
OneToMany 和 ManyToOne
在使用 ORM(如 TypeORM)进行实体关系设计时,OneToMany 和 ManyToOne 是非常重要的注解,常用来表示两个实体之间的一对多关系。下面通过例子详细说明它们的使用场景和工作方式。 OneToMany 和 ManyToOne 的基本概念 ManyToOne 表示…...
《生成式 AI》课程 第3講 CODE TASK 任务3:自定义任务的机器人
课程 《生成式 AI》课程 第3講:訓練不了人工智慧嗎?你可以訓練你自己-CSDN博客 我们希望你创建一个定制的服务机器人。 您可以想出任何您希望机器人执行的任务,例如,一个可以解决简单的数学问题的机器人0 一个机器人,…...
克拉玛依市建设局官方网站/百度平台推广
GROUP BY GROUP BY语句用来与聚合函数(aggregate functions such as COUNT, SUM, AVG, MIN, or MAX.)联合使用来得到一个或多个列的结果集。 语法如下: SELECT column1, column2, ... column_n, aggregate_function (expression) FROM tables …...
哪里可以免费做网站/神马站长平台
题意:就是一个快速排序,理解快速排序就没啥了; 代码: #include <stdio.h>void swap(int a[], int i, int j) {int t a[i];a[i] a[j];a[j] t; }int partition(int a[], int p, int r) {int i p;int j r 1;int x a[p…...
wordpress add filter/贵州seo推广
牙膏膨胀市场的企业竞争态势 该报告涉及的主要国际市场参与者有CCA Industries、Church & Dwight、Colgate-Palmolive、Unilever、Gaba Holding、Dabur India、Hindustan Unilever、Henkel、Johnson and Johnson、LG Household & Health、Lion Corporation、Procter &a…...
我想做个网站/p站关键词排名
快捷键CtrlH 1、选中要替换内容 2、全局替换 快捷键CtrlH 3、替换内容 点击ok就可以了。...
桂林网站制作哪家公司好/网站制作公司怎么找
写Verilog时,虽然每个module都会先用ModelSim或Quartus II自带的simulator仿真过,但真的将每个module合并时,一些不可预期的“run-time”问题可能才一一浮现,这时得靠SignalTap II来帮忙debug。写Verilog时,虽然每个mo…...
政府网站网站安全建设目标/网络营销渠道有哪些
拆包粘包问题解决 netty使用tcp/ip协议传输数据。而tcp/ip协议是类似水流一样的数据传输方式。多次访问的时候有可能出现数据粘包的问题,解决这种问题的方式如下: 1 定长数据流 客户端和服务器,提前协调好,每个消息长度固定。&…...