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

Mybatis使用详解

简介

MyBatis是一款优秀的持久层框架,它支持普通SQL查询,存储过程和高级映射。MyBatis通过简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plain Ordinary Java Object,普通的Java对象)映射成数据库中的记录。MyBatis可以自动注册驱动、建立连接、获取SQL执行对象、释放连接等操作,开发人员只需要关注SQL语句的编写即可,无需过多关注数据库连接问题。

MyBatis的优势在于它通过参数映射方式,将参数灵活地配置在SQL语句中的配置文件中,避免了在Java类中配置参数。此外,MyBatis通过输出映射机制,将结果集的检索自动映射成相应的Java对象,避免了手工检索结果集。MyBatis还支持动态SQL,可以通过条件判断进行查询实现SQL复用。

主要特点

MyBatis的主要特点包括:

  1. 简单易用:MyBatis的API非常简单,易于学习和上手。
  2. 灵活性强:MyBatis允许开发人员自定义SQL语句,满足各种复杂的查询和数据操作需求。
  3. 映射关系自由:MyBatis不强制要求实体类和数据库表之间的映射关系,开发人员可以灵活选择使用注解或XML配置文件来管理映射关系。
  4. 与Spring等框架整合方便:MyBatis提供了与Spring、Spring Boot等框架整合的支持,可以轻松地将MyBatis与这些框架无缝集成。
  5. 易于扩展:MyBatis插件机制可以让开发者增加自定义的功能,扩展性非常强。
  6. 轻量级:MyBatis自身不依赖其他任何JAR,但需要提供JDBC实现。
  7. 学习成本低:相比ORM框架而言,掌握MyBatis的使用是很轻松的。
  8. SQL代码从程序代码中彻底分离出来,可重用:提供XML标签,支持编写动态SQL,提供映射标签,支持对象与数据库的ORM字段关系映射。

然而,MyBatis也有一些缺点,如SQL语句编写工作量大,熟练度要高;数据库移植性差,比如从MySQL移植到Oracle,SQL语句会有差异从而引起错误。

应用场景

MyBatis主要适用于以下应用场景:

  1. 对性能要求高的场景:例如互联网项目,MyBatis可以提供灵活的SQL映射和优化,满足高性能的需求。
  2. 需求变化较多的项目:MyBatis允许开发人员自定义SQL语句,可以根据需求灵活修改和优化SQL语句,适用于需求变化较多的项目。
  3. 数据库操作复杂的场景:MyBatis支持自定义SQL、存储过程以及高级映射,可以处理复杂的数据库操作和数据映射。
  4. 需要减少JDBC代码量的场景:MyBatis可以自动注册驱动、建立连接、获取SQL执行对象、释放连接等操作,减少了大量的JDBC代码,简化了数据库操作。

总的来说,MyBatis适用于各种基于Java的持久层应用,特别是需要高效、灵活地进行数据库操作的应用场景。

Mybatis的原理

MyBatis的工作原理主要包括以下几个步骤:

  1. 读取MyBatis配置文件:MyBatis的配置文件为mybatis-config.xml,其中包含了MyBatis的全局配置信息,如数据库连接信息等。
  2. 加载映射文件:mybatis-config.xml配置文件中可以加载多个映射文件,每个映射文件对应数据库中的一张表。
  3. 构造会话工厂:通过MyBatis的环境等配置信息,可以构建一个会话工厂SqlSessionFactory。
  4. 创建会话对象:由会话工厂创建SqlSession对象,该对象中包含了执行SQL语句的所有方法。
  5. Executor执行器:MyBatis底层定义了一个Executor接口来操作数据库,它将根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。

在输入参数映射过程中,MyBatis将参数映射到SQL语句中,类似于JDBC对preparedStatement对象设置参数的过程。在输出结果映射过程中,MyBatis将查询结果映射到Java对象,类似于JDBC对结果集的解析过程。

SpringBoot集成Mybatis

将MyBatis与Spring Boot集成是一种常见的做法,它可以让你的应用程序更加易于管理、可维护性和高效。以下是集成MyBatis与Spring Boot的步骤:

  1. 添加依赖:在Spring Boot项目的pom.xml文件中,添加MyBatis和MyBatis-Spring的依赖。
