Mybatis Plus 详解 IService、BaseMapper、自动填充、分页查询功能

news2024/10/23 4:46:56

结构直接看目录

前言

MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

愿景

我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。

Relationship Between MyBatis and MyBatis-Plus

特性:

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

SpringBoot使用

将以下内容引入pom.xml

      <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>

以下内容可自选

spring:
    #配置数据源信息
    datasource:
    type: com.zaxxer.hikari.HikariDataSource
    #配置数据库连接信息
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost
    username: root
    password: root
 
#mybatisplus添加日志功能
mybatis-plus:
	configuration:
    	log-impl: org.apache.ibatis.logging.stdout.stdOutImpl
global-config:
	db-config:
    	#配置Mybatis-plus操作表的默认前缀
    	table-prefix: t_
    	#配置Mybatis-plus的主键策略
    	id-type: auto

配置文件注意事项


驱动类driver-class-name

spring boot 2.0(内置jdbc5驱动),驱动类使用:driver-class-name: com.mysql.jdbc.Driver

spring boot 2.1及以上(内置jdbc8驱动),驱动类使用:

driver-class-name: com.mysql.cj.jdbc.Driver

否则运行测试用例的时候会有 WARN 信息

连接地址url

MySQL5.7版本的url:

jdbc:mysql://localhost:3306/?characterEncoding=utf-8&useSSL=false

MySQL8.0版本的url:

jdbc:mysql://localhost:3306/?

serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false

 注意事项

// 这个属性用于指定 MyBatis Mapper XML 文件的位置,例如:mybatis-plus: mapper-locations: classpath*:/mapper/*Mapper.xml
mybatis-plus.mapper-locations


// 这个属性用于设置是否显示 MyBatis-Plus 的启动 banner。在示例中,该属性被设置为 false,表示禁用启动 banner
mybatis-plus.global-config.banner


// 这个属性用于设置主键 ID 的生成策略。在示例中,auto 表示使用数据库自动生成的主键 ID
mybatis-plus.global-config.db-config.id-type:auto


// 这些属性用于设置全局的 SQL 过滤策略。在示例中,not_empty 表示只在参数值非空时才会生成对应的 SQL 条件
mybatis-plus.global-config.db-config.where-strategy:not_empty
mybatis-plus.global-config.db-config.insert-strategy:not_empty
mybatis-plus.global-config.db-config.update-strategy:not_null


// 这个属性用于设置在 SQL 中处理空值时使用的 JDBC 类型。在示例中,'null' 表示使用 NULL 类型
mybatis-plus.configuration.jdbc-type-for-null:'null'


// 这个属性用于设置是否在设置属性为 NULL 时调用对应的 setter 方法。在示例中,该属性被设置为 true,表示在设置属性为 NULL 时会调用 setter 方法
mybatis-plus.configuration.call-setters-on-nulls:true

引导类中添加 @MapperScan 注解,扫描 Mapper 文件夹

