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

MyBatis 二级缓存简单使用步骤

1、二级缓存使用

MyBatis 中默认二级缓存是不开启的,如果要使用需手动开启。在 mybatis-config.xml 配置文件中设置 cacheEnabled = true ,配置如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--对应的设置都在 Configuration 配置类保存着,直接点进源码查看即可--><settings><!--开启二级缓存--><setting name="cacheEnabled" value="true"/><setting name="lazyLoadingEnabled" value="true"/><setting name="multipleResultSetsEnabled" value="true"/><setting name="useColumnLabel" value="true"/><setting name="useGeneratedKeys" value="false"/><setting name="autoMappingBehavior" value="PARTIAL"/><!--修改默认 SQL 执行器,默认是 SIMPLE,但是修改成 REUSE 会好一点点,这也是数据库优化的一个关键之处--><setting name="defaultExecutorType" value="REUSE"/><setting name="defaultStatementTimeout" value="25"/><setting name="safeRowBoundsEnabled" value="false"/><setting name="mapUnderscoreToCamelCase" value="false"/><!--修改作用域,查看 LocalCacheScope 枚举值,修改成 STATEMENT 之后一级缓存失效,但是不一定没用一级缓存,只是作用域缩小了而已,后面的嵌套、子查询就用到了一级缓存--><setting name="localCacheScope" value="SESSION"/><setting name="jdbcTypeForNull" value="OTHER"/><setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/></settings><plugins><plugin interceptor="org.apache.ibatis.gwmtest.plugin.MyPageInterceptor"></plugin></plugins><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/gwmdb?useSSL=false"/><property name="username" value="root"/><property name="password" value="itsme999"/></dataSource></environment></environments><mappers><mapper resource="mapper/PersonMapper.xml"/></mappers></configuration>

或者通过 Configuration 配置方式修改,调用 configuration.setCacheEnabled(true) 代码如下:

public class MyBatisCacheTest {private static SqlSessionFactory sqlSessionFactory;private static Configuration configuration;private static JdbcTransaction jdbcTransaction;private static Connection connection;private static final String resource = "/mybatis-config.xml";private static MappedStatement mappedStatement;private static SqlSession sqlSession;private static SqlSession sqlSession2;static {try {InputStream inputStream = MyBatisCacheTest.class.getResourceAsStream(resource);sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);configuration = sqlSessionFactory.getConfiguration();configuration.setCacheEnabled(true);connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/gwmdb?useSSL=false&allowPublicKeyRetrieval=true", "root", "itsme999");jdbcTransaction = new JdbcTransaction(connection);String statement = "org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson";mappedStatement = configuration.getMappedStatement( statement);// 注意这里设置了自动提交sqlSession = sqlSessionFactory.openSession(true);sqlSession2 = sqlSessionFactory.openSession(true);} catch (Exception e) {e.printStackTrace();}}
}

记得打开开关之后,该如何使用二级缓存?有两种方式:注解式xml 配置注解+配置结合体,提前准备两个文件: PersonMapper.xmlPersonMapper 接口。

1、使用注解缓存—@CacheNamespace

直接在 PersonMapper 接口上面添加注解 @CacheNamespace,通过 @CacheNamespace 设置缓存命名空间,这个注解一加上,就相当于在 PersonMapper 接口文件中准备好一个二级缓存,代码如下:

@CacheNamespace
public interface PersonMapper {@Select("select id,user_name as userName,age as age from test_user where id = #{myId}")Person getPerson(@Param("myId") Integer id);
}

使用代码如下:

  public static void main(String[] args) throws Exception {PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);Person person = mapper.getPerson(1);sqlSession.commit();Person person1 = mapper.getPerson(1);System.out.println("person==person1 = " + (person == person1));}

这里一定要注意二级缓存必须要显示提交才能够命中。否则二级缓存命中率为 0.0 为什么?后面源码中会分析,最终输出结果如下:

2023-02-16 14:31:37,201 DEBUG [main] -org.apache.ibatis.transaction.jdbc.JdbcTransaction Opening JDBC Connection
2023-02-16 14:31:37,216 DEBUG [main] -org.apache.ibatis.datasource.pooled.PooledDataSource Created connection 19986569.
2023-02-16 14:31:37,222 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson ==>  Preparing: select id,user_name as userName,age as age from test_user where id = ?
2023-02-16 14:31:37,276 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson ==> Parameters: 1(Integer)
2023-02-16 14:31:37,350 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson <==      Total: 1
2023-02-16 14:31:37,364  WARN [main] -org.apache.ibatis.io.SerialFilterChecker As you are using functionality that deserializes object streams, it is recommended to define the JEP-290 serial filter. Please refer to https://docs.oracle.com/pls/topic/lookup?ctx=javase15&id=GUID-8296D8E8-2B93-4B9A-856E-0A65AF9B8C66
2023-02-16 14:31:37,369 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper Cache Hit Ratio [org.apache.ibatis.gwmtest.dao.PersonMapper]: 0.5
person==person1 = false

会看到 Cache Hit Ratio 命中率为 0.5,说明已经命中二级缓存。但是发现最终:person==person1 = false 这个是因为反序列化重新生成一个 Person 类型实例。肯定是完全两个不同的实例。就比如网络传输 Person,接受端生成的 Person 能和你发送端 Person 实例一样嘛。

注意此时是在 PersonMapper 加上@CacheNamespace 注解,相当于二级缓存是在 PersonMapper 接口上准备好了。并且测试时查询使用的也是 @Select 注解方式,并且测试使用的时同一个 SqlSession,现在准备弄两个不同 SqlSession 在测试一下,代码如下:

  public static void main(String[] args) throws Exception {PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);PersonMapper mapper1 = sqlSession2.getMapper(PersonMapper.class);Person person = mapper.getPerson(1);sqlSession.commit();Person person1 = mapper1.getPerson(1);mapper.getPerson(1);System.out.println("person==person1 = " + (person == person1));}

运行结果:

2023-02-16 15:11:27,441 DEBUG [main] -org.apache.ibatis.transaction.jdbc.JdbcTransaction Opening JDBC Connection
2023-02-16 15:11:27,453 DEBUG [main] -org.apache.ibatis.datasource.pooled.PooledDataSource Created connection 19986569.
2023-02-16 15:11:27,460 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson ==>  Preparing: select id,user_name as userName,age as age from test_user where id = ?
2023-02-16 15:11:27,511 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson ==> Parameters: 1(Integer)
2023-02-16 15:11:27,572 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson <==      Total: 1
2023-02-16 15:11:27,586  WARN [main] -org.apache.ibatis.io.SerialFilterChecker As you are using functionality that deserializes object streams, it is recommended to define the JEP-290 serial filter. Please refer to https://docs.oracle.com/pls/topic/lookup?ctx=javase15&id=GUID-8296D8E8-2B93-4B9A-856E-0A65AF9B8C66
2023-02-16 15:11:27,592 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper Cache Hit Ratio [org.apache.ibatis.gwmtest.dao.PersonMapper]: 0.5
2023-02-16 15:11:27,592 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper Cache Hit Ratio [org.apache.ibatis.gwmtest.dao.PersonMapper]: 0.6666666666666666
person==person1 = false

发现还是可以命中二级缓存,这就可以在多线程下不同 SqlSession 同时访问二级缓存提高查询效率。

现在准备在 PesonMapper 接口中再添加一个查询方法 getPerson2(),该方法不再使用 @Select 方式,代码如下:

@CacheNamespace
public interface PersonMapper {@Select("select id,user_name as userName,age as age from test_user where id = #{666}")Person getPerson(Integer id);Person getPerson2(Integer id);
}

然后再 PesonMapper.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="org.apache.ibatis.gwmtest.dao.PersonMapper"><select id="getPerson2" resultType="org.apache.ibatis.gwmtest.entity.Person">select id,user_name as userName,age as age from test_user where id = #{666}</select>
</mapper>

