Redis快速上手篇(三)(事务+Idea的连接和使用)

Redis事务

可以一次执行多个命令,本质是一组命令的集合。一个事务中的 所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞。

单独的隔离的操作

官网说明

https://redis.io/docs/interact/transactions/

MULTI、EXEC、DISCARD、WATCH。这四个指令构成了 redis 事务处理的基础。

        1.MULTI 用来组装一个事务;将命令存放到一个队列里面

        2.EXEC 用来执行一个事务;相当于mysql的//commit

        3.DISCARD 用来取消一个事务;相当于mysql的//rollback

        4.WATCH 用来监视一些 key,一旦这些 key 在事务执行之前被改变,则取消事务的执行。

结束后统一执行

有关事务,经常会遇到的是两类错误:

调用 EXEC 之前的错误 如语法错误,事务不会被执行

调用 EXEC 之后的错误 如重复建,事务不会理睬错误(不会影响接下来的其他命令的执行)

WATCH

“WATCH”可以帮我们实现类似于“乐观锁”的效果,即 CAS(check and set)。

WATCH 本身的作用是“监视 key 是否被改动过”,而且支持同时监视多个 key,只要还没真正触发事务,WATCH 都会尽职尽责的监视,一旦发现某个 key 被修改了,在执行 EXEC 时就会返回 nil,表示事务无法触发。

在 multi 之前 set year 修改了值所以 nil

事务回滚(discard)

事务冲突

比如涉及金钱的操作,导致金额负数

解决方案

悲观锁(Pessimistic Lock)

顾名思义,就是很悲观

每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁

这样别人想拿这个数据就会block直到它拿到锁。

传统的关系型数据库里边就用到了很多这种锁机制,

比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

每次都会上锁影响效率

乐观锁(Optimistic Lock)

顾名思义,就是很乐观

每次去拿数据的时候都认为别人不会修改,所以不会上锁,

但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,

可以使用版本号等机制。乐观锁适用于多读的应用类型

这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的。

redis与idea的连接

ssm

添加redis的依赖

<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.2.0</version>
</dependency>

Jedis jds = new Jedis("IP")

jds.auth("密码")

jds.select(数据库) <!-- 0-15 -->

spring boot

加入redis的依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.6.0</version>
</dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId>
</dependency>

编写配置文件

#设置reis的索引
spring.redis.database=15
#设置连接redis的密码
spring.redis.password=yyl
#设置的redis的服务器
spring.redis.host=192.168.159.34
#端口号
spring.redis.port=6379
#连接超时时间(毫秒)
spring.redis.timeout=1800000
#连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.max-active=20
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=5
#连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=0

设置配置类

package com.example.demo;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {/*** 连接池的设置** @return*/@Beanpublic JedisPoolConfig getJedisPoolConfig() {JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();return jedisPoolConfig;}/*** RedisTemplate* @param factory* @return*/@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();RedisSerializer<String> redisSerializer = new StringRedisSerializer();Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om = new ObjectMapper();// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和publicom.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);template.setConnectionFactory(factory);//key序列化方式template.setKeySerializer(redisSerializer);//value序列化template.setValueSerializer(jackson2JsonRedisSerializer);//value hashmap序列化template.setHashValueSerializer(jackson2JsonRedisSerializer);return template;}/*** 缓存处理* @param factory* @return*/@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {RedisSerializer<String> redisSerializer = new StringRedisSerializer();Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(600)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)).disableCachingNullValues();RedisCacheManager cacheManager = RedisCacheManager.builder(factory).cacheDefaults(config).build();return cacheManager;}
}

编写测试代码

spring-data-redis针对jedis提供了如下功能:

1. 连接池自动管理,提供了一个高度封装的“RedisTemplate”类

2. RedisTemplate 对五种数据结构分别定义了操作

操作字符串

redisTemplate.opsForValue();

操作hash

redisTemplate.opsForHash();

操作list

redisTemplate.opsForList();

操作set

redisTemplate.opsForSet();

操作有序set

redisTemplate.opsForZSet();

String类型与List类型