@SpringBootApplication
@MapperScan("com.baomidou.mybatisplus.samples.quickstart.mapper")
public class MPApplication {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

建立实体类

自行建立一个实体,可以是最简单的 学生,姓名,班级,学号

建立Mapper层

继承BaseMapper,后面的实体写自己的实体

@Mapper
public interface UserMapper extends BaseMapper<UserEntity>{

}

建立Service层

建立Service接口
public interface UserService extends IService<UserEntity> {}
建立Service接口实现类ServiceImpl
	@Slf4j
	@Service
	public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements  
	UserService {}

Service Interface接口内容说明

插入功能save

// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);

功能描述:插入记录,根据实体对象的字段进行策略性插入。
返回值: boolean,表示插入操作是否成功。
参数说明:

类型参数名描述
Tentity实体对象
Collection<T>entityList实体对象集合
intbatchSize插入批次数量
示例 
// 假设有一个 User 实体对象
User user = new User();
user.setName("John Doe");
user.setEmail("john.doe@example.com");
boolean result = userService.save(user); // 调用 save 方法
if (result) {
    System.out.println("User saved successfully.");
} else {
    System.out.println("Failed to save user.");
}
 生成的 SQL:

INSERT INTO user (name, email) VALUES ('John Doe', 'john.doe@example.com')

如果存在就更新不存在就新增 saveOrUpdate

功能描述: 根据实体对象的主键 ID 进行判断,存在则更新记录,否则插入记录。
返回值: boolean,表示插入或更新操作是否成功。
参数说明:

类型参数名描述
Tentity实体对象
Wrapper<T>updateWrapper实体对象封装操作类 UpdateWrapper
Collection<T>entityList实体对象集合
intbatchSize插入批次数量
// TableId 注解属性值存在则更新记录,否插入一条记录
boolean saveOrUpdate(T entity);
// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
示例
// 假设有一个 User 实体对象,其中 id 是 TableId 注解的属性
User user = new User();
user.setId(1);
user.setName("John Doe");
user.setEmail("john.doe@example.com");
boolean result = userService.saveOrUpdate(user); // 调用 saveOrUpdate 方法
if (result) {
    System.out.println("User updated or saved successfully.");
} else {
    System.out.println("Failed to update or save user.");
}
生成的 SQL(假设 id 为 1 的记录已存在):
UPDATE user SET name = 'John Doe', email = 'john.doe@example.com' WHERE id = 1
生成的 SQL(假设 id 为 1 的记录不存在):
INSERT INTO user (id, name, email) VALUES (1, 'John Doe', 'john.doe@example.com')

删除功能remove

// 根据 queryWrapper 设置的条件,删除记录
boolean remove(Wrapper<T> queryWrapper);
// 根据 ID 删除
boolean removeById(Serializable id);
// 根据 columnMap 条件,删除记录
boolean removeByMap(Map<String, Object> columnMap);
// 删除(根据ID 批量删除)
boolean removeByIds(Collection<? extends Serializable> idList);

功能描述: 通过指定条件删除符合条件的记录。
返回值: boolean,表示删除操作是否成功。
参数说明:

类型参数名描述
Wrapper<T>queryWrapper实体包装类 QueryWrapper
Serializableid主键 ID
Map<String, Object>columnMap表字段 map 对象
Collection<? extends Serializable>idList主键 ID 列表
示例:
删除
// 假设有一个 QueryWrapper 对象,设置删除条件为 name = 'John Doe'
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "John Doe");
boolean result = userService.remove(queryWrapper); // 调用 remove 方法
if (result) {
    System.out.println("Record deleted successfully.");
} else {
    System.out.println("Failed to delete record.");
}
 生成的 SQL:
DELETE FROM user WHERE name = 'John Doe'
根据ID删除
// 假设要删除 ID 为 1 的用户
boolean result = userService.removeById(1); // 调用 removeById 方法
if (result) {
    System.out.println("User deleted successfully.");
} else {
    System.out.println("Failed to delete user.");
}
  生成的 SQL:
DELETE FROM user WHERE id = 1
批量删除
// 假设有一组 ID 列表,批量删除用户
List<Integer> ids = Arrays.asList(1, 2, 3);
boolean result = userService.removeByIds(ids); // 调用 removeByIds 方法
if (result) {
    System.out.println("Users deleted successfully.");
} else {
    System.out.println("Failed to delete users.");
}
  生成的 SQL:
DELETE FROM user WHERE id IN (1, 2, 3)

更新功能update

// 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
boolean update(Wrapper<T> updateWrapper);
// 根据 whereWrapper 条件,更新记录
boolean update(T updateEntity, Wrapper<T> whereWrapper);
// 根据 ID 选择修改
boolean updateById(T entity);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);

功能描述: 通过指定条件更新符合条件的记录。
返回值: boolean,表示更新操作是否成功。
参数说明:

类型参数名描述
Wrapper<T>updateWrapper实体对象封装操作类 UpdateWrapper
Tentity实体对象
Collection<T>entityList实体对象集合
intbatchSize更新批次数量
 根据元素进行更新
