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

MyBatis枚举映射类讨论

前言

本篇需要对于MyBatis有一定的认识,而且只是针对于TypeHandler接口来讨论,暂不讨论其他方面的问题

TypeHandler概叙

      TypeHandler是MyBatis设计的一个用于参数的接口,你们会不会很好奇MyBatis是如何把整形,时间,字符串等映射到数据表字段的,实际上就是这个接口来做的,在TypeHandlerRegistry的构造器中初始化了很多处理器,如下

public TypeHandlerRegistry(Configuration configuration) {this.unknownTypeHandler = new UnknownTypeHandler(configuration);register(Boolean.class, new BooleanTypeHandler());register(boolean.class, new BooleanTypeHandler());register(JdbcType.BOOLEAN, new BooleanTypeHandler());register(JdbcType.BIT, new BooleanTypeHandler());register(Byte.class, new ByteTypeHandler());register(byte.class, new ByteTypeHandler());register(JdbcType.TINYINT, new ByteTypeHandler());register(Short.class, new ShortTypeHandler());register(short.class, new ShortTypeHandler());register(JdbcType.SMALLINT, new ShortTypeHandler());register(Integer.class, new IntegerTypeHandler());register(int.class, new IntegerTypeHandler());register(JdbcType.INTEGER, new IntegerTypeHandler());register(Long.class, new LongTypeHandler());register(long.class, new LongTypeHandler());register(Float.class, new FloatTypeHandler());register(float.class, new FloatTypeHandler());register(JdbcType.FLOAT, new FloatTypeHandler());register(Double.class, new DoubleTypeHandler());register(double.class, new DoubleTypeHandler());register(JdbcType.DOUBLE, new DoubleTypeHandler());register(Reader.class, new ClobReaderTypeHandler());register(String.class, new StringTypeHandler());register(String.class, JdbcType.CHAR, new StringTypeHandler());register(String.class, JdbcType.CLOB, new ClobTypeHandler());register(String.class, JdbcType.VARCHAR, new StringTypeHandler());register(String.class, JdbcType.LONGVARCHAR, new StringTypeHandler());register(String.class, JdbcType.NVARCHAR, new NStringTypeHandler());register(String.class, JdbcType.NCHAR, new NStringTypeHandler());register(String.class, JdbcType.NCLOB, new NClobTypeHandler());register(JdbcType.CHAR, new StringTypeHandler());register(JdbcType.VARCHAR, new StringTypeHandler());register(JdbcType.CLOB, new ClobTypeHandler());register(JdbcType.LONGVARCHAR, new StringTypeHandler());register(JdbcType.NVARCHAR, new NStringTypeHandler());register(JdbcType.NCHAR, new NStringTypeHandler());register(JdbcType.NCLOB, new NClobTypeHandler());register(Object.class, JdbcType.ARRAY, new ArrayTypeHandler());register(JdbcType.ARRAY, new ArrayTypeHandler());register(BigInteger.class, new BigIntegerTypeHandler());register(JdbcType.BIGINT, new LongTypeHandler());register(BigDecimal.class, new BigDecimalTypeHandler());register(JdbcType.REAL, new BigDecimalTypeHandler());register(JdbcType.DECIMAL, new BigDecimalTypeHandler());register(JdbcType.NUMERIC, new BigDecimalTypeHandler());register(InputStream.class, new BlobInputStreamTypeHandler());register(Byte[].class, new ByteObjectArrayTypeHandler());register(Byte[].class, JdbcType.BLOB, new BlobByteObjectArrayTypeHandler());register(Byte[].class, JdbcType.LONGVARBINARY, new BlobByteObjectArrayTypeHandler());register(byte[].class, new ByteArrayTypeHandler());register(byte[].class, JdbcType.BLOB, new BlobTypeHandler());register(byte[].class, JdbcType.LONGVARBINARY, new BlobTypeHandler());register(JdbcType.LONGVARBINARY, new BlobTypeHandler());register(JdbcType.BLOB, new BlobTypeHandler());register(Object.class, unknownTypeHandler);register(Object.class, JdbcType.OTHER, unknownTypeHandler);register(JdbcType.OTHER, unknownTypeHandler);register(Date.class, new DateTypeHandler());register(Date.class, JdbcType.DATE, new DateOnlyTypeHandler());register(Date.class, JdbcType.TIME, new TimeOnlyTypeHandler());register(JdbcType.TIMESTAMP, new DateTypeHandler());register(JdbcType.DATE, new DateOnlyTypeHandler());register(JdbcType.TIME, new TimeOnlyTypeHandler());register(java.sql.Date.class, new SqlDateTypeHandler());register(java.sql.Time.class, new SqlTimeTypeHandler());register(java.sql.Timestamp.class, new SqlTimestampTypeHandler());register(String.class, JdbcType.SQLXML, new SqlxmlTypeHandler());register(Instant.class, new InstantTypeHandler());register(LocalDateTime.class, new LocalDateTimeTypeHandler());register(LocalDate.class, new LocalDateTypeHandler());register(LocalTime.class, new LocalTimeTypeHandler());register(OffsetDateTime.class, new OffsetDateTimeTypeHandler());register(OffsetTime.class, new OffsetTimeTypeHandler());register(ZonedDateTime.class, new ZonedDateTimeTypeHandler());register(Month.class, new MonthTypeHandler());register(Year.class, new YearTypeHandler());register(YearMonth.class, new YearMonthTypeHandler());register(JapaneseDate.class, new JapaneseDateTypeHandler());// issue #273register(Character.class, new CharacterTypeHandler());register(char.class, new CharacterTypeHandler());}

所以我们平时不用设计什么就可以进行自动转换,而一种特殊情况下,我们需要自己定义,也就是枚举,这也是我们经常用的技术,比如有以下的对象

public class SysUser {/*** 用户名*/private String name;/*** 密码-加密模式*/private String password;/*** 数据状态,0-正常,1-删除*/private DataStateEnum deleted = DataStateEnum.NORMAL;
}package com.zxc.movie.common.enums;/*** 数据状态*/
public enum DataStateEnum implements BaseEnum<DataStateEnum>{NORMAL(0, "正常"),DELETE(1, "删除"),;private final Integer code;private final String desc;DataStateEnum(Integer code, String desc) {this.code = code;this.desc = desc;}@Overridepublic Integer getCode() {return code;}@Overridepublic String getDesc() {return desc;}
}

            那么我们如何进行转换呢,其实有很多种方式,下面一个个说下

常规方式

  直接继承BaseTypeHandler,然后实现就行,看下面的描述就很简单了

package com.zxc.movie.common.typehandler.common;import com.zxc.movie.common.enums.BaseEnumUtils;
import com.zxc.movie.common.enums.DataStateEnum;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Objects;/**
* @author zxc_user
* @date 2023/8/7 19:15
* @version 1.0
* @description 数据状态返回
**/
public class DataStateEnumHandler extends BaseTypeHandler<DataStateEnum> {@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, DataStateEnum parameter, JdbcType jdbcType) throws SQLException {ps.setInt(i, parameter.getCode());}@Overridepublic DataStateEnum getNullableResult(ResultSet rs, String columnName) throws SQLException {return getByCode(rs.getInt(columnName));}@Overridepublic DataStateEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException {return getByCode(rs.getInt(columnIndex));}@Overridepublic DataStateEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {return getByCode(cs.getInt(columnIndex));}private DataStateEnum getByCode(Integer code) {DataStateEnum[] dataStateEnums = DataStateEnum.values();for (DataStateEnum baseEnum : dataStateEnums) {if(Objects.equals(baseEnum.getCode(), code)) {return baseEnum;}}}
}

