MyBatis源码介绍

文章目录

    • MyBatis的核心流程介绍
    • SqlSessionFactory的理解
    • MyBatis中的Executor的源码理解
    • Spring中是如何解决MySQL的SqlSession的线程安全问题
    • MyBatis面向Mapper编程工作原理
    • Mybatis动态sql执行原理
    • Mybatis的一级、二级缓存实现原理
    • Mybatis的插件运行原理
    • 以及如何编写一个插件
    • mybatis插件的应用有哪些

计算机的基本工作就是存储和计算,而MyBatis是存储领域的利器。MyBatis的基本工作原理就是:先封装SQL,接着调用JDBC操作数据库,最后把数据库返回的表结果封装成Java类。

MyBatis的核心流程介绍

mybatis应用程序通过SqlSessionFactoryBuilder从mybatis-config.xml配置文件中构建出SqlSessionFactory,然后,SqlSessionFactory的实例直接开启一个SqlSession,再通过SqlSession实例获得Mapper对象并运行Mapper映射的SQL语句,完成对数据库的CRUD和事务提交,之后关闭SqlSession。如下图所示:
MyBatis的工作原理如下图所示:
在这里插入图片描述
sqlsessionfactoryBuilder类加载核心配置文件(sqlmapConfig.xml)parse方法会产生会产生一个configration对象, configration对象通过构造方法的方式交给sqlsessionfactory对象。sqlsessionfactory产生sqlsession对象,并且将configuration对象通过sqlsession 构造方法的方式传给sqlsession对象。Sqlsession通configration对象拿到excutor执行器,调用select方法时,底层该方法会从configuration对象中去找sql语句(mappedstatement),执行并返回结果集

SqlSessionFactory的理解

SqlSessionFactory是MyBatis中的一个关键接口,用于创建SqlSession对象,是MyBatis的核心组件之一。
SqlSessionFactory是通过SqlSessionFactoryBuilder创建的,SqlSessionFactoryBuilder会读取MyBatis的配置文件(mybatis-config.xml),并根据配置文件中的信息构建SqlSessionFactory对象。
SqlSessionFactory的主要作用是提供了创建SqlSession对象的方法,SqlSession对象是MyBatis中执行数据库操作的主要接口。SqlSession可以通过SqlSessionFactory的openSession方法创建,并且可以设置是否自动提交事务。SqlSession的生命周期应该在一个较小的范围内控制,避免长时间持有,以免占用数据库连接资源。
SqlSessionFactory可以被多个线程共享,应该保证SqlSessionFactory的单例,避免资源浪费。
除此之外,SqlSessionFactory还可以配置MyBatis的一些全局属性,如数据库连接池、缓存等,这些全局属性可以在整个应用程序中共享,从而提高应用程序的性能和可维护性。
总之,SqlSessionFactory是MyBatis中非常重要的一个接口,负责创建SqlSession对象和管理MyBatis全局属性的配置,使用SqlSessionFactory可以简化数据库操作的编写和管理,提高应用程序的性能和可维护性。
SqlSession的理解
MyBatis是一个优秀的持久层框架,而SqlSession则是MyBatis框架中最为核心的组件之一。SqlSession可以看做是对数据库操作的一次会话,每个会话中可以执行多次数据库操作。下面是对SqlSession的一些理解:

  1. SqlSession的生命周期:SqlSession的生命周期是从它的创建到关闭。SqlSession的创建可以通过SqlSessionFactory来创建,一般情况下,我们在需要访问数据库的时候,就会创建一个SqlSession对象。当SqlSession对象不再使用时,应该将其关闭。
  2. SqlSession的作用:SqlSession封装了对数据库的操作,包括数据的插入、更新、删除和查询等操作。通过SqlSession可以执行Mapper中定义的方法,并将执行结果返回给应用程序。SqlSession还提供了事务管理的支持。
  3. SqlSession的管理:在MyBatis中,SqlSession的管理是由SqlSessionFactory来管理的。SqlSessionFactory可以通过配置文件或者Java代码来创建,每个应用程序通常只需要一个SqlSessionFactory实例,用于创建SqlSession对象。在应用程序中,SqlSession的管理一般由Spring框架或者自己手动管理。
  4. SqlSession的线程安全性:SqlSession不是线程安全的,每个SqlSession实例都应该被单独使用,不能被多个线程共享。在多线程环境下,如果多个线程共用一个SqlSession对象,则可能会出现数据混乱的情况,因此需要保证每个线程都有自己的SqlSession实例。
    总之,SqlSession是MyBatis框架中最为核心的组件之一,它封装了对数据库的操作,提供了事务管理的支持,并由SqlSessionFactory进行管理。使用SqlSession时需要注意其生命周期、线程安全性等问题。