// 假设有一个 UpdateWrapper 对象,设置更新条件为 name = 'John Doe',更新字段为 email
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("name", "John Doe").set("email", "john.doe@newdomain.com");
boolean result = userService.update(updateWrapper); // 调用 update 方法
if (result) {
    System.out.println("Record updated successfully.");
} else {
    System.out.println("Failed to update record.");
}
   生成的 SQL:
UPDATE user SET email = 'john.doe@newdomain.com' WHERE name = 'John Doe'
根据ID进行更新
// 假设有一个 User 实体对象,设置更新字段为 email,根据 ID 更新
User updateEntity = new User();
updateEntity.setId(1);
updateEntity.setEmail("updated.email@example.com");
boolean result = userService.updateById(updateEntity); // 调用 updateById 方法
if (result) {
    System.out.println("Record updated successfully.");
} else {
    System.out.println("Failed to update record.");
}

    生成的 SQL:

UPDATE user SET email = 'updated.email@example.com' WHERE id = 1

查询功能get

// 根据 ID 查询
T getById(Serializable id);
// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根据 Wrapper,查询一条记录
Map<String, Object> getMap(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

功能描述: 根据指定条件查询符合条件的记录。
返回值: 查询结果,可能是实体对象、Map 对象或其他类型。
参数说明:

类型参数名描述
Serializableid主键 ID
Wrapper<T>queryWrapper实体对象封装操作类 QueryWrapper
booleanthrowEx有多个 result 是否抛出异常
Tentity实体对象
Function<? super Object, V>mapper转换函数
根据id进行查询
// 假设要查询 ID 为 1 的用户
User user = userService.getById(1); // 调用 getById 方法
if (user != null) {
    System.out.println("User found: " + user);
} else {
    System.out.println("User not found.");
}
   生成的 SQL:
SELECT * FROM user WHERE id = 1
根据对象进行查询
// 假设有一个 QueryWrapper 对象,设置查询条件为 name = 'John Doe'
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "John Doe");
User user = userService.getOne(queryWrapper); // 调用 getOne 方法
if (user != null) {
    System.out.println("User found: " + user);
} else {
    System.out.println("User not found.");
}
生成的SQL:
SELECT * FROM user WHERE name = 'John Doe' LIMIT 1

查询记录功能list

// 查询所有
List<T> list();
// 查询列表
List<T> list(Wrapper<T> queryWrapper);
// 查询(根据ID 批量查询)
Collection<T> listByIds(Collection<? extends Serializable> idList);
// 查询(根据 columnMap 条件)
Collection<T> listByMap(Map<String, Object> columnMap);
// 查询所有列表
List<Map<String, Object>> listMaps();
// 查询列表
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// 查询全部记录
List<Object> listObjs();
// 查询全部记录
<V> List<V> listObjs(Function<? super Object, V> mapper);
// 根据 Wrapper 条件,查询全部记录
List<Object> listObjs(Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

功能描述: 查询符合条件的记录。
返回值: 查询结果,可能是实体对象、Map 对象或其他类型。
参数说明:

类型参数名描述
Wrapper<T>queryWrapper实体对象封装操作类 QueryWrapper
Collection<? extends Serializable>idList主键 ID 列表
Map<String, Object>columnMap表字段 map 对象
Function<? super Object, V>mapper转换函数
示例:
查询全部
// 查询所有用户
List<User> users = userService.list(); // 调用 list 方法
for (User user : users) {
    System.out.println("User: " + user);
}
生成的SQL:
SELECT * FROM user
根据实体进行查询
// 假设有一个 QueryWrapper 对象,设置查询条件为 age > 25
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 25);
List<User> users = userService.list(queryWrapper); // 调用 list 方法
for (User user : users) {
    System.out.println("User: " + user);
}
生成的SQL:
SELECT * FROM user WHERE age > 25
批量查询用户
// 假设有一组 ID 列表,批量查询用户
List<Integer> ids = Arrays.asList(1, 2, 3);
Collection<User> users = userService.listByIds(ids); // 调用 listByIds 方法
for (User user : users) {
    System.out.println("User: " + user);
}

生成的SQL:

SELECT * FROM user WHERE id IN (1, 2, 3)
分页查询
// 无条件分页查询
IPage<T> page(IPage<T> page);
// 条件分页查询
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
// 无条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page);
// 条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);

