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

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 接口的实例,用于处理租户相关的逻辑。

属性名类型默认值描述
tenantLineHandlerTenantLineHandler租户处理器( 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 接口,并重写 insertFillupdateFill 方法。

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
  • 使用 strictInsertFillstrictUpdateFill 方法可以根据注解 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 开始以为很简单&#xff0c;后来发现是最麻烦的。因为 Ubuntu 上的 webview 库是 基于 GTK 的&#xff0c;而 AWTK 是基于 X11 的&#xff0c;两者的窗口系统不同&#xff0c;所以期间踩了几个大坑。 1. 编译 AWTK 在使用 Linux 的输入法时…...

Python入门(7)--高级函数特性详解

Python高级函数特性详解 &#x1f680; 目录 匿名函数&#xff08;Lambda&#xff09;装饰器的使用生成器与迭代器递归函数应用实战案例&#xff1a;文件批处理工具 1. 匿名函数&#xff08;Lambda&#xff09;深入解析 &#x1f3af; 1.1 Lambda函数基础与进阶 1.1.1 基本…...

【数据库原理】理解数据库,基础知识

第一代&#xff1a;网状数据库&#xff1b;第二代&#xff1a;关系数据库&#xff1b;第三代&#xff1a;新一代数据库系统BigData 一、理解数据库 什么是数据&#xff1a;信息&#xff0c;对事物的存在方方式、运动状态及特征的描述。数据&#xff0c;记录信息的识别方式有数…...

VConsole——(H5调试工具)前端开发使用于手机端查看控制台和请求发送

因为开发钉钉H5微应用在手机上一直查看不到日志等&#xff0c;出现安卓和苹果上传图片一边是成功的&#xff0c;一边是失败的&#xff0c;所以找了这个&#xff0c;之前在开发微信小程序进行调试的时候能看到&#xff0c;之前没想到过&#xff0c;这次被人提点发现可以单独使用…...

论文分享 | FuzzLLM:一种用于发现大语言模型中越狱漏洞的通用模糊测试框架

大语言模型是当前人工智能领域的前沿研究方向&#xff0c;在安全性方面大语言模型存在一些挑战和问题。分享一篇发表于2024年ICASSP会议的论文FuzzLLM&#xff0c;它设计了一种模糊测试框架&#xff0c;利用模型的能力去测试模型对越狱攻击的防护水平。 论文摘要 大语言模型中…...

vmWare虚拟环境centos7安装Hadoop 伪分布式实践

背景&#xff1a;近期在研发大数据中台&#xff0c;需要研究Hadoop hive 的各种特性&#xff0c;需要搭建一个Hadoop的虚拟环境&#xff0c;本来想着使用dock &#xff0c;但突然发现docker 公共仓库的镜像 被XX 了&#xff0c;无奈重新使用vm 搭建虚拟机。 大概经历了6个小时完…...

【C++入门(一)】半小时入门C++开发(深入理解new+List+范围for+可变参数)

目录 一.深入理解new 使用格式 二.List列表 定义一个列表 迭代器 添加元素 删除元素 排序 反转序列 三.范围for 四.可变参数 std::initializer_list 可变参数模板&#xff08;variadic template&#xff09; 一.深入理解new 类似于C语言中的malloc、calloc和reallo…...

Vue 3与TypeScript集成指南:构建类型安全的前端应用

在Vue 3中使用TypeScript&#xff0c;可以让你的组件更加健壮和易于维护。以下是使用TypeScript与Vue 3结合的详细步骤和知识点&#xff1a; 1. 环境搭建 首先&#xff0c;确保你安装了Node.js&#xff08;推荐使用最新的LTS版本&#xff09;和npm或Yarn。然后&#xff0c;安…...

MATLAB和Python发射光谱

在MATLAB和Python中&#xff0c;可以使用不同的库来生成发射光谱。以下是两种语言的简单示例&#xff1a; MATLAB: % 定义波长&#xff08;nm&#xff09;和强度&#xff08;a.u.&#xff09; wavelengths linspace(300, 1000, 1000); intensity sin(wavelengths / 500);…...

IEEE(常用)参考文献引用格式详解 | LaTeX参考文献规范(IEEE Trans、Conf、Arxiv)| 期刊会议名缩写查询

期刊 ** 期刊:已正式出版&#xff08;有期卷号) ** 期刊:录用后在线访问即Early access&#xff08;无期卷号&#xff09;会议Arxiv论文 期刊 期刊:已正式出版&#xff08;有期卷号&#xff09; 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是一种自适应学习率的优化算法&#xff0c;结合了动量和自适应学习率的特性。 主要思想是根据参数的梯度来动态调整每个参数的学习率。 核心原理包括&#xff1a; 动量&#xff08;Momentum&#xff09;&#xff1a;Adam算法引入了动量项&#xff0c;以平滑梯度更新的方向…...

Qt按钮类-->day09

按钮基类 QAbstractButton 标题与图标 // 参数text的内容显示到按钮上 void QAbstractButton::setText(const QString &text); // 得到按钮上显示的文本内容, 函数的返回就是 QString QAbstractButton::text() const;// 得到按钮设置的图标 QIcon icon() const; // 给按钮…...

基于xr-frame实现微信小程序的手部、手势识别3D模型叠加和石头剪刀布游戏功能

前言 xr-frame是一套小程序官方提供的XR/3D应用解决方案&#xff0c;基于混合方案实现&#xff0c;性能逼近原生、效果好、易用、强扩展、渐进式、遵循小程序开发标准。xr-frame在基础库v2.32.0开始基本稳定&#xff0c;发布为正式版&#xff0c;但仍有一些功能还在开发&#…...

基于Kafka2.1解读Consumer原理

文章目录 概要整体架构流程技术名词解释技术细节coordinatorfetcherclientconsumer#poll的主要流程 全局总览小结 概要 继上一篇讲Producer原理的文章过去已经一个多月了&#xff0c;今天来讲讲Consumer的原理。 其实源码早就读了部分了&#xff0c;但是最近工作比较忙&#x…...

深度学习:ResNet每一层的输出形状

其中 /**在输出通道数为64、步幅为2的7 7卷积层后&#xff0c;接步幅为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 安全 , 电信 , 评论 , 中国 中国国内的安全市场进入“战国时期”&#xff0c;启明星辰、绿盟、天融信、安氏、亿阳、联想网御、华为等战国七雄拥有雄厚的客户资源和资金基础&#xff0c;帐前皆有勇猛善战之士&#xff0c;渐渐开始统领国内安全市场的潮流…...

修改Android Studio项目配置JDK路径和项目Gradle路径的GUI工具

概述 本工具提供了一个基于Python Tkinter的图形用户界面&#xff08;GUI&#xff09;&#xff0c;用于帮助用户搜索并更新Android Studio项目中的config.properties文件里的java.home路径&#xff0c;以及workspace.xml文件中的last_opened_file_path路径。该工具旨在简化手动…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...