【MySQL】事务——事务的引入、事务的概念、什么是事务、为什么会出现事务、事务的版本支持、事务的提交方式、事务常见操作方式

news2024/11/13 14:31:57

文章目录

  • MySQL
    • 1. 事务的引入
    • 2. 事务的概念
      • 2.1 什么是事务
      • 2.2 为什么会出现事务
      • 2.3 事务的版本支持
      • 2.4 事务的提交方式
      • 2.5 事务常见操作方式
        • 2.5.1 测试事务开始和回滚
        • 2.5.2 测试未commit事务回滚
        • 2.5.3 测试commit事务持久化
        • 2.5.4 测试begin事务不受自动提交影响
        • 2.5.5 测试单条SQL和事务关系

MySQL

在这里插入图片描述
  

1. 事务的引入

  这是火车票销售系统的一个售票过程:

在这里插入图片描述

  

  我们根据上面的看到,1.客户端A先进入到了买票程序中进行买票操作,2.此时客户端B也同样进入了买票系统,由于没有及时更新数据库,nums>0依然成立,3.客户端B进行买票操作,4.客户端A更新票数,5.客户端B更新票数。那票数就变成了-1张,这在现实中显然不成立。

  

  为了解决上述问题,对于买票的CURD要有一定的要求。这个和和多线程加锁访问临界资源有一些相似之处。

  1. 买票的过程得是原子的。

  2. 买票互相应该不能影响。

  4. 买完票应该要永久有效。

  5. 买前,和买后都要是确定的状态。

  
  我们可以使用MySQL的事务很好的解决上面出现的问题。
  

2. 事务的概念

2.1 什么是事务

  事务是一组在逻辑上相关的 DML 语句,要么全部成功,要么全部失败,是一个整体,MySQL 提供机制让我们能够保证这种效果,且规定了不同客户端看到的数据是不同的。

  事务用于处理操作量大、复杂度高的数据, 假设一种场景:你毕业了,学校的教务系统后台 MySQL 中,不需要你的数据了,要删除你的所有信息, 那么要删除你的基本信息(姓名,电话,籍贯等)的同时,也删除和你有关的其他信息,比如:你的各科成绩,你在校表现,甚至你在论坛发过的文章等。这样,就需要多条 MySQL 语句构成,那么所有这些操作合起来,就构成了一个事务。

  一个 MySQL 数据库,肯定不止一个事务在运行,同一时刻,会有大量的请求被包装成事务,在向 MySQL 服务器发起事务处理请求。 而且每条事务至少一条 SQL ,最多很多 SQL ,这样如果大家都访问同样的表数据,在不加保护的情况,就绝对会出现问题。

  因为事务由多条 SQL 构成,那么也可能会出现执行到一半出错或者不想再执行的情况,那么已经执行的怎么办呢?

  

  所有,一个完整的事务,绝对不是简单的 sql 集合,还需要满足如下四个属性:acid(酸的)

  原子性(Atomicity,或称不可分割性)

  一致性(Consistency)

  隔离性(Isolation,又称独立性)

  持久性(Durability)

  

  原子性一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,就好像事务是不可分割的最小工作单元。,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

  例如,在银行转账的事务中,从一个账户扣除款项并将其添加到另一个账户,这两个操作要么都成功完成,要么都不发生。

  

  一致性在事务开始之前和事务结束以后,数据库的完整性没有被破坏,也就是要求事务执行的结果必须使数据库从一个合法的状态转换到另一个合法的状态。 这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

  例如,在银行转账事务中,转账前后所有账户的余额总和应该保持不变,这也是一致性的体现。如果因为某种原因导致余额总和发生了错误的变化,那么这个事务就没有满足一致性要求。

  

  隔离性数据库允许多个并发事务同时对其数据进行读写和修改的能力,它们之间相互隔离,互不干扰, 隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交( Read uncommitted )、读提交( read committed )、可重复读( repeatable read )和串行化( Serializable )

  例如,在上面的在线订票系统中,如果没有适当的隔离性控制,可能会出现多个用户同时看到相同的剩余票数,然后都进行订票操作,导致票数出现错误的情况。通过合理设置隔离级别,可以避免这种问题的发生。

  

  持久性事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

  例如,在一个银行系统中,客户存款的事务提交后,存款金额的增加会被持久保存,不会因为后续的任何故障而消失。

  

