MyBatis源码介绍

news2024/11/28 6:50:10

文章目录

    • 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 {

    @Override
    public 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();
    }

    @Override
    public Object plugin(Object target) {
        // 为目标对象创建代理
        return Plugin.wrap(target, this);
    }

    @Override
    public 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.coloradmin.cn/o/1581921.html

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

相关文章

019——IIC模块驱动开发(基于EEPROM【AT24C02】和I.MX6uLL)

目录 一、 IIC基础知识 二、Linux中的IIC(韦东山老师的学习笔记) 1. I2C驱动程序的层次 2. I2C总线-设备-驱动模型 2.1 i2c_driver 2.2 i2c_client 三、 AT24C02 介绍 四、 AT24C02驱动开发 实验 驱动程序 应用程序 一、 IIC基础知识 总线类…

【linux】谈MobaXterm支持的连接方式

目前远程联机服务器主要有文字命令行接口和图形界面接口两种。 一、命令行接口方式 1.1 加密传输-SSH SSH为主,目前大多在网络上的数据封包都是加密的技术,等到传输的封包加密后再传输到网络上,以增加数据在Internet上面传送的安全性 1.2…

【软考】哈希表

目录 一、概念1.1 定义 二、哈希函数的构造方法2.1 说明2.2 特性 三、处理冲突的方法3.1 说明3.2 开放定址法3.2.1 说明3.2.2 线性探测 3.3 链地址法3.4 再哈希法3.5 建立公共溢出区 四、哈希表的查找4.1 查找过程4.2 查找特点4.3 装填因子 一、概念 1.1 定义 1.一般存储结构由…

Solid Converter 10.1下载地址及安装教程

Solid Converter 10是一款专业的PDF转换工具,用于将PDF文件转换为可编辑的文档格式,如Word、Excel、PowerPoint等。它提供了强大的转换功能和一系列实用的工具,帮助用户将PDF内容转换为可重复使用和编辑的格式。 Solid Converter 10的主要功…

vcruntime140.dll文件缺失的多种解决方法,这五种修复vcruntime140.dll绝对有效

当你在使用电脑的时候,可能会遇到一个提示错误,显示“vcruntime140.dll文件缺失,程序因此无法启动”。这种状况不但打断了你的日常使用,还可能对你的工作效率造成不利影响。为了助你更好地搞清楚这个问题的由来以及解决方案&#…

贪心算法|860.柠檬水找零

力扣题目链接 class Solution { public:bool lemonadeChange(vector<int>& bills) {int five 0, ten 0, twenty 0;for (int bill : bills) {// 情况一if (bill 5) five;// 情况二if (bill 10) {if (five < 0) return false;ten;five--;}// 情况三if (bill …

基于java+springboot+vue实现的人事管理系统(文末源码+Lw)23-242

摘 要 使用旧方法对人事管理系统的信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在人事管理系统的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题。这次开发的人事管理…

【C++】探索C++中的类与对象(下)---深入理解C++中的关键概念与应用

​​ &#x1f331;博客主页&#xff1a;青竹雾色间. &#x1f618;博客制作不易欢迎各位&#x1f44d;点赞⭐收藏➕关注 ✨人生如寄&#xff0c;多忧何为 ✨ 在C编程中&#xff0c;有许多重要的概念和特性&#xff0c;包括构造函数、explicit关键字、静态成员、友元以及内部类…

【Web世界探险家】CSS美学(一)

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更…

linux 迁移home目录以及修改conda中pip的目录,修改pip安装路径

1&#xff09;sudo rsync -av /home/lrf /data/home/lrf 将/home目录下的文件进行复制&#xff08;假设机械硬盘挂载在/data目录下&#xff09;** 2&#xff09;usermod -d /data/home/lrf -m lrf 修改用户$HOME变量** 3&#xff09;vi /etc/passwd 查看对应用户的$HOME变量是…

IDEA无法成功配置Tomcat的解决方法(IDEA版本问题)

在创建Servlet时&#xff0c;下载了Tomcat文件夹以及成功配置了环境变量之后&#xff0c;在IDEA中怎么都找不到Tomcat&#xff0c;尝试了网络中的各种方法&#xff0c;都不行&#xff0c;结果发现时IDEA版本的问题。因为我下的IDEA是社区版的&#xff0c;所以没有自带的Tomcat&…

【HTML】简单制作一个3D动态粒子效果的时空隧道

目录 前言 开始 HTML部分 CSS部分 效果图 总结 前言 无需多言&#xff0c;本文将详细介绍一段HTML&#xff0c;具体内容如下&#xff1a; 开始 首先新建文件夹&#xff0c;创建两个文本文档&#xff0c;其中HTML的文件名改为[index.html]&#xff0c;CSS的文件名改为[Bab…

【数据库】数据库应用系统生命周期

目录 1.为什么提出”软件工程“的思想&#xff1f; 2.为什么提出”瀑布模型“&#xff1f;缺点是什么&#xff1f; 3.为什么提出”快速原型模型“&#xff1f; 4.为什么提出”螺旋模型“&#xff1f; 5.关于数据库的英文缩写。 6.模型设计中的3条设计主线&#xff1a;数…

C++实现list容器

目录 1.前言 2.实现list容器 2.1链表结构体 2.2list迭代器 迭代器的成员变量 迭代器的构造函数 迭代器的&#xff0c;-- 迭代器的&#xff0c;&#xff01; 迭代器的解引用 迭代器的-> 3.list类 构造函数 析构函数 插入 删除 头插、尾插 头删、尾删 begin、end size empty 拷…

第23次修改了可删除可持久保存的前端html备忘录:增加了百度引擎

第22次修改了可删除可持久保存的前端html备忘录视频背景分离&#xff0c;增加了本地连接&#xff0c;增加了纯CSS做的折叠隐藏修改说明 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport…

采用Flink CDC操作SQL Server数据库获取增量变更数据

采用Flink CDC操作SQL Server数据库获取增量变更数据 Flink CDC 1.12版本引入了对SQL Server的支持&#xff0c;包括SqlServerCatalog和SqlServerTable。在SqlServerCatalog中&#xff0c;你可以根据表名获取对应的字段和字段类型。 SQL Server 2008 开始支持变更数据捕获 (C…

数码相框-显示JPG图片

LCD控制器会将LCD上的屏幕数据映射在相应的显存位置上。 通过libjpeg把jpg图片解压出来RGB原始数据。 libjpeg是使用c语言实现的读写jpeg文件的库。 使用libjpeg的应用程序是以"scanline"为单位进行图像处理的。 libjpeg解压图片的步骤&#xff1a; libjpeg的使…

FPGA:图像数字细节增强算法(工程+仿真+实物,可用毕设)

目录 日常唠嗑一、视频效果二、硬件及功能1、硬件选择2、功能3、特点 未完、待续……四、工程设计五、板级验证六、工程获取 日常唠嗑 有2个多月没写文章了&#xff0c;又是老借口&#xff1a;“最近实在是很忙”&#x1f923;&#xff0c;不过说真&#xff0c;确实是比较忙&am…

AWS服务器有哪些优势?

作为一家总部在美国的公司&#xff0c;AWS为什么会受到中国企业的喜爱&#xff1f;他有什么优势&#xff1f;九河云作为AWS合作伙伴&#xff0c;将会带读者展现使用AWS的优势。 首先是作为跨国企业&#xff0c;AWS在全球有数十个区域节点&#xff0c;这种广泛的地域覆盖不仅有…