当前位置: 首页 > 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路径。该工具旨在简化手动…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

pycharm 设置环境出错

pycharm 设置环境出错 pycharm 新建项目&#xff0c;设置虚拟环境&#xff0c;出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...