这种方式很简单,但是如果有多个枚举类会存在大量的重复代码,所以我们可以把公用逻辑进行抽取,其实只要让枚举有统一的类型,并且获取到所有枚举就行了,那么怎么做呢,需要有以下的步骤

进阶方式      

  首先,要提供一个接口,然后所有枚举都实现这个接口,如下

/**
* @author zxc_user
* @date 2023/8/7 19:01
* @version 1.0
* @description 枚举基础类
**/
public interface BaseEnum<T>{Integer getCode();String getDesc();
}/*** 数据状态*/
public enum DataStateEnum implements BaseEnum<DataStateEnum>{NORMAL(0, "正常"),DELETE(1, "删除"),;private final Integer code;private final String desc;DataStateEnum(Integer code, String desc) {this.code = code;this.desc = desc;}@Overridepublic Integer getCode() {return code;}@Overridepublic String getDesc() {return desc;}
}

这样一来,所有枚举都属于BaseEnum类型

        其次提供了一个公用的TypeHandler处理器BaseEnumHandler,定义如下

package com.zxc.movie.common.typehandler;import com.zxc.movie.common.enums.BaseEnum;
import com.zxc.movie.common.enums.BaseEnumUtils;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @author zxc_user
* @date 2023/8/7 18:52
* @version 1.0
* @description 通用的枚举类解释器
**/
public abstract class BaseEnumHandler<T extends BaseEnum<T>> extends BaseTypeHandler<T> {//进一步优化protected abstract BaseEnum<T>[] getBaseEnumArray();//根据code获取对应的数据private BaseEnum<T> getBaseEnum(Integer code) {BaseEnum<T>[] baseEnumArray = getBaseEnumArray();for (BaseEnum<T> baseEnum : baseEnumArray) {if(Objects.equals(baseEnum.getCode(), code)) {return baseEnum;}}return null;}@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {ps.setInt(i, parameter.getCode());}@Overridepublic T getNullableResult(ResultSet rs, String columnName) throws SQLException {return (T) getBaseEnum(rs.getInt(columnName));}@Overridepublic T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {return (T) getBaseEnum(rs.getInt(columnIndex));}@Overridepublic T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {return (T) getBaseEnum(cs.getInt(columnIndex));}
}