<dependencies><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.0</version></dependency>
</dependencies>
  1. 配置数据源:在Spring Boot的application.properties或application.yml文件中,配置数据库连接信息。
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=rootpassword
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
  1. 创建实体类:根据数据库表结构,创建对应的Java实体类。
  2. 创建Mapper接口:为每个实体类创建一个Mapper接口,并使用@Mapper注解进行标注。
  3. 创建Mapper XML文件:在resources/mapper目录下,为每个Mapper接口创建一个对应的XML文件,并在其中编写对应的SQL语句。
  4. 创建Service类:创建一个Service类,注入Mapper接口,并实现业务逻辑。
  5. 创建Controller类:创建一个Controller类,处理前端请求,调用Service类的方法,并返回结果。
  6. 配置MyBatis扫描路径:在application配置类上添加@MapperScan注解,指定MyBatis的扫描路径。
@SpringBootApplication
@MapperScan("com.example.demo.mapper")
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}

通过以上步骤,你就可以将MyBatis与Spring Boot成功集成。在实际开发中,你可以根据需要进一步优化和扩展集成方案,例如使用注解配置SQL语句、使用MyBatis Plus简化开发等。

Mybatis的架构设计

MyBatis的架构设计主要包括以下几个层次:

  1. 接口层:这是MyBatis与数据库交互的方式。可以使用传统的MyBatis提供的API,通过创建SqlSession对象实现。此外,还可以使用Mapper接口,其中声明的方法和跟节点中的<select|update|delete|insert>节点项对应。
  2. 核心处理层:这一层主要负责处理MyBatis的核心逻辑,包括配置解析、参数映射、SQL解析、SQL执行、结果集映射、插件等。
  3. 基础支持层:这一层为MyBatis提供了基础支持,包括数据源模块、事务管理模块、缓存模块、Binding模块、反射模块、类型转换、日志模块、资源加载和解析器模块等。

此外,MyBatis的插件机制允许开发者通过继承Interceptor接口自定义拦截器,对SQL语句执行过程中的某一点进行拦截。MyBatis还采用了责任链模式,使得插件的开发和使用更加灵活。

MyBatis的架构设计使其易于使用和扩展,同时还能提供高效的数据库操作。

Mybatis的核心处理层

MyBatis的核心处理层是负责处理接口层传进来的指令,并将这些指令转换成SQL语句,然后执行相关SQL,并对结果集进行封装映射。这一层的主要任务包括SQL执行与结果集映射,由Executor负责维护缓存和事务管理,并将数据库操作委托给StatementHandler。

核心处理层的两个关键类是Configuration和Executor。Configuration持有了Mybatis运行期间所有的数据,包括SQL模板,结果集映射数据等。Executor负责维护缓存和事务管理,并将数据库操作委托给StatementHandler。

核心处理层的StatementHandler接口是MyBatis的核心接口之一,它完成了MyBatis中最核心的工作,也就是如何去与使用原生JDBC数据库进行交互。StatementHandler的功能包括创建对应的Statement对象,为SQL绑定实参,执行各种SQL语句,批量执行SQL语句,将结果集映射到结果对象等。

核心处理层还包括一些其他组件,如ParameterHandler负责完成SQL语句的实参绑定,ResultSetHandler负责处理结果集的映射等。这些组件协同工作,共同完成了MyBatis的核心处理任务。

MyBatis的核心处理层包括以下几个关键类:

  1. SqlSessionFactoryBuilder:每个MyBatis应用程序的入口。通过XML配置文件创建Configuration对象,然后通过build方法创建SqlSessionFactory对象。
  2. SqlSessionFactory:用于创建SqlSession的工厂。SqlSession是MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能。
  3. SqlSession:执行增删改查操作,管理事务。
  4. Executor:MyBatis执行器,是MyBatis调度的核心,负责SQL语句的生成和查询缓存的维护。
  5. StatementHandler:封装了JDBC Statement操作,负责对JDBC Statement的操作,如设置参数、将Statement结果集转换成List集合。
  6. ResultSetHandler:处理查询结果。