2.2 为什么会出现事务

  事务被 MySQL 编写者设计出来,本质是为了当应用程序访问数据库的时候,事务能够简化我们的编程模型,不需要我们去考虑各种各样的潜在错误和并发问题。

  可以想一下当我们使用事务时,要么提交,要么回滚,我们不会去考虑网络异常了,服务器宕机了,同时更改一个数据怎么办对吧?

  因此事务本质上是为了应用层服务的,而不是伴随着数据库系统天生就有的。

  备注:我们后面把 MySQL 中的一行信息,称为一行记录。

  

2.3 事务的版本支持

  在 MySQL 中只有使用了Innodb 数据库引擎的数据库或表才支持事务, MyISAM 不支持。

  
查看数据库引擎:

mysql> show engines; -- 表格显示
mysql> show engines \G -- 行显示

  
在这里插入图片描述

  

2.4 事务的提交方式

  事务的提交方式常见的有两种:自动提交,手动提交

  
查看事务提交方式:

mysql> show variables like 'autocommit';

在这里插入图片描述

  

用 SET 来改变 MySQL 的自动提交模式:

mysql> SET AUTOCOMMIT=0; #SET AUTOCOMMIT=0 禁止自动提交

在这里插入图片描述

  

mysql> SET AUTOCOMMIT=1; #SET AUTOCOMMIT=1 开启自动提交

在这里插入图片描述

  

2.5 事务常见操作方式

  开始一个事务:

  使用 begin 或 start transaction 语句来开启一个事务。

  

  创建一个保存点:

  savepoint 加上自定义的保存点名字,可以在事务中创建保存点。保存点的作用是让您能够在事务执行的过程中,有选择地回滚到特定的点。

  

  回滚操作:

  rollback to 保存点名字 :将事务回滚到指定的保存点,保存点之后的操作被撤销,但保存点之前的操作仍然有效。

  直接使用 rollback :会将事务直接回滚到事务的最开始,所有操作都被撤销。

  

  提交事务:

  commit 语句用于提交事务,将事务中所做的更改永久保存到数据库中,使其对其他事务可见。

  

  查看事务的隔离级别:

  select @@tx_isolation 用于查看当前事务的隔离级别。

  

创建测试环境:

## Centos 7 云服务器,默认开启3306 mysqld服务

## 使用win cmd远程访问Centos 7云服务器,mysqld服务(需要win上也安装了MySQL,这里看到结果即可)

## 注意,使用本地mysql客户端,可能看不到链接效果,本地可能使用域间套接字,查不到链接
C:\Users\whb>mysql -uroot -padim123

## 使用netstat查看链接情况,可知:mysql本质是一个客户端进程

## 为了便于演示,我们将mysql的默认隔离级别设置成读未提交。
## 具体操作我们后面专门会讲,现在已使用为主。
mysql> set global transaction isolation level READ UNCOMMITTED;
Query OK, 0 rows affected (0.00 sec)

mysql> quit
Bye

##需要重启终端,进行查看
mysql> select @@tx_isolation;
+------------------+
|  @@tx_isolation  |
+------------------+
| READ-UNCOMMITTED |
+------------------+
1 row in set, 1 warning (0.00 sec)

  

创建测试表:

create table if not exists account(
	id int primary key,
	name varchar(50) not null default '',
	blance decimal(10,2) not null default 0.0
)ENGINE=InnoDB DEFAULT CHARSET=UTF8;

  

2.5.1 测试事务开始和回滚

正常演示 - 证明事务的开始与回滚:

mysql> show variables like 'autocommit'; -- 查看事务是否自动提交。我们故意设置成自动提交,看看该选项是否影响begin
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |  
+---------------+-------+
1 row in set (0.00 sec)

mysql> start transaction; -- 开始一个事务begin也可以,推荐begin
Query OK, 0 rows affected (0.00 sec)