原来的DataStateEnumHandler只需要继承上面的处理器,然后实现方法即可,如下

package com.zxc.movie.common.typehandler.common;import com.zxc.movie.common.enums.BaseEnum;
import com.zxc.movie.common.enums.DataStateEnum;
import com.zxc.movie.common.typehandler.BaseEnumHandler;/**
* @author zxc_user
* @date 2023/8/7 19:15
* @version 1.0
* @description 数据状态返回
**/
public class DataStateEnumHandler extends BaseEnumHandler<DataStateEnum> {@Overrideprotected BaseEnum<DataStateEnum>[] getBaseEnumArray() {return DataStateEnum.values();}
}

是不是很简单,到这里其实就已经很容易了,但是其实还能进一步优化,回看逻辑,其实我们只要有办法拿到所有枚举的对象就可以处理,那么有没有办法呢,其实是有的,可以通过反射,如下

最终方式

package com.zxc.movie.common.typehandler;import com.zxc.movie.common.enums.BaseEnum;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Objects;/**
* @author zxc_user
* @date 2023/8/7 18:52
* @version 1.0
* @description 通用的枚举类解释器
**/
public abstract class BaseEnumHandler<T extends BaseEnum<T>> extends BaseTypeHandler<T> {private BaseEnum<T>[] baseArrayEnum;public BaseEnumHandler(){//获取泛型的类型Type genericSuperclass = this.getClass().getGenericSuperclass();if (genericSuperclass instanceof ParameterizedType){ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();for (Type actualTypeArgument : actualTypeArguments) {//获取枚举的所有对象,因为都实现了BaseEnum接口this.baseArrayEnum = (BaseEnum[]) ((Class)actualTypeArgument).getEnumConstants();}}}//根据code获取对应的数据private BaseEnum<T> getBaseEnum(Integer code) {for (BaseEnum<T> baseEnum : baseArrayEnum) {if(Objects.equals(baseEnum.getCode(), code)) {return baseEnum;}}return null;}@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {ps.setInt(i, parameter.getCode());}@Overridepublic T getNullableResult(ResultSet rs, String columnName) throws SQLException {return (T) getBaseEnum(rs.getInt(columnName));}@Overridepublic T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {return (T) getBaseEnum(rs.getInt(columnIndex));}@Overridepublic T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {return (T) getBaseEnum(cs.getInt(columnIndex));}
}

最重要的地方就是构造器里面通过反射获取到枚举所有类型,然后原来的处理器只需要直接继承就行了,如下

package com.zxc.movie.common.typehandler.common;import com.zxc.movie.common.enums.DataStateEnum;
import com.zxc.movie.common.typehandler.BaseEnumHandler;/**
* @author zxc_user
* @date 2023/8/7 19:15
* @version 1.0
* @description 数据状态返回
**/
public class DataStateEnumHandler extends BaseEnumHandler<DataStateEnum> {}

是不是变的很简单?唯一的缺点就是还是需要创建一个转换器,但是转换器已经不需要实现任何内容了,只需要提供一个类就行了

TypeHandler生效

老版本的MyBatis是通过xml文件注册的,这里就不说了,因为现在都是需要和Spring进行集成的,而且还是SpringBoot,所以这里只说SpringBoot的方式

第一种

在application.yml文件中配置如下内容,type-handlers-package为处理类所在包

mybatis-plus:
  type-handlers-package: com.zxc.movie.common.typehandler

第二种

往IOC容器中注入一个Bean,如下,这是MyBatis-PLUS提供的扩展点,是不是很方便?

/**
* @author zxc_user
* @date 2023/8/7 19:17
* @version 1.0
* @description mybatis-plus配置类
**/
@Configuration
public class MyBatisPlusConfig {/*** 自定义配置,看源码发现的* @return*/@Beanpublic ConfigurationCustomizer mybatisConfiguration() {return configuration -> {//注册解析器configuration.getTypeHandlerRegistry().register(DataStateEnumHandler.class);};}
}

这里顺便说一下,第二种方式的优先度比第一种的要高,这个逻辑需要在源码中查看或者官网介绍,源码逻辑在MybatisPlusAutoConfiguration.applyConfiguration中有所体现

总结

到这里本篇文章就结束了,其实并不复杂,主要是为了统一TypeHandler的处理逻辑,最妙的是通过反射获取的枚举列表方法,如下,虽然不难,不过也可以记录一下