Set类型
添加元素
redisTemplate.opsForSet().add(key, values)
移除元素(单个值、多个值)
redisTemplate.opsForSet().remove(key, values)删除并且返回一个随机的元素redisTemplate.opsForSet().pop(key)获取集合的大小redisTemplate.opsForSet().size(key)判断集合是否包含value
redisTemplate.opsForSet().isMember(key, value)获取两个集合的交集(key对应的无序集合与otherKey对应的无序集合求交集)
redisTemplate.opsForSet().intersect(key, otherKey)获取多个集合的交集(Collection var2)redisTemplate.opsForSet().intersect(key, otherKeys)key集合与otherKey集合的交集存储到destKey集合中(其中otherKey可以为单个值或者集合)redisTemplate.opsForSet().intersectAndStore(key, otherKey, destKey)key集合与多个集合的交集存储到destKey无序集合中redisTemplate.opsForSet().intersectAndStore(key, otherKeys, destKey)获取两个或者多个集合的并集(otherKeys可以为单个值或者是集合)redisTemplate.opsForSet().union(key, otherKeys)key集合与otherKey集合的并集存储到destKey中(otherKeys可以为单个值或者是集合)redisTemplate.opsForSet().unionAndStore(key, otherKey, destKey)获取两个或者多个集合的差集(otherKeys可以为单个值或者是集合)redisTemplate.opsForSet().difference(key, otherKeys)差集存储到destKey中(otherKeys可以为单个值或者集合)redisTemplate.opsForSet().differenceAndStore(key, otherKey, destKey)随机获取集合中的一个元素redisTemplate.opsForSet().randomMember(key)获取集合中的所有元素redisTemplate.opsForSet().members(key)随机获取集合中count个元素redisTemplate.opsForSet().randomMembers(key, count)获取多个key无序集合中的元素(去重),count表示个数redisTemplate.opsForSet().distinctRandomMembers(key, count)遍历set类似于Interator(ScanOptions.NONE为显示所有的)redisTemplate.opsForSet().scan(key, options)
Hash类型
Long delete(H key, Object... hashKeys);
删除给定的哈希hashKeysSystem.out.println(template.opsForHash().delete("redisHash","name"));System.out.println(template.opsForHash().entries("redisHash"));1{class=6, age=28.1}Boolean hasKey(H key, Object hashKey);
确定哈希hashKey是否存在System.out.println(template.opsForHash().hasKey("redisHash","666"));System.out.println(template.opsForHash().hasKey("redisHash","777"));truefalseHV get(H key, Object hashKey);
从键中的哈希获取给定hashKey的值System.out.println(template.opsForHash().get("redisHash","age"));26Set<HK> keys(H key);
获取key所对应的散列表的keySystem.out.println(template.opsForHash().keys("redisHash"));//redisHash所对应的散列表为{class=1, name=666, age=27}[name, class, age]Long size(H key);
获取key所对应的散列表的大小个数System.out.println(template.opsForHash().size("redisHash"));//redisHash所对应的散列表为{class=1, name=666, age=27}3void putAll(H key, Map<? extends HK, ? extends HV> m);
使用m中提供的多个散列字段设置到key对应的散列表中Map<String,Object> testMap = new HashMap();testMap.put("name","666");testMap.put("age",27);testMap.put("class","1");template.opsForHash().putAll("redisHash1",testMap);System.out.println(template.opsForHash().entries("redisHash1"));{class=1, name=jack, age=27}void put(H key, HK hashKey, HV value);
设置散列hashKey的值template.opsForHash().put("redisHash","name","666");template.opsForHash().put("redisHash","age",26);template.opsForHash().put("redisHash","class","6");System.out.println(template.opsForHash().entries("redisHash"));{age=26, class=6, name=666}List<HV> values(H key);
获取整个哈希存储的值根据密钥System.out.println(template.opsForHash().values("redisHash"));[tom, 26, 6]Map<HK, HV> entries(H key);
获取整个哈希存储根据密钥System.out.println(template.opsForHash().entries("redisHash"));{age=26, class=6, name=tom}Cursor<Map.Entry<HK, HV>> scan(H key, ScanOptions options);
使用Cursor在key的hash中迭代,相当于迭代器。Cursor<Map.Entry<Object, Object>> curosr = template.opsForHash().scan("redisHash", ScanOptions.ScanOptions.NONE);while(curosr.hasNext()){Map.Entry<Object, Object> entry = curosr.next();System.out.println(entry.getKey()+":"+entry.getValue());}age:27class:6name:666

命令

操作

返回值

hash.delete(H key, Object... hashKeys)

删除,可以传入多个map的key【hdel】

Long