MyBatis中的Executor的源码理解

MyBatis框架中的Executor是一个执行器,负责执行SQL语句,与数据库进行交互,并将执行结果返回给调用方。Executor是MyBatis中最为核心的组件之一,它的实现涉及到多种设计模式和技术,包括装饰器模式、代理模式、线程池等。
Executor的实现类:MyBatis中默认提供了三个Executor的实现类,分别是SimpleExecutor、ReuseExecutor和BatchExecutor。SimpleExecutor是最简单的Executor实现,每次执行SQL语句都会创建一个新的Statement对象;ReuseExecutor会尝试重用Statement对象,避免多次创建Statement对象,提高执行效率;BatchExecutor则是批量执行SQL语句的Executor实现。
Executor的作用:Executor的主要作用是执行SQL语句,并将执行结果返回给调用方。在执行SQL语句之前,Executor会首先创建Statement对象,然后通过JDBC与数据库进行交互,将执行结果返回给MyBatis框架。Executor还负责缓存Statement对象,避免多次创建Statement对象,提高执行效率。
Executor的执行流程:Executor的执行流程可以概括为以下几个步骤:

  1. 根据传入的MappedStatement对象创建StatementHandler对象。
  2. 判断是否开启了二级缓存,如果开启了,则先从二级缓存中获取执行结果。
  3. 判断是否需要刷新缓存,如果需要,则清空缓存。
  4. 执行SQL语句,并将执行结果保存到缓存中。
  5. 如果开启了二级缓存,则将执行结果保存到二级缓存中。
    Executor的线程安全性:Executor是线程安全的,多个线程可以共用同一个Executor实例。在多线程环境下,Executor会使用线程池来管理多个线程的执行,避免线程竞争和线程创建销毁的开销。
    总之,Executor是MyBatis框架中最为核心的组件之一,它的实现涉及到多种设计模式和技术。Executor负责执行SQL语句,并将执行结果返回给调用方。使用Executor时需要注意其实现类、执行流程、线程安全性等问题。

Spring中是如何解决MySQL的SqlSession的线程安全问题