Mybatis的常用插件

MyBatis提供了多种常用的插件,以扩展其功能和性能。以下是一些常用的MyBatis插件:

  1. 全局通用操作插件:支持全局通用方法注入,如Write once, use anywhere,方便开发者在多个地方复用相同的代码。
  2. 分页插件:基于Mybatis物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于写基本List查询。
  3. 性能分析插件:可输出Sql语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询问题。
  4. 全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作。
  5. 代码生成插件:mybatis-generator可以针对数据库表自动生成MyBatis执行所需要的代码(如Mapper.java、Mapper.xml、POJO)。

这些插件可以帮助开发者提高开发效率、优化数据库查询性能、增强代码安全性等。在实际开发中,可以根据需要选择合适的插件,以提升MyBatis的应用效果。

Mybatis插件原理

MyBatis的插件原理是基于JDK的动态代理和责任链模式实现的。

MyBatis允许使用插件来拦截四个核心对象:Executor、StatementHandler、ParameterHandler和ResultSetHandler。这四个对象在MyBatis的底层源码中被创建时,都会调用interceptor.plugin方法,这就是插件的切入点。

MyBatis的插件机制采用了JDK的动态代理,当这些对象被创建时,MyBatis会为他们生成代理对象。这些代理对象会增强原始对象的方法,实现在方法执行前后进行拦截的功能。这种机制类似于AOP(切面编程),可以在不修改原始代码的情况下,对方法的执行进行增强。

当代理对象的方法被调用时,会先执行插件的拦截逻辑,然后再执行原始对象的方法。插件的拦截逻辑可以根据需要进行定制,比如添加日志、性能监控、事务管理等。

总的来说,MyBatis的插件机制提供了一种灵活的方式来扩展和定制MyBatis的功能,使得开发者可以更加方便地使用MyBatis进行数据库操作。

相关文章:

Mybatis使用详解

简介 MyBatis是一款优秀的持久层框架&#xff0c;它支持普通SQL查询&#xff0c;存储过程和高级映射。MyBatis通过简单的XML或注解用于配置和原始映射&#xff0c;将接口和Java的POJOs&#xff08;Plain Ordinary Java Object&#xff0c;普通的Java对象&#xff09;映射成数据…...

云原生周刊:Karmada 成为 CNCF 孵化项目 | 2023.12.25

开源项目推荐 kubernetes-reflector Reflector 是一个 Kubernetes 的插件&#xff0c;旨在监视资源&#xff08;secrets 和 configmaps&#xff09;的变化&#xff0c;并将这些变化反映到同一命名空间或其他命名空间中的镜像资源中。 Lingo Lingo 是适用于 K8s 的 OpenAI 兼…...

【开源】基于JAVA的学校热点新闻推送系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 新闻类型模块2.2 新闻档案模块2.3 新闻留言模块2.4 新闻评论模块2.5 新闻收藏模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 新闻类型表3.2.2 新闻表3.2.3 新闻留言表3.2.4 新闻评论表3.2.5 新闻收藏表 四、系统展…...

Java基于TCP网络编程的群聊功能