然后测试代码如下:

  public static void ma333in(String[] args) throws Exception {PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);PersonMapper mapper1 = sqlSession2.getMapper(PersonMapper.class);Person person = mapper.getPerson2(1);sqlSession.commit();Person person1 = mapper1.getPerson2(1);System.out.println("person==person1 = " + (person == person1));}

输出结果:

2023-02-16 15:22:07,088 DEBUG [main] -org.apache.ibatis.transaction.jdbc.JdbcTransaction Opening JDBC Connection
2023-02-16 15:22:07,102 DEBUG [main] -org.apache.ibatis.datasource.pooled.PooledDataSource Created connection 1487470647.
2023-02-16 15:22:07,108 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson2 ==>  Preparing: select id,user_name as userName,age as age from test_user where id = ?
2023-02-16 15:22:07,159 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson2 ==> Parameters: 1(Integer)
2023-02-16 15:22:07,200 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson2 <==      Total: 1
2023-02-16 15:22:07,202 DEBUG [main] -org.apache.ibatis.transaction.jdbc.JdbcTransaction Opening JDBC Connection
2023-02-16 15:22:07,210 DEBUG [main] -org.apache.ibatis.datasource.pooled.PooledDataSource Created connection 1796371666.
2023-02-16 15:22:07,210 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson2 ==>  Preparing: select id,user_name as userName,age as age from test_user where id = ?
2023-02-16 15:22:07,211 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson2 ==> Parameters: 1(Integer)
2023-02-16 15:22:07,212 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson2 <==      Total: 1
person==person1 = false

发现没有命中二级缓存,因为不同 SqlSession,所以一级缓存也没有命中。为什么没有命中二级缓存,明明在开启了二级缓存,但是你要知道二级缓存是在哪里开启的?是在 PersonMapper 接口上,注意是接口文件上,PersonMapper.xml 资源文件中压根没有开启二级缓存,所以你使用 PersonMapper.xml 配置中的方法肯定命中不了二级缓存。那么要怎么才能够让他使用到 PersonMapper 接口上二级缓存呢?可以使用 <cache-ref> 标签,代码如下:

<?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="org.apache.ibatis.gwmtest.dao.PersonMapper"><cache-ref namespace="org.apache.ibatis.gwmtest.dao.PersonMapper"/><select id="getPerson2" resultType="org.apache.ibatis.gwmtest.entity.Person">select id,user_name as userName,age as age from test_user where id = #{666}</select>
</mapper>

<cache-ref> 标签中 namespace 属性可以引用到 PersonMapper 接口上配置二级缓存。最后测试可以命中二级缓存。

以上就是通过 @CacheNamespace 注解使用二级缓存的步骤。通知也要注意 Mapper 接口和 Mapper 配置文件中准备的二级缓存不是同一个,要使用同一个就需要互相进行引入。 <cache-ref> 标签就是用于配置文件中引入接口中配置的二级缓存。

2、使用 xml 配置缓存

直接在 PersonMapper.xml 配置中加上 <cache/> 标签,相当于在 PersonMapper.xml 配置中准备好一个二级缓存,和上面注解式的不一样,上面是在 PersonMapper 接口中准备二级缓存(两个缓存是一样的,可以互相引用)配置如下:

<?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="org.apache.ibatis.gwmtest.dao.PersonMapper"><select id="getPerson2" resultType="org.apache.ibatis.gwmtest.entity.Person">select id,user_name as userName,age as age from test_user where id = #{666}</select>
</mapper>

对应 PersonMapper 接口代码如下:


public interface PersonMapper {@Select("select id,user_name as userName,age as age from test_user where id = #{666}")Person getPerson(Integer id);Person getPerson2(Integer id);
}

注意此时不要用 @CacheNamespace 注解,因为在 xml 中已经通过 <cache/> 标签准备好二级缓存,所以这里不能再去构建一个二级缓存,会冲突报错,错误如下:

Caused by: java.lang.IllegalArgumentException: Caches collection already contains value for org.apache.ibatis.gwmtest.dao.PersonMapperat org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:1021)at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:977)at org.apache.ibatis.session.Configuration.addCache(Configuration.java:713)at org.apache.ibatis.builder.MapperBuilderAssistant.useNewCache(MapperBuilderAssistant.java:140)at org.apache.ibatis.builder.annotation.MapperAnnotationBuilder.parseCache(MapperAnnotationBuilder.java:190)at org.apache.ibatis.builder.annotation.MapperAnnotationBuilder.parse(MapperAnnotationBuilder.java:121)at org.apache.ibatis.binding.MapperRegistry.addMapper(MapperRegistry.java:72)at org.apache.ibatis.session.Configuration.addMapper(Configuration.java:848)at org.apache.ibatis.builder.xml.XMLMapperBuilder.bindMapperForNamespace(XMLMapperBuilder.java:432)at org.apache.ibatis.builder.xml.XMLMapperBuilder.parse(XMLMapperBuilder.java:97)at org.apache.ibatis.builder.xml.XMLConfigBuilder.mapperElement(XMLConfigBuilder.java:378)at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:120)

提示你已经存在缓存,你可以直接引用,但是你不要再重新准备,可以使用 @CacheNamespaceRef 注解引入,在此之前先接着测试下能不能命中二级缓存。

定义好了 PersonMapper 接口和 PersonMapper.xml 之后,开始测试,先测试 getPerson() 方法,注意这个方法是在 PersonMapper 接口上的,要知道测试的 PersonMapper 接口上面没有 @CacheNamespace 和 @CacheNamespaceRef 注解修饰,测试代码如下:

  public static void main(String[] args) throws Exception {PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);PersonMapper mapper1 = sqlSession2.getMapper(PersonMapper.class);Person person = mapper.getPerson(1);sqlSession.commit();Person person1 = mapper1.getPerson(1);mapper.getPerson(1);System.out.println("person==person1 = " + (person == person1));}

输出结果:

2023-02-16 15:43:42,638 DEBUG [main] -org.apache.ibatis.transaction.jdbc.JdbcTransaction Opening JDBC Connection
2023-02-16 15:43:42,652 DEBUG [main] -org.apache.ibatis.datasource.pooled.PooledDataSource Created connection 255944888.
2023-02-16 15:43:42,658 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson ==>  Preparing: select id,user_name as userName,age as age from test_user where id = ?
2023-02-16 15:43:42,703 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson ==> Parameters: 1(Integer)
2023-02-16 15:43:42,760 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson <==      Total: 1
2023-02-16 15:43:42,763 DEBUG [main] -org.apache.ibatis.transaction.jdbc.JdbcTransaction Opening JDBC Connection
2023-02-16 15:43:42,770 DEBUG [main] -org.apache.ibatis.datasource.pooled.PooledDataSource Created connection 1935972447.
2023-02-16 15:43:42,770 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson ==>  Preparing: select id,user_name as userName,age as age from test_user where id = ?
2023-02-16 15:43:42,771 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson ==> Parameters: 1(Integer)
2023-02-16 15:43:42,772 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson <==      Total: 1
person==person1 = false

发现没有使用到二级缓存,因为在 PersonMapper 接口上压根就没有定义二级缓存,直接去连接两次数据库查询,那怎么才能让他使用到二级缓存并且命中呢?上面说过在使用 @CacheNamespace 注解准备缓存直接冲突,所以这里应该使用 CacheNamespaceRef 注解,来引用在 PersonMapper.xml 中配置的二级缓存。代码如下:

@CacheNamespaceRef(PersonMapper.class)
public interface PersonMapper {@Select("select id,user_name as userName,age as age from test_user where id = #{666}")Person getPerson(Integer id);Person getPerson2(Integer id);
}

测试结果:

2023-02-16 15:49:48,135 DEBUG [main] -org.apache.ibatis.transaction.jdbc.JdbcTransaction Opening JDBC Connection
2023-02-16 15:49:48,146 DEBUG [main] -org.apache.ibatis.datasource.pooled.PooledDataSource Created connection 294184992.
2023-02-16 15:49:48,153 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson ==>  Preparing: select id,user_name as userName,age as age from test_user where id = ?
2023-02-16 15:49:48,212 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson ==> Parameters: 1(Integer)
2023-02-16 15:49:48,264 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson <==      Total: 1
2023-02-16 15:49:48,281  WARN [main] -org.apache.ibatis.io.SerialFilterChecker As you are using functionality that deserializes object streams, it is recommended to define the JEP-290 serial filter. Please refer to https://docs.oracle.com/pls/topic/lookup?ctx=javase15&id=GUID-8296D8E8-2B93-4B9A-856E-0A65AF9B8C66
2023-02-16 15:49:48,285 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper Cache Hit Ratio [org.apache.ibatis.gwmtest.dao.PersonMapper]: 0.5
person==person1 = false

发现又可以命中二级缓存。然后在测试 getPerson2() 方法,最终也是可以命中二级缓存的。

以上就是对 Mybatis 二级缓存的具体使用步骤。

相关文章:

MyBatis 二级缓存简单使用步骤

1、二级缓存使用 在 MyBatis 中默认二级缓存是不开启的&#xff0c;如果要使用需手动开启。在 mybatis-config.xml 配置文件中设置 cacheEnabled true &#xff0c;配置如下&#xff1a; <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE c…...

kubeadmin kube-apiserver Exited 始终起不来查因记录

kubeadmin kube-apiserver Exited 始终起不来查因记录 [rootk8s-master01 log]# crictl ps -a CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD b7af23a98302e …...

论文投稿指南——中文核心期刊推荐(工程材料学)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…...

【动态规划】背包问题题型及方法归纳

背包问题的种类 背包问题是在规定背包容量为j的前提下&#xff0c;每个物品对应的体积为v[i]&#xff0c;价值为w[i]&#xff0c;从物品0到物品i中选择物品放入背包中&#xff0c;找出符合某种要求的价值。 &#xff08;1&#xff09;背包问题种类 01背包&#xff1a;每种物…...

全球十大资质正规外汇期货平台排行榜(最新版汇总)

外汇期货简称为FxFut&#xff0c;是“Forex Futures”的缩写&#xff0c;是在集中形式的期货交易所内&#xff0c;交易双方通过公开叫价&#xff0c;以某种非本国货币买进或卖出另一种非本国货币&#xff0c;并签订一个在未来的某一日期根据协议价格交割标准数量外汇的合约。 …...

使用Paramiko时遇到的一些问题

目录 1.背景 2.问题合集 1&#xff09;“bash: command not found” 2&#xff09;Paramiko中正常的输入&#xff0c;却到了stderr&#xff0c;而stdout是空 3&#xff09;命令实际是alias 1.背景 在自动化脚本中&#xff0c;使用了库Paramiko&#xff0c;远程SSH到后台服…...

数据预处理(无量纲化、缺失值、分类特征、连续特征)

文章目录1. 无量纲化1.1 sklearn.preprocessing.MinMaxScaler1.2 sklearn.preprocessing.StandardScaler2. 缺失值3. 分类型特征4. 连续型特征数据挖掘的五大流程包括&#xff1a;获取数据数据预处理特征工程建模上线 其中&#xff0c;数据预处理中常用的方法包括数据标准化和归…...

【C#基础】C# 运算符总结

序号系列文章2【C#基础】C# 基础语法解析3【C#基础】C# 数据类型总结4【C#基础】C# 变量和常量的使用文章目录前言运算符1&#xff0c;算术运算符2&#xff0c;布尔逻辑运算符3&#xff0c;位运算符4&#xff0c;关系运算符5&#xff0c;赋值运算符6&#xff0c;其他运算符7&am…...

存储性能软件加速库(SPDK)

存储性能软件加速库SPDK存储加速存储性能软件加速库&#xff08;SPDK&#xff09;SPDK NVMe驱动1.用户态驱动1&#xff09;UIO2&#xff09;VFIOIOMMU&#xff08;I/O Memory Management Unit&#xff09;3&#xff09;用户态DMA4&#xff09;大页&#xff08;Hugepage&#xf…...