Spring提供了两种解决方案来解决SqlSession的线程安全问题:
1.使用SqlSessionTemplate
SqlSessionTemplate是Spring提供的一个线程安全的SqlSession实现。它封装了SqlSession的操作,并确保每个线程都有自己的SqlSession实例。因此,在多线程环境下,每个线程都可以独立地使用自己的SqlSession实例,而不会相互干扰。可以在配置文件中定义SqlSessionTemplate bean,然后在需要使用SqlSession时注入该bean。
2.使用@Scope注解
另一个解决方案是在配置文件中使用@Scope注解,将SqlSession的作用域设置为prototype。这将确保每次从容器中获取SqlSession时都会返回一个新的实例,因此每个线程都可以使用自己的SqlSession实例。可以在配置文件中声明SqlSession bean,并使用@Scope注解将其作用域设置为prototype。在需要使用SqlSession时,可以注入该bean。
这两种解决方案都可以有效地解决SqlSession的线程安全问题。选择哪种方案取决于具体的需求和实现细节。
MyBatis中的Configuration的源码的理解
Configuration类的源码主要涉及以下几个方面:
1.加载配置文件
在MyBatis的配置文件中,可以配置数据源、映射文件、插件、类型别名等信息。Configuration通过XMLConfigBuilder类来加载配置文件,并将解析后的配置信息保存到Configuration对象中。
2.创建SqlSessionFactory
Configuration类也负责创建SqlSessionFactory。它会通过build方法创建SqlSessionFactory对象,并将该对象缓存起来,以便后续使用。在创建SqlSessionFactory对象时,会将Configuration对象作为参数传入,以便SqlSessionFactory可以获取MyBatis的配置信息和映射信息。
3.管理映射信息
MyBatis中的映射文件通常包含SQL语句和实体类之间的映射关系。Configuration会读取映射文件,将其中的SQL语句解析成MappedStatement对象,并将其保存到mappedStatements集合中。mappedStatements集合中保存了所有映射文件中定义的SQL语句,以及它们对应的MappedStatement对象。
4.管理缓存
Configuration还负责管理MyBatis的缓存。它会读取配置文件中的缓存配置信息,并创建对应的缓存对象,缓存对象被保存在caches集合中。在执行SQL语句时,如果该语句对应的MappedStatement对象中配置了缓存,则会从caches集合中获取缓存对象,并使用缓存对象来提高查询效率。
总的来说,Configuration类是MyBatis框架的核心组成部分之一,它负责加载配置文件、管理映射信息和缓存等功能,是整个框架的配置和管理中心。通过深入理解Configuration的源码,我们可以更好地理解MyBatis框架的

MyBatis面向Mapper编程工作原理

Mapper接口是没有实现类的,当调用接口方法时,采用了JDK的动态代理,先从Configuration配置类MapperRegistry对象中获取mapper接口和对应的代理对象工厂信息(MapperProxyFactory),然后利用代理对象工厂MapperProxyFactory创建实际代理类(MapperProxy),最后在MapperProxy类中通过MapperMethod类对象内保存的中对应方法的信息,以及对应的sql语句的信息进行分析,最终确定对应的增强方法进行调用。

为什么MyBatis Mapper接口中的方法不支持重载
在MyBatis源码中有这么几行代码,我们可以看到在解析XML文件创建mapper接口对应方法的时候,采用了接口全限名+方法名的方式作为StrictMap(MappedStatement数据存放的Map集合)的key值,而源码对于StrictMap的put方法进行了判断,如果存入的数据key已重复则抛出异常,所以Mapper接口中的方法不支持重载

id = applyCurrentNamespace(id, false);public String applyCurrentNamespace(String base, boolean isReference) {...//返回值为mapper的全限名(xml中namespace的值)+方法名(xml中Statement id的值)return currentNamespace + "." + base;
}

Mybatis动态sql执行原理

(1)初始化阶段:通过XMLConfigBuilder、XMLMapperBuilder、XMLStatementBuilder解析XML文件中的信息存储到Configuration类中;
(2)代理阶段:先从Configuration配置类MapperRegistry对象中获取mapper接口和对应的代理对象工厂信息,再利用代理对象工厂MapperProxyFactory创建实际代理类,最后在MapperProxy类中通过MapperMethod类对象内保存的中对应方法的信息,以及对应的sql语句的信息进行分析,最终确定对应的增强方法进行调用。
(3)数据读写阶段:通过四种Executor调用四种Handler进行查询和封装数据;
Mybatis都有哪些Executor执行器?它们之间的区别是什么