功能描述: 分页查询符合条件的记录。
返回值: 分页查询结果,包含记录列表和总记录数。
参数说明:

类型参数名描述
IPage<T>page翻页对象
Wrapper<T>queryWrapper实体对象封装操作类 QueryWrapper
示例
分页查询
// 假设要进行无条件的分页查询,每页显示10条记录,查询第1页
IPage<User> page = new Page<>(1, 10);
IPage<User> userPage = userService.page(page); // 调用 page 方法
List<User> userList = userPage.getRecords();
long total = userPage.getTotal();
System.out.println("Total users: " + total);
for (User user : userList) {
    System.out.println("User: " + user);
}
 生成的SQL:
SELECT * FROM user LIMIT 10 OFFSET 0

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

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

相关文章

【前端技巧】css篇

利用counter实现计数器 counter-reset&#xff1a;为计数器设置名称&#xff0c;语法如下&#xff1a; counter-rese: <idntifier><integer>第一个参数为变量名称&#xff0c;第二个参数为初始值&#xff0c;默认为0 counter-increment&#xff1a;设置计数器增…

Redis 主从复制+哨兵+集群

Redis复制 查看docker 容器 ip docker inspect 容器id | grep IPAddressdocker inspect -f{{.Name}} {{.NetworkSettings.IPAddress}} $(docker ps -aq)修改配置文件 初始配置文件见 > redis.conf 远程访问 bind 0.0.0.0protected-mode no 主机设置 replicaof 172.17.0.…

fastadmin多语言切换设置

fastadmin版本&#xff1a;1.4.0.20230711 以简体&#xff0c;繁体&#xff0c;英文为例 一&#xff0c;在application\config.php 里开启多语言 // 是否开启多语言lang_switch_on > true, // 允许的语言列表allow_lang_list > [zh-cn, en,zh-tw], 二…

文本高效管理神器:支持自定义行数拆分,轻松实现批量高效编辑与管理新体验

在信息爆炸的时代&#xff0c;文本处理成为了我们日常工作中不可或缺的一部分。然而&#xff0c;面对大量的文本数据&#xff0c;如何高效地进行编辑和管理&#xff0c;却成为了许多人头疼的问题。现在&#xff0c;有了我们的文本批量高效编辑管理工具&#xff0c;一切将变得简…

RS485中继器的作用你还不知道?

RS485是一种串行通信协议&#xff0c;支持设备间长距离通信。RS485中继器则像“传声筒”&#xff0c;能放大衰减信号&#xff0c;延长通信距离&#xff0c;隔离噪声&#xff0c;扩展分支。在实际场景中&#xff0c;如工厂内&#xff0c;通过中继器可确保控制室与远距离机器间通…

虚拟现实环境下的远程教育和智能评估系统(十一)

视频帧画面知识点区域划分 知识点区域精确分割技术: 在深度学习检测模型结果基础上使用基于交并比&#xff08;IoU&#xff09;阈值的目标合并算法&#xff0c;合并过度重合目标区域面积&#xff0c;实现知识点区域精确分割 多模态知识点内容匹配策略: 图像&#xff1a;利用…

Linux驱动开发-01配置开发环境

一、配置网络环境 使用桥接网卡时 Ubuntu 就是使用一个真实的网卡 &#xff1a;开发板的网线也连接到这个真实的网卡上&#xff0c;这样 Windows 、 Ubuntu 、开发板就都可以用过这个网卡互通了。 NAT 网卡&#xff1a; Ubuntu 通过它上网&#xff0c;只要 Windows 能上网&…

idea 配置文件中文乱码

再进行springboot项目开发时发现新建的配置文件中文注释乱码&#xff0c;如下: 处理办法: 1、打开idea&#xff0c;在 File 中找到 Settings,如下图 2、搜索 encodings 找到 File Encodings&#xff0c;如下图 3、将上图中圈上的地方全部改为 UTF-8 编码最后点击 Apply 应用即…