mysql> savepoint save1; -- 创建一个保存点save1
Query OK, 0 rows affected (0.00 sec)

mysql> insert into account values (1, '张三', 100); -- 插入一条记录
Query OK, 1 row affected (0.05 sec)

mysql> savepoint save2; -- 创建一个保存点save2
Query OK, 0 rows affected (0.01 sec)

mysql> insert into account values (2, '李四', 10000); -- 在插入一条记录
Query OK, 1 row affected (0.00 sec)

mysql> select * from account; -- 两条记录都在了
+----+--------+----------+
| id |  name  |  blance  |
+----+--------+----------+
| 1  |   张三  |   100.00 |
| 2  |   李四  | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)


mysql> rollback to save2; -- 回滚到保存点save2
Query OK, 0 rows affected (0.03 sec)

mysql> select * from account; -- 一条记录没有了
+----+--------+--------+
| id |  name  | blance |
+----+--------+--------+
| 1  |  张三   | 100.00 |
+----+--------+--------+
1 row in set (0.00 sec)

mysql> rollback; -- 直接rollback,回滚在最开始
Query OK, 0 rows affected (0.00 sec)

mysql> select * from account; -- 所有刚刚的记录没有了
Empty set (0.00 sec)

  

2.5.2 测试未commit事务回滚

非正常演示1 - 证明未commit,客户端崩溃,MySQL自动会回滚(隔离级别设置为读未提交):

-- 终端A
mysql> select * from account; -- 当前表内无数据
Empty set (0.00 sec)

mysql> show variables like 'autocommit'; -- 依旧自动提交
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
|  autocommit   |  ON   |
+---------------+-------+
1 row in set (0.00 sec)

mysql> begin; --开启事务
Query OK, 0 rows affected (0.00 sec)

mysql> insert into account values (1, '张三', 100); -- 插入记录
Query OK, 1 row affected (0.00 sec)

mysql> select * from account; --数据已经存在,但没有commit,此时同时查看
终端B
+----+--------+--------+
| id |  name  | blance |
+----+--------+--------+
| 1  |  张三   | 100.00 |
+----+--------+--------+
1 row in set (0.00 sec)

mysql> Aborted -- ctrl + \ 异常终止MySQL

--终端B
mysql> select * from account; --终端A崩溃前
+----+--------+--------+
| id |  name  | blance |
+----+--------+--------+
| 1  |  张三   | 100.00 |
+----+--------+--------+
1 row in set (0.00 sec)

mysql> select * from account; --数据自动回滚
Empty set (0.00 sec)

  

2.5.3 测试commit事务持久化

非正常演示2 - 证明commit了,客户端崩溃,MySQL数据不会在受影响,已经持久化:

--终端 A
mysql> show variables like 'autocommit'; -- 依旧自动提交
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
|  autocommit   |  ON   |
+---------------+-------+
1 row in set (0.00 sec)

mysql> select * from account; -- 当前表内无数据
Empty set (0.00 sec)

mysql> begin; -- 开启事务
Query OK, 0 rows affected (0.00 sec)

mysql> insert into account values (1, '张三', 100); -- 插入记录
Query OK, 1 row affected (0.00 sec)

mysql> commit; --提交事务
Query OK, 0 rows affected (0.04 sec)

mysql> Aborted -- ctrl + \ 异常终止MySQL

--终端 B
mysql> select * from account; --数据存在了,所以commit的作用是将数据持久化到MySQL中
+----+--------+--------+
| id |  name  | blance |
+----+--------+--------+
| 1  |  张三   | 100.00 |
+----+--------+--------+
1 row in set (0.00 sec)

  

2.5.4 测试begin事务不受自动提交影响

  自动提交的作用(不启动事务时):自动提交开启,即使客户端异常崩溃,也会自动提交;自动提交关闭,异常情况下数据会回滚。

  

非正常演示3 - 对比试验。证明begin操作会自动更改提交方式,不会受MySQL是否自动提交影响:

-- 终端 A
mysql> select *from account; --查看历史数据
+----+--------+--------+
| id |  name  | blance |
+----+--------+--------+
| 1  |  张三   | 100.00 |
+----+--------+--------+
1 row in set (0.00 sec)