BaseExecutor:基础抽象类,实现了executor接口的大部分方法,主要提供了缓存管理和事务管理的能力,使用了模板模式,doUpdate,doQuery,doQueryCursor 等方法的具体实现交给不同的子类进行实现
CachingExecutor:直接实现Executor接口,使用装饰器模式提供二级缓存能力。先从二级缓存查,缓存没有命中再从数据库查,最后将结果添加到缓存中。如果在xml文件中配置了cache节点,则会创建CachingExecutor。
BatchExecutor:BaseExecutor具体子类实现,在doUpdate方法中,提供批量执行多条SQL语句的能力;
SimpleExecutor:BaseExecutor具体子类实现且为默认配置,在doQuery方法中使用PrepareStatement对象访问数据库, 每次访问都要创建新的 PrepareStatement对象;
ReuseExecutor:BaseExecutor具体子类实现,与SimpleExecutor不同的是,在doQuery方法中,使用预编译PrepareStatement对象访问数据库,访问时,会重用缓存中的statement对象,而不是每次都创建新的PrepareStatement。

Mybatis的一级、二级缓存实现原理

(1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,Mybatis默认打开一级缓存,一级缓存存放在BaseExecutor的localCache变量中:

(2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace)级别。Mybatis默认不打开二级缓存,可以在config文件中xml开启全局的二级缓存,但并不会为所有的Mapper设置二级缓存,每个mapper.xml文件中使用标签来开启当前mapper的二级缓存,二级缓存存放在MappedStatement类cache变量中:

(3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被清除并重新更新,如果开启了二级缓存,则只根据配置判断是否刷新。

Mybatis的插件运行原理

Mybatis 仅可以编写针对 ParameterHandler、ResultSetHandler、
StatementHandler、Executor 这 4 种接口的插件,Mybatis 使用 JDK 的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这 4 种接口对象的方法时,就会进入拦截方法,具体就是 InvocationHandler 的 invoke()方法,当然,只会拦截那些你指定需要拦截的方法。
编写插件:实现 Mybatis 的 Interceptor 接口并复写 intercept()方法,然 后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了 在配置文件中配置你编写的插件
MyBatis 的插件(Interceptor)是一种可以拦截并修改 MyBatis 执行过程的机制,它可以在 SQL 语句执行的各个阶段进行干预和增强,比如在 SQL 语句执行前后添加日志、统计信息等功能。插件的运行原理主要涉及以下几个关键点:

  1. Interceptor 接口:
    ○ MyBatis 的插件需要实现 Interceptor 接口,并覆盖其中的 intercept 方法,在这个方法中编写拦截逻辑。
  2. 拦截器链:
    ○ 在 MyBatis 的配置文件(mybatis-config.xml)中,可以通过 标签配置插件,并指定插件类的路径。MyBatis 在初始化时会构建一个插件链,将所有配置的插件按顺序组成一个链表结构,当执行 SQL 语句时,会依次调用每个插件的 intercept 方法。
  3. 拦截点:
    每个插件可以通过实现 intercept 方法来定义拦截点,即在 SQL 语句执行的哪个阶段进行拦截和处理。常见的拦截点包括:生成代理对象、创建 Statement 对象、执行查询操作等。
  4. Invocation 对象:
    ○ 在 intercept 方法中,每个插件都会接收一个 Invocation 对象作为参数,该对象包含了目标对象、方法以及方法参数等信息,插件可以根据这些信息进行自定义的处理。
  5. 动态代理:
    ○ MyBatis 中的插件是通过动态代理来实现的,插件会对目标对象进行代理,当调用目标对象的方法时,会先经过插件的拦截逻辑,再转发给目标对象执行。
    总体来说,MyBatis 插件的运行原理是通过动态代理和拦截器链实现的,插件可以在 SQL 执行的各个阶段进行拦截和处理,从而实现对 MyBatis 执行过程的定制化扩展。开发者可以利用插件机制来实现日志记录、性能监控、权限控制等功能,从而满足项目特定需求。

应用场景

  1. 一些字段的自动填充
  2. SQL语句监控、打印、数据权限等
  3. 数据加解密操作、数据脱敏操作
  4. 分页插件
  5. 参数、结果集的类型转换

以及如何编写一个插件

Mybatis 是一个流行的 Java ORM 框架,允许将 SQL 语句映射到 Java 对象。编写一个 Mybatis 插件可以扩展框架的功能,提供更好的灵活性和可维护性。下面是一个简单的 Mybatis 插件示例:

  1. 创建一个 Java 项目并添加 Mybatis 和 Mybatis-Spring 的依赖。
  2. 创建一个类,实现 org.apache.ibatis.plugin.Interceptor 接口,并重写以下方法:
public Object intercept(Invocation invocation) throws Throwable;
public Object plugin(Object target);
public void setProperties(Properties properties);
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.Configuration;import java.sql.Connection;
import java.util.Properties;@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
})
public class MyPlugin implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {// 在 StatementHandler 准备期间执行的操作StatementHandler statementHandler = (StatementHandler) invocation.getTarget();String originalSql = statementHandler.getBoundSql().getSql();System.out.println("原始 SQL 语句: " + originalSql);return invocation.proceed();}@Overridepublic Object plugin(Object target) {// 为目标对象创建代理return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {// 接收来自 Mybatis 配置文件的属性设置String foo = properties.getProperty("foo");System.out.println("foo 属性: " + foo);}
}
  1. 在 intercept 方法中,您可以添加任何您想要执行的逻辑。例如,可以在此处修改 SQL 语句或添加自定义逻辑。在本例中,我们只是简单地打印原始 SQL 语句。
  2. 在 plugin 方法中,使用 Plugin.wrap 方法为目标对象创建代理。这将使 Mybatis 在执行目标对象的方法之前和之后调用插件中的方法。
  3. 在 setProperties 方法中,可以接收来自 Mybatis 配置文件的属性设置。这些属性可用于根据需要配置插件行为。
  4. 将插件添加到 Mybatis 配置文件(例如 mybatis-config.xml)中:
注意:确保将 元素的 name 属性设置为插件类中 setProperties 方法接受的参数。在本例中,我们接受一个名为 foo 的属性。

编写插件的步骤:
(1)实现Interceptor接口方法
(2)确定拦截的签名
(3)在配置文件中配置插件
在创建三个重要的Handler(StatementHandler、ParameterHandler、ResultSetHandler)时通过插件数组包装了三大Handler:
resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);
获取到所有的Interceptor(拦截器)(插件需要实现的接口),调用:
interceptor.plugin(target);
返回target包装后的对象,最后回调回自定义插件的intercept方法执行插件内的代码逻辑。可拦截的接口和方法一览:
Executor(update、query 、 flushStatment 、 commit 、 rollback 、 getTransaction 、 close 、 isClose)
StatementHandler(prepare 、 paramterize 、 batch 、 update 、 query)
ParameterHandler( getParameterObject 、 setParameters )
ResultSetHandler( handleResultSets 、 handleCursorResultSets 、 handleOutputParameters )

mybatis插件的应用有哪些

MyBatis 是一个开源的持久层框架,它简化了数据库操作,并且提供了很多方便的功能。MyBatis 插件是一种扩展机制,允许开发人员在 MyBatis 的核心功能上添加自定义的功能或者行为。下面是一些常见的 MyBatis 插件的应用场景:

  1. 分页插件:提供了在 SQL 查询中添加分页功能的支持,常见的分页插件有 MyBatis-PageHelper 和 MyBatis-Spring 的分页支持。
  2. 缓存插件:MyBatis 提供了一级缓存和二级缓存,但有时候需要更加灵活地控制缓存的行为,比如清除缓存、自定义缓存键等。缓存插件可以扩展 MyBatis 的缓存功能,如 MyBatis-Redis、MyBatis-Ehcache 等。
  3. 审计插件:用于记录数据库操作的日志,包括操作类型、执行时间、参数等信息,便于后期排查问题和审计。常见的审计插件有 MyBatis-SQLLogger、MyBatis-Log4j2 等。
  4. 乐观锁插件:实现乐观锁机制,用于在并发情况下避免数据的冲突。乐观锁插件可以在更新操作中自动判断数据版本,避免更新过期数据。常见的乐观锁插件有 MyBatis-OptimisticLocker 等。
  5. 数据加密插件:用于对数据库中的敏感数据进行加密处理,保护数据安全。数据加密插件可以在 MyBatis 的查询和写入操作中自动加解密数据。常见的数据加密插件有 MyBatis-Encrypt 等。
  6. SQL 注入插件:用于检测和防止 SQL 注入攻击,可以在 SQL 执行前对参数进行检查和过滤,确保 SQL 的安全执行。常见的 SQL 注入插件有 MyBatis-SQLInjection 等。
  7. 自定义类型处理器插件:用于处理数据库字段与 Java 类型之间的映射关系,可以自定义类型处理器来处理特定类型的数据转换。常见的自定义类型处理器插件有 MyBatis-EnumTypeHandler、MyBatis-JsonTypeHandler 等。
    这些插件可以根据项目的需求进行选择和集成,提高开发效率和代码质量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/803291.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