hash.hasKey(key, hashKey)

查看hash中的某个hashKey是否存在【hexists】

Boolean

hash.get(key, hashKey)

获取值【hget】

Object(HV 泛型约束对象)

hash.multiGet(H key, Collection<HK> hashKeys)

批量获取集合中的key对应的值【hmget】

List<HV>

hash.increment(H key, HK hashKey, long delta)

对值进行+(delta值)操作【】

Long

hash.increment(H key, HK hashKey, double delta)

~

double

hash.keys(key)

返回map内hashKey的集合【hkeys】

Set<HK>

hash.lengthOfValue(H key, HK hashKey)

返回查询键关联的值的长度,为null则返回0【hstrlen】

Long

hash.size(H key)

获取hashKey的个数【hlen】

Long

hash.putAll(H key, Map<? extends HK, ? extends HV> m)

相当于map的putAll【hmset】

void

hash.put(H key, HK hashKey, HV value)

设置值,添加hashKey-value,hashKay相当于map的key 【hset】

void

hash.putIfAbsent(H key, HK hashKey, HV value)

仅当hashKey不存在时设置值

Boolean

hash.values(key)

返回value的集合【hvals】

List<HV>

hase.entries(H key)

获取map【hgetall】

Map<HK, HV>

hash.scan(H key, ScanOptions options)

基于游标的迭代查询【hscan】

Cursor<Map.Entry<HK, HV>>(返回的Cursor要手动关闭,见下面示例2)

hash.getOperations()

返回RedisOperation,它就是redis操作的接口

RedisOperations<H, ?>

ZSet类型
Boolean add(K key, V value, double score);
新增一个有序集合,存在的话为false,不存在的话为trueSystem.out.println(template.opsForZSet().add("zset1","zset-1",1.0));trueLong add(K key, Set<TypedTuple<V>> tuples);
新增一个有序集合ZSetOperations.TypedTuple<Object> objectTypedTuple1 = new DefaultTypedTuple<>("zset-5",9.6);ZSetOperations.TypedTuple<Object> objectTypedTuple2 = new DefaultTypedTuple<>("zset-6",9.9);Set<ZSetOperations.TypedTuple<Object>> tuples = new HashSet<ZSetOperations.TypedTuple<Object>>();tuples.add(objectTypedTuple1);tuples.add(objectTypedTuple2);System.out.println(template.opsForZSet().add("zset1",tuples));System.out.println(template.opsForZSet().range("zset1",0,-1));[zset-1, zset-2, zset-3, zset-4, zset-5, zset-6]
Long remove(K key, Object... values);
从有序集合中移除一个或者多个元素System.out.println(template.opsForZSet().range("zset1",0,-1));System.out.println(template.opsForZSet().remove("zset1","zset-6"));System.out.println(template.opsForZSet().range("zset1",0,-1));[zset-1, zset-2, zset-3, zset-4, zset-5, zset-6]1[zset-1, zset-2, zset-3, zset-4, zset-5]Long rank(K key, Object o);
返回有序集中指定成员的排名,其中有序集成员按分数值递增(从小到大)顺序排列System.out.println(template.opsForZSet().range("zset1",0,-1));System.out.println(template.opsForZSet().rank("zset1","zset-2"));[zset-2, zset-1, zset-3, zset-4, zset-5]0   //表明排名第一Set<V> range(K key, long start, long end);
通过索引区间返回有序集合成指定区间内的成员,其中有序集成员按分数值递增(从小到大)顺序排列System.out.println(template.opsForZSet().range("zset1",0,-1));[zset-2, zset-1, zset-3, zset-4, zset-5]
Long count(K key, double min, double max);
通过分数返回有序集合指定区间内的成员个数System.out.println(template.opsForZSet().rangeByScore("zset1",0,5));System.out.println(template.opsForZSet().count("zset1",0,5));[zset-2, zset-1, zset-3]3Long size(K key);
获取有序集合的成员数,内部调用的就是zCard方法System.out.println(template.opsForZSet().size("zset1"));6Double score(K key, Object o);
获取指定成员的score值System.out.println(template.opsForZSet().score("zset1","zset-1"));2.2Long removeRange(K key, long start, long end);
移除指定索引位置的成员,其中有序集成员按分数值递增(从小到大)顺序排列System.out.println(template.opsForZSet().range("zset2",0,-1));System.out.println(template.opsForZSet().removeRange("zset2",1,2));System.out.println(template.opsForZSet().range("zset2",0,-1));[zset-1, zset-2, zset-3, zset-4]2[zset-1, zset-4]Cursor<TypedTuple<V>> scan(K key, ScanOptions options);
遍历zsetCursor<ZSetOperations.TypedTuple<Object>> cursor = template.opsForZSet().scan("zzset1", ScanOptions.NONE);while (cursor.hasNext()){ZSetOperations.TypedTuple<Object> item = cursor.next();System.out.println(item.getValue() + ":" + item.getScore());}zset-1:1.0zset-2:2.0zset-3:3.0zset-4:6.0

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

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