mysql> show variables like 'autocommit'; --查看事务提交方式
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
|  autocommit   |  ON   |
+---------------+-------+
1 row in set (0.00 sec)

mysql> set autocommit=0; --关闭自动提交
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'autocommit'; --查看关闭之后结果
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
|  autocommit   |  OFF  |
+---------------+-------+
1 row in set (0.00 sec)

mysql> begin; --开启事务
Query OK, 0 rows affected (0.00 sec)

mysql> insert into account values (2, '李四', 10000); --插入记录
Query OK, 1 row affected (0.00 sec)

mysql> select *from account; --查看插入记录,同时查看终端B
+----+--------+----------+
| id |  name  |  blance  |
+----+--------+----------+
| 1  |  张三   |  100.00  |
| 2  |  李四   | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)

mysql> Aborted --再次异常终止

-- 终端B
mysql> select * from account; --终端A崩溃前
+----+--------+----------+
| id |  name  |  blance  |
+----+--------+----------+
| 1  |  张三   |   100.00 |
| 2  |  李四   | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)

mysql> select * from account; --终端A崩溃后,自动回滚
+----+--------+--------+
| id |  name  | blance |
+----+--------+--------+
| 1  |  张三   | 100.00 |
+----+--------+--------+
1 row in set (0.00 sec)

  

2.5.5 测试单条SQL和事务关系

非正常演示4 - 证明单条 SQL 与事务的关系:

--实验一
-- 终端A
mysql> select * from account;
+----+--------+--------+
| id |  name  | blance |
+----+--------+--------+
| 1  |  张三   | 100.00 |
+----+--------+--------+
1 row in set (0.00 sec)

mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
|  autocommit   |  ON   |
+---------------+-------+
1 row in set (0.00 sec)

mysql> set autocommit=0; --关闭自动提交
Query OK, 0 rows affected (0.00 sec)

mysql> insert into account values (2, '李四', 10000); --插入记录
Query OK, 1 row affected (0.00 sec)

mysql> select *from account; --查看结果,已经插入。此时可以在查看终端B
+----+--------+----------+
| id |  name  |  blance  |
+----+--------+----------+
| 1  |  张三  |  100.00   |
| 2  |  李四  | 10000.00  |
+----+--------+----------+
2 rows in set (0.00 sec)

mysql> ^DBye --ctrl + \ or ctrl + d,终止终端

--终端B
mysql> select * from account; --终端A崩溃前
+----+--------+----------+
| id |  name  |  blance  |
+----+--------+----------+
| 1  |  张三   |  100.00  |
| 2  |  李四   | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)

mysql> select * from account; --终端A崩溃后
+----+--------+--------+
| id |  name  | blance |
+----+--------+--------+
| 1  |  张三   | 100.00 |
+----+--------+--------+
1 row in set (0.00 sec)

-- 实验二
--终端A
mysql> show variables like 'autocommit'; --开启默认提交
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
|  autocommit   |  ON   |
+---------------+-------+
1 row in set (0.00 sec)

mysql> select * from account;
+----+--------+--------+
| id |  name  | blance |
+----+--------+--------+
| 1  |  张三   | 100.00 |
+----+--------+--------+
1 row in set (0.00 sec)

mysql> insert into account values (2, '李四', 10000);
Query OK, 1 row affected (0.01 sec)

mysql> select *from account; --数据已经插入
+----+--------+----------+
| id |  name  |  blance  |
+----+--------+----------+
| 1  |   张三  |  100.00  |
| 2  |   李四  | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)

mysql> Aborted --异常终止

--终端B
mysql> select * from account; --终端A崩溃前
+----+--------+----------+
| id |  name  |  blance  |
+----+--------+----------+
| 1  |  张三   |  100.00  |
| 2  |  李四   | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)