    public BaseEnumHandler(){//获取枚举类型Type genericSuperclass = this.getClass().getGenericSuperclass();if (genericSuperclass instanceof ParameterizedType){ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();for (Type actualTypeArgument : actualTypeArguments) {this.baseArrayEnum = (BaseEnum[]) ((Class)actualTypeArgument).getEnumConstants();}}}

相关文章:

MyBatis枚举映射类讨论

前言 本篇需要对于MyBatis有一定的认识&#xff0c;而且只是针对于TypeHandler接口来讨论&#xff0c;暂不讨论其他方面的问题 TypeHandler概叙 TypeHandler是MyBatis设计的一个用于参数的接口&#xff0c;你们会不会很好奇MyBatis是如何把整形&#xff0c;时间&#xff0c;字符…...

微信开发之朋友圈自动点赞的技术实现

简要描述&#xff1a; 朋友圈点赞 请求URL&#xff1a; http://域名地址/snsPraise 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型说明wId…...

Linux命令200例:sed对文本进行修改、替换和删除等操作的强大工具(常用)

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…...

python 合并多个excel文件

使用 openpyxl 思路&#xff1a; 读取n个excel的文件&#xff0c;存储在一个二维数组中&#xff0c;注意需要转置。将二维数组的数据写入excel。 安装软件&#xff1a; pip install openpyxl源代码&#xff1a; import os import openpyxl # 将n个excel文件数据合并到一个…...

【Docker】性能测试监控平台搭建:InfluxDB+Grafana+Jmeter+cAdvisor

前言 在做性能测试时&#xff0c;如果有一个性能测试结果实时展示的页面&#xff0c;可以极大的提高我们对系统性能表现的掌握程度&#xff0c;进而提高我们的测试效率。但是我们每次打开Jmeter都会有几个硕大的字提示别用GUI模式进行负载测试&#xff0c;而且它自带的监视器效…...

wordpress日主题Ripro9.0最新二开修正源码下载+美化包和插件

日主题Ripro9.0最新二开升级修正源码美化包和插件&#xff0c;RiPro9.0的二开版本新模板&#xff0c;包含2个美化包和全屏水印以及防复制插件。 模板和美化包路径:\wp-content\themes 插件路径&#xff1a;\wp-content\plugins&#xff0c;有兴趣的自行去体验吧...

fib Model Code史海拾贝

文章目录 0. 背景1. 强度等级不一致&#xff08;20230807&#xff09;1.1 问题描述&#xff08;20230807&#xff09;1.2 问题探索 0. 背景 本文主要记录在学习了解ModelCode的过程中产生的问题。当然&#xff0c;主要是我个人认为有意思的地方。欢迎有共同兴趣的网友留言一起…...

6.7.tensorRT高级(1)-使用onnxruntime进行onnx模型推理过程

目录 前言1. python-ort2. C-ort总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习 tensorRT 高级-使用 onnxruntime 进行 on…...

360未来安全研究院笔试题

笔试时间:2020.04.16,15:00-17:30。 岗位:Linux 安全开发工程师(实习生) 题型: 能力测试——逻辑题(20个5分=100分) 专业测试——客观题(40个2分=80分) 专业测试——在线编程题(2个25分=50分) 逻辑题 一共40道题目,很多逻辑推断题,包含数字找规律和图片找…...

Linux SSH 远程连接主机,并执行命令

应用场景 当需要远程到另一台Linux上&#xff0c;并在另一台机器上执行 Shell 命令&#xff0c;则需要注意命令的书写格式 示例说明 远程到 192.158.157.47 机器上&#xff0c;并执行命令 cd /tmp && ./zabbixagent_install.sh && echo Success 1、错误方式…...

FAST协议详解1 不同数据类型的编码与解码

一、概述 FAST协议里不同的数据类型在编码时有非常大的区别&#xff0c;比如整数只需要将二进制数据转为十进制即可&#xff0c;而浮点数则需要先传小数点位数&#xff0c;再传一个整数&#xff0c;最后将二者结合起来才是最终结果。本篇使用openfast自设了一些数据并编码成FA…...

黑马大数据学习笔记5-案例

目录 需求分析背景介绍目标需求数据内容DBeaver连接到Hive建库建表加载数据 ETL数据清洗数据问题需求实现查看结果扩展 指标计算需求需求指标统计 可视化展示BIFineBI的介绍及安装FineBI配置数据源及数据准备 可视化展示 P73~77 https://www.bilibili.com/video/BV1WY4y197g7?…...

网络编程——TCP/IP协议族(IP协议、TCP协议和UDP协议……)

TCP/IP协议族 一、IP协议 1、IP协议简介 IP协议又称网际协议 特指为实现在一个相互连接的网络系统上从源地址到目的地传输数据包(互联网数据包)所提供必要功能的协议&#xff0c;是网络层中的协议。 2、特点 不可靠:它不能保证IP数据包能成功地到达它的目的地&#xff0c;仅…...

Oracle SQL存储过程能够返回表吗

使用Oracle游标返回表数据 在Oracle存储过程中&#xff0c;我们可以使用游标来返回表的数据。游标是一种类似于指针的数据类型&#xff0c;可以用来遍历和操作结果集。以下是一个示例的Oracle存储过程&#xff0c;通过游标返回表数据&#xff1a; CREATE OR REPLACE PROCEDUR…...

2 Vue使用v-bind来代替{{}}取值

注意&#xff01;当两个具有共同id的标签都要从数据层拿值时&#xff0c;需要使用div标签&#xff0c;赋予他们共同的id&#xff0c;不然其中有一个会拿不到数据&#xff01; v-bind用来绑定前标签的属性&#xff0c;然后对属性赋值。{{}}用来对前后标签中的文本赋值。使用方法…...

20230807在WIN10下使用python3将TXT文件转换为DOCX(在UTF8编码下转换为DOCX有多一行的瑕疵)

20230807在WIN10下使用python3将TXT文件转换为DOCX&#xff08;在UTF8编码下转换为DOCX有多一行的瑕疵&#xff09; 2023/8/7 12:58 https://translate.google.com/?slen&tlzh-CN&opdocs 缘起&#xff0c;由于google的文档翻译不支持SRT/TXT格式的字幕&#xff0c;因此…...

Flutter(八)事件处理与通知

1.原始指针事件处理 一次完整的事件分为三个阶段&#xff1a;手指按下、手指移动、和手指抬起&#xff0c;而更高级别的手势&#xff08;如点击、双击、拖动等&#xff09;都是基于这些原始事件的。 Listener 组件 Flutter中可以使用Listener来监听原始触摸事件 Listener({…...

Java,python,c#,js,c++搞量化交易的接口大全

股票基金api接口地址&#xff1a;https://stockapi.com.cn 不想自己写的&#xff1a;https://stockapi.com.cn 除了牛逼&#xff0c;只剩下牛逼&#xff0c;除了方便&#xff0c;只剩下方便&#xff0c;python不是唯一的量化编程语言 接口说明&#xff1a;日线macd指标 https:/…...

javaAPI(一):String

String的特性 String底层源码 1、String声明为final&#xff0c;不可被继承 2、String实现了Serializable接口&#xff1a;表示字符支持序列化 实现了Comparable接口&#xff1a;表示String可以比较大小 3、String内部定义了final char[] value用于存储字符串 4、通过字面量的…...

数据互通,版本管理优化图文档与BOM数据

在现代企业的产品开发过程中&#xff0c;图文档和BOM数据是不可或缺的关键要素。图文档记录了产品的设计和工程信息&#xff0c;而BOM数据则明确了产品所需物料的清单和规格。然而&#xff0c;由于数据的复杂性和版本变更的频繁性&#xff0c;图文档与BOM数据之间的协作和管理常…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中&#xff0c;API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关&#xff0c;Kong凭借其插件化架构…...

【深度学习新浪潮】什么是credit assignment problem?

Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...

鸿蒙HarmonyOS 5军旗小游戏实现指南

1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;采用DevEco Studio实现&#xff0c;包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...

链式法则中 复合函数的推导路径 多变量“信息传递路径”

非常好&#xff0c;我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题&#xff0c;统一使用 二重复合函数&#xff1a; z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y))​ 来全面说明。我们会展示其全微分形式&#xff08;偏导…...

软件工程教学评价

王海林老师您好。 您的《软件工程》课程成功地将宏观的理论与具体的实践相结合。上半学期的理论教学中&#xff0c;您通过丰富的实例&#xff0c;将“高内聚低耦合”、SOLID原则等抽象概念解释得十分透彻&#xff0c;让这些理论不再是停留在纸面的名词&#xff0c;而是可以指导…...