SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录(第二天)Mybatis的深入学习
SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录(第二天)Mybatis的深入学习(增删改查的操作)
上一篇我们的项目搭建好了,也写了简答的Junit测试类进行测试,可以正确映射到数据库中。
那么这篇文章来深入学习一下以下几个点:
- 了解MyBatis的核心对象SqlSessionFactoryBuilder以及它的作用
- 掌握MyBatis核心配置文件以及元素的使用。
- 掌握MyBatis映射文件及其元素的使用。
一、什么是MyBatis的核心对象?

可以看到红色框住的这部分代码,我们使用了SqlSessionFactoryBuilder().build(reader)来创建MyBatis的SqlSessionFactory的一个实例。
稍微解释一下代码吧(这是一种链式操作,使得代码更为紧凑方便阅读):
SqlSessionFactoryBuilder():这是 MyBatis 框架提供的 SqlSessionFactoryBuilder 类的构造方法,用于创建 SqlSessionFactory 实例的构建器。build(reader):这是 SqlSessionFactoryBuilder 类的build方法,用于**构建 SqlSessionFactory 实例。**该方法需要一个 Reader 参数,该 Reader 包含了 MyBatis 配置文件的内容。通常,配置文件名为mybatis-config.xml。
但是呢,写入数据库的操作是SqlSession对象完成的,所以我们上面创建了SqlSessionFactory的实例就是为了通过其中的build()方法创建出一个SqlSession对象,这样才能进行数据库操作。
//创建SqlSession实例SqlSession session = sqlSessionFactory.openSession();//调用方法,传入参数进行查询\插入\更新\删除等操作PasswordMS passwordMS = session.selectOne("findById",1);//SqlSession中查询单个对象的方法,若是要查询多条则要使用selectList(),方法不同返回值也不同。
//日志输出信息查看返回结果logger.info("姓名:"+passwordMS.getAccount()+",密码:"+passwordMS.getPassword()+",网站:"+passwordMS.getWebsiteName());//关闭sessionsession.close();
因此SqlSessionFactoryBuilder通常被认为是Mybatis的核心对象!(若是上面的代码解释,还是不太懂的话,建议去看看我的其他俩个专栏,先把Java基础和Java高级编程学习这俩专栏学习看完,或者也可以单独看一下Java方法详解这一篇文章,即可理解大概的逻辑思路。)
SqlSessionFactoryBuilder中有多个重载的build()方法