mysql> select * from account; --终端A崩溃后,并不影响,已经持久化。autocommit起作用
+----+--------+----------+
| id |  name  |  blance  |
+----+--------+----------+
| 1  |  张三   |   100.00 |
| 2  |  李四   | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)

  

  从上面的例子,我们能看到事务本身的原子性(回滚),持久性(commit)结论:

  只要输入begin或者start transaction,事务便必须要通过commit提交,才会持久化,与是否设置set autocommit无关。

  事务可以手动回滚,同时,当操作异常,MySQL会自动回滚。

  对于 InnoDB 每一条 SQL 语言都默认封装成事务,自动提交。(select有特殊情况,因为MySQL 有 MVCC )。

  

  事务操作注意事项:

  如果没有设置保存点,也可以回滚,只能回滚到事务的开始。直接使用 rollback(前提是事务还没有提交)。

  如果一个事务被提交了(commit),则不可以回退(rollback)。

  可以选择回退到哪个保存点。

  InnoDB 支持事务, MyISAM 不支持事务。

  开始事务可以使 start transaction 或者 begin。

          

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

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

相关文章

【C++】模板(相关知识点讲解 + STL底层涉及的模板应用)

目录 模板是什么? 模板格式 模板本质 函数模板 格式介绍 显式实例化 模板参数匹配原则 类模板 类模板的实例化 非类型模板参数 模板特化——概念 函数模板特化 类模板的特化 全特化 半特化 偏特化 三种类特化例子(放一起比较)…

在 CentOS 7 上安装 Redmine 的详细步骤及 20 个经典用法

目录 1. 引言 2. 安装步骤 2.1 更新系统 2.2 安装依赖包 2.3 安装 MariaDB 数据库 2.4 配置 MariaDB 2.5 安装 Ruby 2.6 安装 Redmine 2.7 配置 Redmine 2.8 安装 Bundler 和必要的 Gems 2.9 生成密钥并迁移数据库 2.10 配置 Apache 2.11 启动 Apache 并设置开机自…

1712系列 嵌入式电源系统

1712系列 嵌入式电源系统 2/3/4/5G&共享站点快速部署 简述 1712A 300A嵌入式电源系统采用模块化设计、组合式结构,由控制器、整流模块、交流配电单元、直流配电单元等组成。该系统将交流电转换成稳定的-48V直流电,用于铁塔、移动、电信、联通等公司…

修改nacos实力权重或者对某实例下线报错

在Nacos控制台进行上述操作,错误信息 caused: errCode: 500, errMsg: do metadata operation failed ;caused: com.alibaba.nacos.consistency.exception.ConsistencyException: The Raft Group [naming_instance_metadata] did not find the Leader node;caused:…

sql注入大总结【万字详解】

文章目录 数据库的架构sql注入概念正常语句正常回显页面在页面中使用sql语句 跨库查询sql文件读写影响条件复现读写的路径的问题 sql注入请求分类sql注入请求类型sql注入请求方式:sql注入数据请求格式 数据库的增删改查数据库查询数据库添加数据库删除数据库修改 盲…

【python函数】读文件(返回str数据)

大家好,我是一名_全栈_测试开发工程师,已经开源一套【自动化测试框架】和【测试管理平台】,欢迎大家关注我,和我一起【分享测试知识,交流测试技术,趣聊行业热点】。 一、函数说明: 使用的函数&a…

STM32IIC与SPI详解

单片机里的通信协议其实蛮多的,IIC;SPI;MQTT;CAN;包括串口也是一种通信协议。而串口通信虽然实现了全双工,但需要至少三根线,为了节省这一根线的成本,于是IIC诞生了。 目录 一.IIC…

【产业前沿】树莓集团如何以数字媒体产业园为引擎,加速产业升级?

在数字化转型的浪潮中,树莓集团以敏锐的洞察力和前瞻性的战略眼光,将数字媒体产业园打造成为产业升级的强劲引擎。这一创新举措不仅为传统行业插上了数字的翅膀,更为整个产业链注入了新的活力与可能。 树莓集团深知,数字媒体产业园…

【人工智能】AI最终会取代程序员吗?

1. 前言 到 2030 年,40% 的编程任务将实现自动化。这个令人难以置信的统计数据凸显了人工智能在软件工程中日益增长的影响力,并引发了一个问题:人工智能会彻底接管软件工程吗? 人工智能技术正在蓬勃发展,有望实现大量…