鸿蒙Harmony实战—通过登录Demo了解ArkTS

ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript&#xff08;简称TS&#xff09;生态基础上做了进一步扩展&#xff0c;继承了TS的所有特性&#xff0c;是TS的超集。 ArkTS在TS的基础上主要扩展了如下能力&#xff1a; 基本语法&#xff1a;ArkTS定义…

信息学奥赛初赛天天练-30CSP-J2022完善程序-结构体构造函数初始化、auto关键字、连通块、洪水填充算法实战

PDF文档公众号回复关键字:20240620 2022 CSP-J 阅读程序2 完善程序 (单选题 &#xff0c;每小题3分&#xff0c;共30分) 2 (洪水填充) 现有用字符标记像素颜色的8 * 8图像。颜色填充操作描述如下&#xff1a;给定起始像素的位置和待填充的颜色&#xff0c;将起始像素和所有可…

山东华素制药有限公司:素心做药,感恩回报

在山东威海这片美丽的土地上,有一颗璀璨的明珠——山东华素制药有限公司。自2013年成立以来,这家企业以其深厚的制药底蕴、卓越的研发实力和坚定的社会责任,赢得了社会各界的广泛赞誉。它不仅是化学药品制剂制造的佼佼者,更是“素心做药,感恩回报”的典范。 一、素心做药,品质为…

Android Compose 文本输入框TextField使用详解

一、 TextField介绍 TextField 允许用户输入和修改文本&#xff0c;也就是文本输入框。 TextField 分为三种&#xff1a; TextField是默认样式OutlinedTextField 是轮廓样式版本BasicTextField 允许用户通过硬件或软件键盘修改文本&#xff0c;但不提供提示或占位符等装饰&a…

【机器学习】机器学习重要方法—— 半监督学习:理论、算法与实践

文章目录 引言第一章 半监督学习的基本概念1.1 什么是半监督学习1.2 半监督学习的优势 第二章 半监督学习的核心算法2.1 自训练&#xff08;Self-Training&#xff09;2.2 协同训练&#xff08;Co-Training&#xff09;2.3 图半监督学习&#xff08;Graph-Based Semi-Supervise…

C++基础知识——命名空间

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan. 文章目录 1、什么是命名空间2、命名空间的作用3、如何定义命名…

总结之LangChain(一)—— 简单使用LangChain

LangChain介绍 LangChain官网&#xff1a;https://python.langchain.com/v0.2/docs/introduction/ LangChain 是一个基于大型语言模型&#xff08;LLM&#xff09;开发应用程序的框架。 LangChain 简化了LLM应用程序生命周期的每个阶段&#xff1a; 开发&#xff1a;使用 L…

JavaSE 利用正则表达式进行本地和网络爬取数据(爬虫)

爬虫 正则表达式的作用 作用1&#xff1a;校验字符串是满足规则 作用2&#xff1a;在一段文本中查找满足需要的内容 本地爬虫和网络爬虫 Pattern类 表示正则表达式 Matter类 文本编译器&#xff0c;作用按照正则表达式的规则去读取字符串&#xff0c;从头开始读取&#xf…

Everything 一款功能强大的搜索工具

要在电脑上使用Everything搜索文件&#xff0c;您需要使用以下步骤&#xff1a; 在您的电脑上下载并安装Everything软件。您可以从官方网站https://www.voidtools.com/downloads/下载最新版本的软件。 安装完成后&#xff0c;打开Everything软件。 在搜索栏中输入您要查找的文…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 连续字母长度(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; &#x1f…

手把手教你如何部署自己的One Tool助手

手把手教你如何部署自己的One Tool助手 前言安装教程效果图在这里插入图片描述 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/0fc5cb0f451e4c50b55ec850a5517b0c.png) ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/56331f878b9545d5bff6f938c4b317…

uniapp 项目,用HBuilder X在小程序端 运行项目,发布项目

1. 运行项目&#xff08;直接在微信开发者工具中导入项目&#xff0c;运行项目会报错&#xff0c;要通过HBuilder X运行项目&#xff09; 1.1 配置内容&#xff0c;必须是该小程序的开发者才能运行 查看appid, 项目 -- manifest.json 文件 -- 微信小程序配置 -- APPID 小程序…