服务端 import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List;public class Server2 {public static List<Socket> onlineList new ArrayList<>();public static void main(String[] args) throws Except…...

CentOS+ISCSI

九、配置iSCSI 添加1块大小为10G的虚拟硬盘; 安装iSCSI服务端targetcli; 使用新增加的硬盘创建卷组,名称为iscsivg,再创建iSCSI共享逻辑卷,逻辑 卷名称为iscsistore,大小为5G; 使用上述逻辑卷创建后端存储,名称为serverc.iscsistore; 定义iSCSI的IQN为iqn.2022-…...

RHCE9学习指南 第11章 网络配置

11.1 网络基础知识 一台主机需要配置必要的网络信息&#xff0c;才可以连接到互联网。需要的配置网络信息包括IP&#xff0c;子网掩码&#xff0c;网关和DNS。 11.1.1 IP地址 在计算机中对IP的标记使用的是32bit的二进制&#xff0c;例如&#xff0c; 11000000 10101000 00…...

Qt如何在控制台项目中使用opencv打开视频

Qt如何在控制台项目中使用opencv打开视频&#xff1f; 重要代码&#xff1a; 1、在pro文件中这样设置&#xff1a; QT - gui QT core widgets serialport 2、不要继承和使用&#xff1a;QCoreApplication #include pro文件&#xff1a; cpp QT - gui QT core widgets seria…...

Node.js 默认包管理器 npm 详解

目录 npm 概念 npm 命令 npm init npm install npm update npm uninstall npm search npm run other npm 安装 yarn npm 安装 yarn 和 npm 安装项目依赖 websocket 本质区别 npm 概念 npm&#xff08;Node Package Manager&#xff09;是一个用于管理 JavaScript 包…...

vue利用深拷贝解决修改不能取消的问题

vue利用深拷贝解决修改不能取消的问题 在对某数据进行修改时考虑还需要进行“确认”、“取消”操作&#xff0c;那么在取消时就需要返回保留的数据内容&#xff0c;那么如何将原有数据保留一份则是关键性问题。 显然修改值不能直接进行原值的赋值操作&#xff0c;因为这样无法取…...

MATLAB - 使用 YOLO 和基于 PCA 的目标检测,对 UR5e 的半结构化智能垃圾箱拣选进行 Gazebo 仿真

系列文章目录 前言 本示例展示了在 Gazebo 中使用 Universal Robots UR5e cobot 模拟智能垃圾桶拣选的详细工作流程。本示例提供的 MATLAB 项目包括初始化、数据生成、感知、运动规划和积分器模块&#xff08;项目文件夹&#xff09;&#xff0c;可创建完整的垃圾桶拣选工作流…...

个性化定制的知识付费小程序,为用户提供个性化的知识服务,知识付费saas租户平台

明理信息科技知识付费saas租户平台 在当今数字化时代&#xff0c;知识付费已经成为一种趋势&#xff0c;越来越多的人愿意为有价值的知识付费。然而&#xff0c;公共知识付费平台虽然内容丰富&#xff0c;但难以满足个人或企业个性化的需求和品牌打造。同时&#xff0c;开发和…...

基于flask和echarts的新冠疫情实时监控系统源码+数据库,后端基于python的flask框架,前端主要是echarts

介绍 基于flask和echarts的新冠疫情实时监控系统 软件架构 后端基于python的flask框架&#xff0c;前端主要是echarts 安装教程 下载到本地&#xff0c;在python相应环境下运行app.py,flask项目部署请自行完成 使用说明 flaskProject文件夹中 app.py是flask项目主运行文…...

总结js中遍历对象属性的方法

方法介绍 1、 forin循环&#xff1a;遍历对象自身的和原型链上的可枚举属性。 2、Object.getOwnPropertySymbols()方法&#xff1a;返回一个数组&#xff0c;包含对象自身的所有Symbol类型的属性。 3、 Object.getOwnPropertyNames()方法&#xff1a;返回一个数组&#xff0…...

编写fastapi接口服务

FastAPI是一个基于 Python 的后端框架&#xff0c;该框架鼓励使用 Pydantic 和 OpenAPI (以前称为 Swagger) 进行文档编制&#xff0c;使用 Docker 进行快速开发和部署以及基于 Starlette 框架进行的简单测试。 step1&#xff1a;安装必要库 pip install fastapi uvicorn st…...

RasaGPT对话系统的工作原理

RasaGPT 结合了 Rasa 和 Langchain 这 2 个开源项目&#xff0c;当超出 Rasa 现有意图(out_of_scope)的时候&#xff0c;就会执行 ActionGPTFallback&#xff0c;本质上就是利用 Langchain 做了一个 RAG&#xff0c;调用 LLM API。RasaGPT 涉及的技术栈比较多而复杂&#xff0c…...

C++设计模式 #7 工厂方法(Factory Method)

“对象创建”模式 通过“对象创建”模式绕开new&#xff0c;来避免对象创建&#xff08;new&#xff09;过程中所导致的紧耦合&#xff08;依赖具体类&#xff09;&#xff0c;从而支持创建的稳定。它是接口抽象之后的第一步工作。 动机 在软件系统中&#xff0c;经常面临着创…...

信息网络协议基础-接入网技术

文章目录 概述***基于ATM架构虚电路PVC和SVC信元格式为什么信元格式由AAL决定?网络架构传统电信网络:点对点链路PPP协议协议内容消息过程多协议封装功能电话网接入Internet(DSL 数字用户线路)主要接入技术ADSL关键技术DMTDSLAM体系结构PPPOE帧格式过程特点局域网定义参考模型L…...

springboot 自动装配原理

在理解springboot自动装配之前需要了解spring的Configuration原理和Conditional两个注解原理。可以看下以前写的这两篇文章 spring 源码阅读之Configuration解析 spring使用Conditional进行条件装配 spring的SPI机制之使用SpringFactoriesLoader加载服务实现 SpringBootApp…...

前端---表格标签

1. 表格的结构 表格是由行和列组成&#xff0c;好比一个excel文件 2. 表格标签 <table>标签&#xff1a;表示一个表格 <tr>标签&#xff1a;表示表格中的一行 <td>标签&#xff1a;表示表格中的列<th>标签&#xff1a;表示表格中的表头 示例代码: &l…...

【软件工程】可执行文件和数据分离

一、概述 可执行文件和数据分离是一种软件设计策略&#xff0c;旨在将程序代码和程序使用的数据分离存储。这种方法通常用于提高软件的模块化程度和灵活性&#xff0c;以及方便软件的管理和维护。 在可执行文件和数据分离中&#xff0c;程序代码通常以可执行文件的形式存储&a…...

Linux dirs命令

Linux dirs命令用于显示目录记录。 显示目录堆叠中的记录。 语法 dirs [/-n -l]参数&#xff1a; n 显示从左边算起第n笔的目录。-n 显示从右边算起第n笔的目录。-l 显示目录完整的记录。 实例 列出"/home/cc/Ruijie"里所有内容的详细信息。可用如下命令。 dir…...

有什么好用的C/C++源代码混淆工具?

​ 有什么好用的C/C源代码混淆工具&#xff1f; 开始使用ipaguard 前言 iOS加固保护是直接针对ios ipa二进制文件的保护技术&#xff0c;可以对iOS APP中的可执行文件进行深度混淆、加密。使用任何工具都无法逆向、破解还原源文件。对APP进行完整性保护&#xff0c;防止应用…...

iOS设备信息详解

文章目录 ID 体系iOS设备信息详解IDFA介绍特点IDFA新政前世今生获取方式 IDFV介绍获取方式 UUID介绍特点获取方式 UDID介绍获取方式 OpenUDID介绍 Bundle ID介绍分类其他 IP地址介绍获取方式 MAC地址介绍获取方式正常获取MAC地址获取对应Wi-Fi的MAC地址 系统版本获取方式 设备型…...

如何使用支付宝沙箱环境支付并公网调用sdk创建支付单服务

文章目录 1.测试环境2.本地配置2. 内网穿透2.1 下载安装cpolar内网穿透2.2 创建隧道3. 测试公网访问4. 配置固定二级子域名4.1 保留一个二级子域名4.2 配置二级子域名5. 使用固定二级子域名进行访问 1.测试环境 MavenSpring bootJdk 1.8 2.本地配置 获取支付宝支付Java SDK,…...

[EFI]Dell Latitude-7400电脑 Hackintosh 黑苹果efi引导文件

硬件型号驱动情况主板 Dell Latitude-7400 处理器Intel Core i7-8665U已驱动内存16GB DDR4 RAM已驱动硬盘Toshiba KIOXIA 512GB SSD已驱动显卡Intel UHD 620 Graphics已驱动声卡Realtek ALC256已驱动有线网卡 无 无无线网卡蓝牙Intel Wireless-AC 9560已驱动 支持系统版本 maco…...

用芯片SIC8833可开发电子秤方案

SIC8833作为一款高性能的电子秤方案芯片&#xff0c;这款芯片是一个带24bitADC的8位RISC MCU&#xff0c;内置8k16位OTP程序存储器。具体24位双向I/O口的特性&#xff0c;广泛应用于电子衡器和精密测量及控制系统&#xff0c;能满足用户的不同需求和应用场景。 以下是电子秤方案…...

【Qt-QFile-QDir】

Qt编程指南 ■ Stream■ QTextStream■ QDataStream ■ QDial■ QDir■ QFile■■ ■ Stream ■ QTextStream /* 获取文件的路径 */ QString fileName QFileDialog::getOpenFileName(this);/* 指向文件 */ file.setFileName(fileName);/* 判断文件是否存在 */ if (!file.exi…...

设计模式之-单列设计模式,5种单例设计模式使用场景以及它们的优缺点

系列文章目录 设计模式之-6大设计原则简单易懂的理解以及它们的适用场景和代码示列 设计模式之-单列设计模式&#xff0c;5种单例设计模式使用场景以及它们的优缺点 设计模式之-3种常见的工厂模式简单工厂模式、工厂方法模式和抽象工厂模式&#xff0c;每一种模式的概念、使用…...

Android 13 - Media框架(25)- OMXNodeInstance(二)

上一节我们了解了 OMXNodeInstance 的创建过程&#xff0c;以及 IOmx 服务和 OMXNodeInstance、OMX组件之间的联系。接下来我们将一起了解 ACodec 是如何通过 OMXNodeInstance 这个中间层进行端口定义设置&#xff0c;以及端口Buffer分配的。 OMXNodeInstance 的代码还是比较长…...

生物系统学中的进化树构建和分析R工具包V.PhyloMaker2的介绍和详细使用

V.PhyloMaker2是一个R语言的工具包&#xff0c;专门用于构建和分析生物系统学中的进化树&#xff08;也称为系统发育树或phylogenetic tree&#xff09;。以下是对V.PhyloMaker2的一些基本介绍和使用说明&#xff1a; 论文介绍&#xff1a;V.PhyloMaker2: An updated and enla…...

网站怎么做定位功能/seo建站是什么意思

目录 一、Assets序列化和反序列化 二、Xml序列化和反序列化 三、二进制形式序列化和反序列化 四、AssetBundle 一、Assets序列化和反序列化 /// <summary> /// 使用如下特性即可在Create->找到CreateAssets菜单&#xff0c;创建一个Assets可格式化的存储文件 ///…...

建设眼镜网站风格/做网站用哪个软件

R包经常会遇到各种版本不兼容的毛病&#xff0c;比如当前的版本相较于包&#xff0c;新了/旧了都是麻烦而升级R软件呢&#xff0c;最麻烦的就是之前安装的包怎么办&#xff1f;搜罗了以下几种方法&#xff1a;方法1&#xff1a;&#xff08;1&#xff09;直接安装新版本&#x…...

岳阳网站建设哪里有/线上营销模式

对Transformer中Positional Encoding的理解1. 什么是Positional Encoding&#xff1f;为什么Transformer需要使用Positional Encoding&#xff1f;Transformer的输入2. Positional Encoding是怎么做的&#xff1f;公式表达源码展示直观理解计算过程参考资料Transformer是最新的…...

做视频网站挣钱吗/新闻10 30字

参考文献&#xff1a;1. 在windows下用python调用DLL&#xff0c;传递复杂结构体2. 在linux下用python调用so&#xff0c;传递复杂结构体本人总结&#xff1a;假设有如下C文件&#xff0c;被编译成so文件#pragma pack(push)#pragma pack(4) // 注意字节对齐方式为4字节&#xf…...

wordpress 开启链接/跨境电商哪个平台比较好

原标题&#xff1a;Java编程-构造方法有哪些特殊性及使用构造方法是一种特殊的方法&#xff0c;它是一个与类同名且没有返回值类型的方法。对象的创建就是通过构造方法来完成&#xff0c;其功能主要是完成对象的初始化。当类实例化一个对象时会自动调用构造方法。构造方法和其他…...

mip网站设计/网页模板怎么用

早晨起床时间&#xff1a;6:30 晚上休息时间&#xff1a;24:29 全天处理事件&#xff1a;1.继续学习BLE蓝牙协议。2.编写52单片机的驱动程序。 处事经验总结&#xff1a;暂无。 人生感悟&#xff1a;暂无。 其它&#xff1a;暂无。...