【实战】Spring Security Oauth2自定义授权模式接入手机验证

文章目录 前言技术积累Oauth2简介Oauth2的四种模式授权码模式简化模式密码模式客户端模式自定义模式 实战演示1、mavan依赖引入2、自定义手机用户3、自定义手机用户信息获取服务4、自定义认证令牌5、自定义授权模式6、自定义实际认证提供者7、认证服务配置8、Oauth2配置9、资源…

C语言程序设计-[11] 循环结构嵌套

1、循环结构嵌套形式 上面三种循环语句结构可以相互嵌套,组合非常灵活。循环嵌套需要记住最重要的一点:”外循环执行一次,内循环要完整执行一遍”,要通过实例加深对这一句话的理解。 注1:一个循环结构由四个要素构成&…

Java设计模式-建造者模式-一次性理解透

1. 建造者模式简介 今天我们将研究 Java 中的建造者模式(Builder 模式)。Builder 设计模式是一种创建型设计模式,也被称为生成器模式,类似于工厂模式和抽象工厂模式。 该模式用于创建复杂对象,允许用户创建不同类型的…

【Python】PyWebIO 初体验:用 Python 写网页

目录 前言1 使用方法1.1 安装 Pywebio1.2 输出内容1.3 输入内容 2 示例程序2.1 BMI 计算器2.2 Markdown 编辑器2.3 聊天室2.4 五子棋 前言 前两天正在逛 Github,偶然看到一个很有意思的项目:PyWebIo。 这是一个 Python 第三方库,可以只用 P…

100 Exercises To Learn Rust 挑战!准备篇

公司内部的学习会非常活跃!我也参与了Rust学习会,并且一直在研究rustlings。最近,我发现了一个类似于rustlings的新教程网站:Welcome - 100 Exercises To Learn Rust。 rustlings是基于Rust的权威官方文档《The Rust Programming…

汽车免拆诊断案例 | 2010款劳斯莱斯古斯特车中央信息显示屏提示传动系统故障

故障现象  一辆2010款劳斯莱斯古斯特车,搭载N74发动机,累计行驶里程约为11万km。车主反映,起动发动机后组合仪表和中央信息显示屏均提示传动系统故障。用故障检测仪检测,发现发动机控制模块2(DME2)中存储…

SmartBI拓展包二开入门开发

前言 新接到一个项目拓展包三开的需求,没有相关经验,学习开发,本文尝试通过简单的定位以及指导,确定修改点 SmartBI帮助文档-拓展包开发 登录 http://localhost:18080/smartbi/vision/index.jsp后台配置 上传拓展包&#xff0…

MySQL和Redis的数据一致性

MySQL和Redis的数据一致性 多线程环境下的涉及读写的缓存才会存在MySQL和Redis的数据不一致问题 先删除缓存再更新数据库再延时删除缓存 线程一删除缓存线程一更新数据线程二开始查数据如果第二步线程一更新数据延时,那么线程二会重新从数据库加载数据&#xff0…

超好用的windows系统工具PowerToys

文章目录 Github地址基本介绍使用 Github地址 PowerToys 基本介绍 是windows官方好用的工具箱,包括各种工具 使用 要带上win键 此工具安装后每次运行电脑自启动,桌面没有快捷方式,只能右下角 窗口在上效果演示,会被蓝线框到…

基于GeoTools使用JavaFx进行矢量数据可视化实战

目录 前言 一、JavaFx展示原理说明 二、GeoTools的Maven依赖问题 三、引入Geotools相关的资源包 四、创建JavaFx的Canvas实例 五、JavaFx的Scene和Node的绑定 六、总结 前言 众所周知,JavaFx是Java继Swing之后的又一款用于桌面应用的开发利器。当然&#xff0…

江科大/江协科技 STM32学习笔记P22

文章目录 AD单通道&AD多通道ADC基本结构和ADC有关的库函数AD单通道AD.cmain.c连续转换,非扫描模式的AD.c AD多通道AD.cmain.c AD单通道&AD多通道 ADC基本结构 第一步,开启RCC时钟,包括ADC和GPIO的时钟,ADCCLK的分频器也需…