微服务(五)—— 服务注册中心Consul

一、引入依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-discovery</artifactId></dependency>二、配置yml文件 server:port: 8006spring:application:name: cloud-payment-con…...

冷冻电镜 - ChimeraX Density Map 密度图 操作

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://blog.csdn.net/caroline_wendy/article/details/129055160 由冷冻电镜所生成的Volume,需要观察其内部结构,使用ChimeraX进行操作。 加载Volumes,例如my_volume.mrc 效果如下: 高斯滤波 在命令行(Co…...

Matlab 点云旋转之轴角式

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 三维空间中表示旋转的方法有很多种,轴角式是其中非常经典的一种表示方式。虽然欧拉角表示旋转的方法很是常用,但欧拉角存在着万向锁这个问题,因此轴角式旋转在旋转使用中更为合适。其原理也很是明了,如下所述:…...

2023美赛数学建模资料思路模型

美赛我们为大家准备了大量的资料&#xff0c;我们会在比赛期间给大家分析美题目和相关的思路 全文都是干货&#xff0c;大家仔细阅读&#xff0c;资料文末自取&#xff01; 首先我们来看美赛23年题型的一个变化&#xff1a; 美赛23年题目变化&#xff1a; A题&#xff1a;连…...

Nginx配置HTTP强制跳转到HTTPS

https 访问我们的测试域名 https://www.xxx.com 站点&#xff0c;但是当我们直接在浏览器地址栏中直接输入 www.xxx.com 的时候却发现进入的是 http 协议的网站&#xff0c;这与我们的初衷不一致。由于浏览器默认访问域名使用的是80端口&#xff0c;而当我们使用SSL证书后&…...

从实现到原理,聊聊Java中的SPI动态扩展

原创&#xff1a;微信公众号 码农参上&#xff0c;欢迎分享&#xff0c;转载请保留出处。 八股文背多了&#xff0c;相信大家都听说过一个词&#xff0c;SPI扩展。 有的面试官就很喜欢问这个问题&#xff0c;SpringBoot的自动装配是如何实现的&#xff1f; 基本上&#xff0c…...

3、MySQL字符集

1.MySQL字符集和校验规则 字符集:是一套符号和编码的规则校验规则:是对该套符号和编码的校验,定义字符的排序和比较规则,其中是否区分大小写,跟校验规则有关。2.查看字符集方法 netstat -lntup |grep 3306 tcp6 0 0 :::3306 :::* …...

大漠插件最新中文易语言模块7.2302

模块名称:大漠插件中文模块最新通用7.2302模块简介:大漠插件中文模块最新通用7.2302模块特色:原翻译:花老板完善命令备注:易生易世本人花费一个月时间才将命令完善了插件的备注说明.且用且珍惜去掉了大漠插件定制版类.因为没用.模块特色:什么是中文模块?大漠插件模块是由大漠类…...

极客大挑战 2021

题量很大&#xff0c;收获挺多&#xff0c;持续时间也长&#xff0c;据说结束之后会再持续一段时间&#xff0c;然后题目会开源。 WEB Dark 暗网签到&#xff0c;难以置信 Welcome2021 改个请求方法会提示你文件&#xff0c;再进去就好了 babysql 直接把请求包扔sqlmap里&…...

C#开发的OpenRA加载文件的管理

C#开发的OpenRA加载文件的管理 在前面我们分析了mod.yaml文件,发现里面有很多文件列表, 比如下像下面的文件: Packages: ~^SupportDir|Content/cnc ~^SupportDir|Content/cnc/movies ^EngineDir $cnc: cnc ^EngineDir|mods/common: common ~speech.mix ~conquer.mix ~sounds…...

SSM实现文件上传

目录 SSM实现文件上传 1、修改from表单请求方式改为post&#xff0c;添加属性 2、修改springmvc配置文件&#xff0c;添加一下配置 3、后端方法 SSM实现文件上传 1、修改from表单请求方式改为post&#xff0c;添加属性&#xff1a; enctype"multipart/form-data"…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...