制作一个RISC-V的操作系统十-Trap和Exception(流 mtvec mepc mcause mtval mstatus trap完整流程)

文章目录 流mtvecmepcmcausemtvalmstatustrap 初始化trap的top half(硬件完成)trap的bottom half(软件完成)从trap返回代码实现 流 控制流:程序控制的执行流 trap分为中断和异常 mtvec base:存储trap入…

2_8.Linux系统引导过程及引导修复

# 1.磁盘引导 # mbr主引导记录0磁道1扇区446 作用: 记录grub2引导文件的位置 当mbr数据丢失系统会因为找不到启动分区而停止启动 问题模拟方式: 系统磁盘/dev/sda dd if/dev/zero of/dev/vda bs446 count1 ##清空系统/dev/sda上的mbr数据 恢复方式: &…

图形化界面使用MQ!!!

一、docker安装 1、拉去镜像 docker pull rabbitmq:3.10-management 2、Docker运行,并设置开机自启动(第一个-p是MQ默认配置的端口,第二个-p是图形化界面配置的端口) docker run -d --restartalways --name rabbitmq -p 5672:5672…

直播系统的短视频直播源码,带有多功能后台系统的直播短视频平台 APP 源码。

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 此源码是一个直播系统,集直播、短视频等功能,根据市场趋势开发并推出思乐直播APP,APP功能丰富且可在后台管理系统进行配置,做到按需求来…

《QT实用小工具·二十二》多种样式导航按钮控件

1、概述 源码放在文章末尾 该项目实现了多种样式的导航按钮控件 可设置文字的左侧、右侧、顶部、底部间隔。 可设置文字对齐方式。 可设置显示倒三角、倒三角边长、倒三角位置、倒三角颜色。 可设置显示图标、图标间隔、图标尺寸、正常状态图标、悬停状态图标、选中状态图标…

ctfshow web入门 文件上传web162--web167

web162 session文件包含条件竞争 直接包含不传马了 我们上传的文件如果不符合要求,就会被删除,导致成功上传无法访问,没有用。但是如果我们上传的速度比服务器删的速度快,就可以了。 上传.user.ini GIF89a auto_append_file/tmp/…

四、书城开发--3、书城图书部分的开发

书城图书部分 首先我们做书城首页搜索栏下面的图片展示 我们在书城首页组件中通过home请求方法中获取回来的数据中,打印出来可以看到那个banner就是我们现在要的图片 我们在data中定义一个变量banner用来存放获取回来的数据中的banner 然后把它展示出来就可以了&a…

LeetCode-84. 柱状图中最大的矩形【栈 数组 单调栈】

LeetCode-84. 柱状图中最大的矩形【栈 数组 单调栈】 题目描述:解题思路一:单调栈解题思路二:解题思路三: 题目描述: 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且…

阿赵UE学习笔记——26、动画混合空间