相关文章

Python机器学习17——Xgboost和Lightgbm结合分位数回归(机器学习与传统统计学结合)

最近XGboost支持分位数回归了&#xff0c;我看了一下&#xff0c;就做了个小的代码案例。毕竟学术市场上做这种新颖的机器学习和传统统计学结合的方法还是不多&#xff0c;算的上创新&#xff0c;找个好数据集可以发论文。 代码实现 导入包 import numpy as np import pandas…

【转载】双亲委派模型

双亲委派模型是 Java 类加载器的一种工作模式&#xff0c;通过这种工作模式&#xff0c;Java 虚拟机将类文件加载到内存中&#xff0c;这样就保证了 Java 程序能够正常的运行起来。那么双亲委派模型究竟说的是啥呢&#xff1f;接下来我们一起来看。 1.类加载器 双亲委派模型针…

HighCharts点击无响应问题

HighCharts 点击无响应问题 背景介绍 项目需要展示一个小时内日志设备的状态&#xff0c;由于数据量比较大&#xff0c;使用echarts效果不好。于是采用highcharts来处理显示。highcharts使用起来很方便&#xff0c;还有打印照片功能&#xff0c;相当满意。这里采用官网给的例…

产研团队必看!3款在线白板工具助你轻松改善工作!

随着科技的不断进步和团队协作的需求日益增加&#xff0c;产研团队在工作中常常面临各种挑战。例如&#xff0c;团队成员之间的沟通不畅、信息共享不便以及项目进度不明确等等。这些问题会导致团队的效率低下&#xff0c;影响整体工作质量。 为了解决这些问题&#xff0c;越来…

ExoPlayer架构详解与源码分析(7)——SampleQueue

系列文章目录 ExoPlayer架构详解与源码分析&#xff08;1&#xff09;——前言 ExoPlayer架构详解与源码分析&#xff08;2&#xff09;——Player ExoPlayer架构详解与源码分析&#xff08;3&#xff09;——Timeline ExoPlayer架构详解与源码分析&#xff08;4&#xff09;—…

可自由搭建的能源管理平台,轻松实现高效节能

随着科技的不断发展&#xff0c;能源问题越来越重要。为了提高能源的利用效率&#xff0c;减少能源浪费&#xff0c;能源用能企业纷纷开始注重能源管理工作&#xff0c;并想要一款可以进行高效管理的工具。智慧能源管理平台&#xff0c;是一款可自由搭建的能源管理平台&#xf…

app分发的一些流程2

应用分发的流程通常包括以下步骤&#xff1a; 开发应用程序&#xff1a;首先&#xff0c;您需要开发您的应用程序。这包括编写代码、设计用户界面、测试应用程序等等。确保您的应用程序符合各个应用商店的规范和要求&#xff0c;以确保顺利通过审核。 准备应用材料&#xff1…

九方面解读国家数据局成立,可交易数据的五大特性探讨

​ 10月25日&#xff0c;国家数据局正式揭牌&#xff0c;标志着我国数据管理进入了新的阶段。国家数据局负责协调推进数据基础制度建设&#xff0c;统筹数据资源整合共享和开发利用&#xff0c;统筹推进数字中国、数字经济、数字社会规划和建设等&#xff0c;由国家发展和改革…

SENet 学习

ILSVRC 是一个比赛&#xff0c;全称是ImageNet Large-Scale Visual Recognition Challenge&#xff0c;平常说的ImageNet比赛指的是这个比赛。 使用的数据集是ImageNet数据集的一个子集&#xff0c;一般说的ImageNet&#xff08;数据集&#xff09;实际上指的是ImageNet的这个子…

容器类之QT