可以看出都是构建出SqlSessionFactory对象, 通过以上代码可知,配置信息可以通过InputStream(字节流)、Reader(字符流)、Configuration(类)三种形式提供给SqlSessionFactoryBuilder的build()方法。
我们是以读取XML文件的方式构造SqlSessionFactory对象
//字符流 读取配置文件
Reader reader = Resources.getResourceAsReader("配置文件位置");
// 根据配置文件构建SqlSessionFactory
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(reader);-----------------------------------------------------------------------------
//字节流 读取配置文件
InputStream inputStream = Resources.getResourceAsStream("配置文件位置");
// 根据配置文件构建SqlSessionFactory
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(inputStream);----------------------------------------------------------------------------
//类方式可以自己去尝试编写一下,开发中常用这种方式
SqlSessionFactory对象是线程安全的,它一旦被创建,在整个应用程序执行期间都会存在。如果我们多次创建同一个数据库的SqlSessionFactory对象,那么该数据库的资源将很容易被耗尽。通常每一个数据库都只创建一个SqlSessionFactory对象,所以在构建SqlSessionFactory对象时,建议使用单例模式。
通过SqlSessionFactory的openSession()方法创建出SqlSession来操作数据库
| 方法名称 | 描述 |
|---|---|
| SqlSession openSession() | 开启一个事务。 |
| SqlSession openSession(Boolean autoCommit) | 参数autoCommit可设置是否开启事务。 |
| SqlSession openSession(Connection connection) | 参数connection可提供自定义连接。 |
| SqlSession openSession(TransactionIsolationLevel level) | 参数level可设置隔离级别。 |
| SqlSession openSession(ExecutorType execType) | 参数execType有三个可选值。 |
| SqlSession openSession(ExecutorType execType,Boolean autoCommit) | 参数execType有三个可选值。 |
| SqlSession openSession(ExecutorType execType, Connection connection) | 参数ExecutorType有三个可选值。 |
openSession(ExecutorType execType)简称execType参数值 有三个可选值:
- ExecutorType.SIMPLE:表示为每条语句创建一条新的预处理语句。
- ExecutorType.REUSE:表示会复用预处理语句。
- ExecutorType.BATCH:表示会批量执行所有更新语句。
简单理解,知道有这些方法设置就行后面才会用到。
SqlSession对象的作用
SqlSession是MyBatis框架中另一个重要的对象,它是应用程序与持久层之间执行交互操作的一个单线程对象,主要作用是执行持久化操作,类似于JDBC中的Connection。SqlSession对象包含了执行SQL操作的方法,由于其底层封装了JDBC连接,所以可以直接使用SqlSession对象来执行已映射的SQL语句。
以下是一些常见的 SqlSession 方法:
-
selectOne(String statement, Object parameter): 执行查询并返回单个结果对象。
statement是 SQL 语句的唯一标识符,parameter是查询所需的参数。 -
selectList(String statement, Object parameter): 执行查询并返回结果列表。与
selectOne类似,只是返回多个结果。 -
insert(String statement, Object parameter): 执行插入操作,插入一条数据。
-
update(String statement, Object parameter): 执行更新操作,更新数据。
-
delete(String statement, Object parameter): 执行删除操作,删除数据。
-
commit(): 提交事务。
-
rollback(): 回滚事务。
-
close(): 关闭
SqlSession实例。 -
getMapper(Class type): 获取一个 Mapper 接口的实例,通过该实例可以调用映射文件中配置的 SQL 语句。
示例使用:
SqlSession session = sqlSessionFactory.openSession();// 查询单个结果
User user = session.selectOne("getUserById", 1);// 查询结果列表
List<User> userList = session.selectList("getAllUsers");// 插入数据
User newUser = new User("John", "john@example.com");
int rowsInserted = session.insert("insertUser", newUser);// 更新数据
User updatedUser = new User(1, "UpdatedName", "updated@example.com");
int rowsUpdated = session.update("updateUser", updatedUser);// 删除数据
int rowsDeleted = session.delete("deleteUser", 1);// 提交事务
session.commit();// 关闭 SqlSession
session.close();
上述示例中的方法参数 "getUserById"、"getAllUsers"、"insertUser"、"updateUser"、"deleteUser" 是 MyBatis 配置文件中定义的 SQL 语句的唯一标识符。这些标识符与映射文件中的配置相对应,可以在映射文件中查找具体的 SQL 语句。
PS(名词科普):提交事务
在数据库中,事务(Transaction)是指一系列的数据库操作,这些操作被当作一个单独的工作单元来执行。事务的目的是确保数据库的一组操作要么全部执行成功,要么全部失败,以保持数据的一致性和完整性。
提交事务(Commit Transaction)是指将之前在一个事务中进行的一系列数据库操作永久地保存到数据库中,使这些操作对其他事务可见。当你执行提交事务操作时,数据库会将所有的变更持久保存,而且这些变更对其他事务和查询都是可见的。如果事务中的所有操作都执行成功,那么提交事务会将这些操作永久保存到数据库中。如果事务中的任何一个操作失败,那么整个事务都会被回滚(Rollback),即取消之前的操作,使数据库回到事务开始前的状态。
提交事务是数据库管理系统中确保数据一致性和持久性的重要机制之一,它确保了在事务执行完毕后,对数据的变更是持久保存的,而不会因为系统崩溃等情况而丢失。
SqlSession对象的使用范围:
每一个线程都应该有一个自己的SqlSession对象,并且该对象不能共享。SqlSession对象是线程不安全的,因此其使用范围最好在一次请求或一个方法中,绝不能将其放在类的静态字段、对象字段或任何类型的管理范围(如Servlet的HttpSession)中使用。SqlSession对象使用完之后,要及时的关闭,SqlSession对象通常放在finally块中关闭,代码如下所示。
SqlSession sqlSession = sqlSessionFactory.openSession();
try { // 此处执行持久化操作
} finally { sqlSession.close(); }
二、MyBatis核心配置文件
其中的主要元素如下:

以下是一些核心配置文件和配置项的含义(“”内的要重点掌握一下):
- properties: 用于指定一些全局的属性和变量,这些属性可以在整个配置文件中使用。
- “settings”: 用于配置 MyBatis 的全局性设置,例如缓存、延迟加载等。
- ”typeAliases“: 用于配置类型别名,使得在映射文件中可以使用简短的别名来引用 Java 类。
- typeHandlers: 用于配置类型处理器,用于将数据库中的数据类型映射为 Java 类型。
- objectFactory: 用于配置对象工厂,可以通过对象工厂来创建结果对象的实例。
- plugins: 用于配置插件,插件可以拦截 MyBatis 的一些操作,扩展其功能。
- environments: 用于配置不同的运行环境,比如开发环境、测试环境和生产环境。
- environment: 在
environments中配置的运行环境,可以指定transactionManager和dataSource。 - transactionManager: 用于配置事务管理器,管理数据库连接的生命周期和事务的提交与回滚。
- dataSource: 用于配置数据源,包括数据库连接的基本信息。
- mappers: 用于指定映射器接口的位置,即映射文件的位置。
元素是整个XML配置文件的根元素,相当于MyBatis各元素的管理员。有很多子元素,MyBatis的核心配置就是通过这些子元素完成的,子元素的顺序并不重要,只需要在 标签对中即可。

这里重点讲一下****的配置元素:
| 配置参数 | 描述 |
|---|---|
| cacheEnabled | 用于配置是否开启缓存。 |
| lazyLoadingEnabled | 延迟加载的全局开关。 |
| aggressiveLazyLoading | 关联对象属性的延迟加载开关。 |
| multipleResultSetsEnabled | 是否允许单一语句返回多结果集(需要兼容驱动)。 |
| useColumnLabel | 使用列标签代替列名。 |
| useGeneratedKeys | 允许JDBC支持自动生成主键,需要驱动兼容。 |
| autoMappingBehavior | 指定MyBatis应如何自动映射列到字段或属性。 |
| defaultExecutorType | 配置默认的执行器。 |
| defaultStatementTimeout | 配置超时时间,它决定驱动等待数据库响应的秒数。 |
| mapUnderscoreToCamelCase | 是否开启自动驼峰命名规则(camel case)映射。 |
| jdbcTypeForNull | 当没有为参数提供特定的JDBC类型时,为空值指定JDBC类型。 |
格式如下:
<settings><!-- 是否开启缓存 --><setting name="cacheEnabled" value="true" /><!-- 是否开启延迟加载,如果开启,所有关联对象都会延迟加载 --><setting name="lazyLoadingEnabled" value="true" /><!-- 是否开启关联对象属性的延迟加载,如果开启,对任意延迟属性的调用都会使用带有延迟加载属性的对象向完整加载,否则每种属性都按需加载 --><setting name="aggressiveLazyLoading" value="true" />...
</settings>
这里重点讲一下****元素:
核心配置文件若要引用一个POJO实体类,需要输入POJO实体类的全限定类名,而全限定类名比较冗长,如果直接输入,很容易拼写错误。例如,POJO实体类User的全限定类名是com.itheima.pojo.User,未设置别名之前,映射文件的select语句块若要引用POJO类User,必须使用其全限定类名,引用代码如下。
<select id="findById" parameterType="int" resultType="com.example.pojo.User">select * from users where id = #{id}
</select>
设置别名的方式如下:
①在元素下,使用多个元素为每一个全限定类逐个配置别名。
<typeAliases><typeAlias alias="User" type="com.example.pojo.User"/><typeAlias alias="Student" type="com.example.pojo.Student"/><typeAlias alias="Employee" type="com.example.pojo.Employee"/><typeAlias alias="Animal" type="com.example.pojo.Animal"/>
</typeAliases>
<environments>
②通过自动扫描包的形式自定义别名。
<typeAliases><package name="com.example.pojo"/>
</typeAliases>
<environments>
注意要放在 上面,不然程序会报错,Error building SqlSession.
除了可以使用元素为实体类自定义别名外,MyBatis框架还为许多常见的Java类型(如数值、字符串、日期和集合等)提供了相应的默认别名。例如别名_byte映射类型byte、_long映射类型long等,别名可以在MyBatis中直接使用,但由于别名不区分大小写,所以在使用时要注意重复定义的覆盖问题。
并且设置完别名以后,pojo包里面的类都会自动识别,所以Mapper.xml文件里面也需要修改一下。如下图得从pojo.PasswordMS 修改➡成 PasswordMS:

三、MyBatis映射文件及其元素的使用
上一篇文章,我们后面自己写一个插入的sql语句,现在要检测一下能不能正确的映射到数据库中。

结果发现,程序一直转动,但是不能在终端输入,也没办法继续进行。神奇的是也不报错,在我查阅资料后发现,原因如下
在JUnit测试中,无法直接通过终端输入参数。JUnit测试是自动化测试,在测试过程中是无法进行交互操作的。
解决办法:pom中引入Mockito,就可以模拟用户输入了
<!-- Mockito 依赖 --><dependency><groupId>org.mockito</groupId><artifactId>mockito-core</artifactId><version>4.0.0</version><scope>test</scope></dependency>
测试类也要修改
lass PasswordMSTest {private Logger logger= Logger.getLogger(PasswordMSTest.class);private InputStream originalSystemIn;private ByteArrayInputStream simulatedInput;@BeforeEachpublic void setUp() {originalSystemIn = System.in;}@AfterEachpublic void tearDown() {System.setIn(originalSystemIn);}@org.junit.jupiter.api.Testvoid insertOneIntoPasswordMS() {//读取文件名:String resources="mybatis-config.xml";//创建流Reader reader = null;try{reader = Resources.getResourceAsReader(resources);}catch (IOException e){e.printStackTrace();}String input = "John\n123456\n1234567890\nexample1.com\nhttps://example1.com\nicon.png\nSocial\n";// 将标准输入重定向到模拟输入流InputStream inputStream = new ByteArrayInputStream(input.getBytes());System.setIn(inputStream);PasswordMS passwordMS=new PasswordMS();Scanner scanner = new Scanner(System.in);System.out.println("请输入你想要存储的账号名:");passwordMS.setAccount(scanner.nextLine());System.out.println("请输入你想要存储的账号密码:");passwordMS.setPassword(scanner.nextLine());System.out.println("请输入你想要存储的与该账号绑定的手机号:");passwordMS.setPhoneNumber(scanner.nextLine());System.out.println("请输入你想要存储的账号所属网站名:");passwordMS.setWebsiteName(scanner.nextLine());System.out.println("请输入你想要存储的网址URL:");passwordMS.setWebsiteURL(scanner.nextLine());System.out.println("请输入网站的缩略图或者图标:");String WebsiteImage=scanner.nextLine();Optional<String> optionalS = Optional.ofNullable(WebsiteImage);passwordMS.setWebsiteImage(optionalS.orElse("Sorry 还没有"));System.out.println("请输入该账号的描述比如类别:");passwordMS.setAccountDescription(scanner.nextLine());//初始化mybatis数据库,创建SqlSessionFactory类的实例SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);//创建SqlSession实例SqlSession session = sqlSessionFactory.openSession();//传入参数查询,返回结果session.insert("insertOne",passwordMS);session.commit();session.close();}}
输出结果如下:

数据库中也成功插入记录

现在回过头来看,每个测试类其实有很大一部分都是重复的

这段代码的作用是打开mybatis-config.xml文件,用它连上数据库,然后打开数据连接,这段代码经常会在进行数据操作之前用到,但是我们又不想每次都复制粘贴它,这时我们可以把它**”封装“起来。直接调用。**
操作如下:
①java包下新建一个package为utils(一般默认为工具包)
②utils包下新建一个类为:MyBatisUtil.java
代码如下:
package utils;import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;public class MyBatisUtil {private static SqlSessionFactory factory;static{在静态代码块中,factory只会被创建一次System.out.println("static factory===============");try {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");factory = new SqlSessionFactoryBuilder().build(is);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static SqlSession createSqlSession(){return factory.openSession(false);//true为自动提交事务}public static void closeSqlSession(SqlSession sqlSession){if(null != sqlSession)sqlSession.close();}
}
通过以上”静态类“的方式来保证Sql Session Factory实例只被创建一次,当然,最佳的解决方案是使用Spring框架来管理Sql Session Factory的单例模式生命周期。关于和Spring的集成,我们会在后面使用到中进行讲解。
完成以上步骤以后,我们就能去优化我们的测试类了

blog.csdnimg.cn/c903f525bf3441ba8cc4a39acad62617.png#pic_center)
进行测试,还是能够正常运行,也能写入数据库进行交互。

使用Mybatis进行数据修改、删除操作
自行编写补充mapper映射文件嗷


总结
这是第二天对SSM框架的学习**,深入了解了Mybatis的核心对象SqlSessionFactoryBuilder**,掌握MyBatis核心配置文件以及元素的使用,也掌握MyBatis映射文件及其元素的使用。想要跟着学习的可以去我的资源里面找对应的文件下载,我的md文件也会发上去,项目文件会上传可以自己跟着学习一下。
PS:sql语句自己编写┗|`O′|┛ 嗷~~
作者:Stevedash
发表于:2023年8月21日 22点45分
注:本文内容基于个人学习理解,如有错误或疏漏,欢迎指正。感谢阅读!如果觉得有帮助,请点赞和分享。
相关文章:
SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录(第二天)Mybatis的深入学习
SSM框架的学习与应用(Spring Spring MVC MyBatis)-Java EE企业级应用开发学习记录(第二天)Mybatis的深入学习(增删改查的操作) 上一篇我们的项目搭建好了,也写了简答的Junit测试类进行测试,可以正确映射…...
学习笔记:Opencv实现限制对比度得自适应直方图均衡CLAHE
2023.8.19 为了完成深度学习的进阶,得学习学习传统算法拓展知识面,记录自己的学习心得 CLAHE百科: 一种限制对比度自适应直方图均衡化方法,采用了限制直方图分布的方法和加速的插值方法 clahe(限制对比度自适应直方图…...
R语言处理缺失数据(1)-mice
#清空 rm(listls()) gc()###生成模拟数据### #生成100个随机数 library(magrittr) set.seed(1) asd<-rnorm(100, mean 60, sd 10) %>% round #平均60,标准差10 #将10个数随机替换为NA NA_positions <- sample(1:100, 10) asd[NA_positions] <- NA #转…...
SpringBoot自动配置原理
Spring Boot 的自动配置可以根据添加的jar依赖,自动配置 Spring Boot 应用程序。例如,我们想要使用Redis,直接在POM文件中增加spring-boot-starter-data-redis依赖,然后我们配置下连接信息就可以使用了。 那么Spring Boot 是如何…...
HarmonyOS学习路之方舟开发框架—学习ArkTS语言(状态管理 五)
管理应用拥有的状态概述 LocalStorage:页面级UI状态存储 LocalStorage是页面级的UI状态存储,通过Entry装饰器接收的参数可以在页面内共享同一个LocalStorage实例。LocalStorage也可以在UIAbility内,页面间共享状态。 本文仅介绍LocalStora…...
Java基础篇——反射枚举
反射&枚举 课程目标 1. 【理解】类加载器 2. 【理解】什么是反射 3. 【掌握】获取Class对象的三种方式 4. 【掌握】反射获取构造方法并创建对象 5. 【掌握】反射获取成员变量并使用 6. 【掌握】反射获取成员方法并使用 7. 【掌握】反射综合案例 8. 【理解】枚举B友:http…...
每日一学——案例难点Windows配置
在Windows上配置DNS服务器有几个步骤: 步骤1:打开网络连接设置 在任务栏上右键单击网络图标,并选择“打开网络和Internet设置”。 在新窗口中,选择“更改适配器选项”。 在打开的窗口中,找到正在使用的网络适配器&a…...
2023.8 - java - 运算符
Java 运算符 算术运算符关系运算符位运算符逻辑运算符赋值运算符其他运算符 算术运算符 算术运算符用在数学表达式中,它们的作用和在数学中的作用一样。下表列出了所有的算术运算符。 表格中的实例假设整数变量A的值为10,变量B的值为20: …...
推荐三款Scrum敏捷项目管理工具/敏捷管理实践
免费版敏捷工具推荐: Leangoo领歌 Leangoo领歌是ScrumCN(scrum.cn)旗下的一款永久免费的专业敏捷开发管理工具,提供端到端敏捷研发管理解决方案,涵盖敏捷需求管理、任务协同、进展跟踪、缺陷管理、统计度量等。包括小…...
WARNING: undefined behavior - version of Delve is too old for Go version
在更新了 go 版本后,使用 goland 进行调试会报错 WARNING: undefined behavior - version of Delve is too old for Go version 1.20.5 (maximum supported version 1.19)这是因为 go 的版本升级后,相对 dlv 的版本就低了。 所以解决办法就是升级对应的…...
https非对称加密算法
非对称加密算法原理 在客户端公开公钥,服务端保存私钥 1.客户端第一次请求先请求443端口,从443端口下载公钥。 2.客户端将数据进行公钥算法进行加密,将秘文发送到服务端 服务端收到秘文后,通过私钥算法进行解密得到明文数据。…...
“深入探索JVM:Java虚拟机背后的奥秘“
标题:深入探索JVM:Java虚拟机背后的奥秘 摘要:本文将深入探索Java虚拟机(JVM)的内部工作原理和关键组成部分,揭示JVM背后的奥秘。通过对类加载机制、内存管理、垃圾回收、即时编译等方面的详细介绍&#x…...
树莓派系统入门教程(三)—— 使用Windows上的VSCode远程连接树莓派进行Python开发
树莓派系统入门教程(三)—— 使用Windows上的VSCode远程连接树莓派进行Python开发 1. 安装VSCode和SSH扩展2. SSH连接配置3. 连接到树莓派4. 运行Python程序5. 建议和注意事项 很多开发者更喜欢在大屏幕和强大的开发环境中编写代码,但同时他们…...
如何使用HTML5新增的标签来优化SEO?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用HTML5新增的标签来优化SEO?⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这个专栏是为那些对…...
LVS之keepalived
1、keepalived 概述 总结:Keepalived 软件就是通过VRRP协议来实现高可用功能。 应用场景:企业应用中,单台服务器承担应用存在单点故障的危险 单点故障一旦发生,企业服务将发生中断,造成极大的危害 VRRP通信原理&…...
Linux(入门篇)
Linux(入门篇) Linux概述Linux是什么Linux的诞生Linux和Unix的渊源GNU/LinuxLinux的发行版Linux VS Windows Linux概述 Linux是什么 Linux是一个操作系统(OS) Linux的诞生 作者:李纳斯托瓦兹(git也是他开发的😂&am…...
如何构造不包含字母和数字的webshell
利用不含字母与数字进行绕过 1.异或进行绕过 2.取反进行绕过 3.利用php语法绕过 利用不含字母与数字进行绕过 基本代码运行思路理解 <?php echo "A"^""; ?> 运行结果为! 我们可以看到,输出的结果是字符"!"。之所以会…...
springboot(JavaCV )实现视频截取第N帧并保存图片
springboot(JavaCV )实现视频截取第N帧并保存图片 现在视频网站展示列表都是用img标签展示的,动图用的是gif,但是我们上传视频时并没有视屏封面,就这需要上传到服务器时自动生成封面并保存 本博客使用jar包的方式实现…...
Linux面试笔试题(5)
79、下列工具中可以直接连接mysql的工具有【c 】。 A.xhsell B.plsql C.navicat D.以上都不是 Navicat 是一套可创建多个连接的数据库开发工具, 让你从单一应用程序中同时连接 MySQL、Redis、MariaDB、MongoDB、 SQL Server、Oracle、PostgreSQL和 SQLite 。它与…...
WordPress文章:创建和优化您的网站内容
WordPress是一种流行的内容管理系统(CMS),用于创建和管理网站。无论您是个人博客作者、企业网站管理员还是电子商务店主,WordPress都是一个强大而灵活的平台,可帮助您展示和传达您的信息。本文将为您提供一些关于创建和…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