阿赵UE学习笔记目录   大家好,我是阿赵。   继续学习虚幻引擎的使用。之前学习了通过蓝图直接控制动画播放,或者通过动画状态机去控制播放。这次来学习一种比较细致的动画控制播放方式,叫做动画混合空间。 一、使用的情景 假设我们现在需…

ssm035基于JavaWeb的家居商城系统的设计与实现+jsp

家居商城系统 摘 要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于家居商城系统当然也不能排除在外,随着网络技术的不断成熟,带动了家居商城系统,它彻底改…

Linux操作系统安装注意事项(新手简易版)

Linux操作系统安装注意事项(新手简易版) 目录: 1、字符集安装 2、磁盘分区 3、关闭KDUMP防火墙 4、时区选择 注:事例截图是centos8的安装,其他版本是一样的 1、字符集安装 ecology运行需要用到GBK和UTF8字符…

设计模式-结构型-装饰器模式-decorator

发票基本类 public class Invoice {public void printInvoice() {System.out.println("打印发票正文");} } 发票正文类 public class Decorator extends Invoice {protected Invoice ticket;public Decorator(Invoice ticket) {this.ticket ticket;}Overridepubl…

Android获取连接到手机热点上的设备信息

主题:在手机开启热点网络的情况下,想要获取是哪个设备已经连接上了当前开启的热点。 实现思路:Android通过读取 /proc/net/arp 文件可以得到连接当前热点的设备信息,包括Mac地址、IP地址等信息。 一. 方法逻辑: /*** …

ruoyi-vue-pro 前端vue js直接import导入本地文件使用方法

我的xml文件名称叫w2101.xml 第一步,删除所有依赖,否则配置以后就会启动报错: 第二步配置对应的文件格式,我当前使用的是xml文件 config.module.rule(xml).test(/\.xml$/).use(xml-loader).loader(xml-loader).end();第三步…

你应该知道的21个html小技巧

本文翻译自 21 HTML Tips You Must Know About,作者:Shefali, 略有删改。 在这篇文章中,我将分享21个HTML技巧和代码片段,可以提高你的编码技能。 链接联系人 使用HTML创建可点击的电子邮件、电话和短信链接&#xf…

转圈游戏——快速幂

目录 题目 思路 代码 题目 思路 每个小朋友移动一次的位置为,移动 q 次的位置则为。那么题目要求移动 ,最后的位置为 。 但 的范围是,而总的移动次数是 。时间复杂度是在,因此是一定不能硬算的,肯定会超时。那么该…

长期通配符证书介绍

长期通配符证书是指有效期较长的泛域名证书,这种证书允许您使用单一证书为一个主域名及其所有相关子域名提供长期的HTTPS加密服务。获取长期通配符证书的过程与普通通配符证书相似,但需要注意选择具有较长有效期的证书产品,并确保符合CA机构及…

私域电商客户要挨一刀的“订单发货管理”,微信:必须强制接入

文丨微三云营销总监胡佳东,点击上方“关注”,为你分享市场商业模式电商干货。 - 引言:超90%的私域运营商家都见到了或者说遇到了这个问题,如果没有读懂这个微信的模型机制,一定会懵逼,微三云营销总监胡佳…

SpringBoot整合MyBatis四种常用的分页方式

目录 方式1 一、准备工作 1. 创建表结构 2. 导入表数据 3. 导入pom.xml依赖 4. 配置application.yml文件 5. 创建公用的实体类 项目结构 2. 创建controller层 3. 创建service层 4. 创建mapper层 5. 创建xml文件 6. 使用postman进行测试,测试结果如下…

DNS 各记录类型说明及规则

各记录类型使用目的 记录类型使用目的A 记录将域名指向一个 IP 地址。CNAME 记录将域名指向另一个域名,再由另一个域名提供 IP 地址。MX 记录设置邮箱,让邮箱能收到邮件。NS 记录将子域名交给其他 DNS 服务商解析。AAAA 记录将域名指向一个 IPv6 地址。…