容器类之QT 顺序容器 关联容器 STL迭代容器 STL风格的反向迭代容器 QVariant类 QFlags类 QRandomGenerator类

金属纳米颗粒通过水基剥离方案使用嵌段共聚物模板

引言 随着纳米结构表面和界面在广泛的科学和技术应用中变得越来越重要&#xff0c;确定可扩展和廉价的方法来实现这些变成了一个关键的挑战。特别是有序、非密集、表面支撑的金属纳米颗粒的大面积阵列的制造&#xff0c;由于其在不同领域如等离子体增强薄膜太阳能电池中的应用…

【电路笔记】-波特图(Bode Diagrams)

波特图(Bode Diagrams) 文章目录 波特图(Bode Diagrams)1、概述2、定义3、波特图的呈现4、常见的波特图4.1 一阶滤波器4.2 二阶滤波器 5、总结 1、概述 上世纪30年代末&#xff0c;一位名叫 Hendrick Wade Bode 的美国工程师设计了一个著名的表示法来研究频域中的交流电路。 这…

论文-分布式-并发控制-Lamport逻辑时钟

目录 前言 逻辑时钟讲解 算法类比为面包店内取号 Lamport算法的时间戳原理 Lamport算法的5个原则 举例说明 算法实现 参考文献 前言 在并发系统中&#xff0c;同步与互斥是实现资源共享的关键Lamport面包店算法作为一种经典的解决并发问题的算法&#xff0c;它的实现原…

docker部署rabbitmq的坑

背景 今天用docker部署rabbitmq&#xff0c;启动都一起正常&#xff0c;但是当访问15672端口时&#xff0c;不能加载出页面。 排查 1.防火墙是否开启 ufw status2.ip是否能ping通 ping 192.168.x.x3.检查docker日志 docker psdocker logs -f 容器id4.进入容器&#xff0c…

Vue3项目创建+组合式API使用+组件通信+渲染微博热搜+打包上线

摘要 Vue3的组合式API大大减少了代码量&#xff0c;以及使用也方便了很多&#xff0c;本案例使用Vite创建一个Vue3示例&#xff0c;简单介绍Vue3的组合式API使用以及父传子组件传参示例。 创建Vue3项目 1、首先要安装 Node.js 下载地址&#xff1a;https://nodejs.org/en/do…

Windows安装virtualenv虚拟环境

需要先安装好python环境 1 创建虚拟环境目录 还是在D:\Program\ 的文件夹新建 .env 目录&#xff08;你也可以不叫这个名字&#xff0c;一般命名为 .env 或者 .virtualenv &#xff0c;你也可以在其他目录中创建&#xff09; 2 配置虚拟环境目录的环境变量 3 安装虚拟环境 进…

如何集成验证码短信API到你的应用程序

引言 当你需要为你的应用程序增加安全性和用户验证功能时&#xff0c;集成验证码短信API是一个明智的选择。验证码短信API可以帮助你轻松实现用户验证、密码重置和账户恢复等功能&#xff0c;提高用户体验并增强应用程序的安全性。本文将介绍如何将验证码短信API集成到你的应用…

AutoCAD 2024 Mac中文附激活补丁 兼容M1.M2电脑

AutoCAD 2024是一款功能强大的CAD设计绘图工具&#xff0c;旨在帮助用户创建和编辑高质量的设计图纸和模型。该软件支持2D和3D设计&#xff0c;具有丰富的功能和工具&#xff0c;可用于绘图、建模、注释、标注、尺寸设置等多种操作。AutoCAD 2024还引入了智能对象捕捉、实时预览…

【AGC】.p12证书文件如何获取MD5

近期在使用DevEco Studio3.1打包应用时遇到了一个问题&#xff0c;我使用Build—Generate Key and CSR创建了密钥库文件。 我这里需要获取到创建的.p12证书文件的MD5值&#xff0c;于是在控制台使用了keytool -list -v -keystore D:\myapp.p12命令获取证书指纹&#xff0c;但是…

【51单片机】:智能施工电梯系统

项目效果&#xff1a; 基于51单片机的智能施工电梯系统 摘 要 智能施工电梯系统目前广泛应用于人们建筑工程中&#xff0c;为人们施工时上下搬运提供了极大的便利。智能施工电梯系统包括密码开启、超重提示&#xff0c;电梯运作及相关信息显示等等功能&#xff0c;施工电梯为我…