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

C#入坑JAVA MyBatis入门 CURD 批量 联表分页查询

本文,分享 MyBatis 各种常用操作,不限于链表查询、分页查询等等。

1. 分页查询

在 下文的 的「3.4 selectPage」小节,我们使用 MyBatis Plus 实现了分页查询。除了这种方式,我们也可以使用 XML 实现分页查询。

这里,以查询 system_users 表为例,讲解如何使用 XML 实现分页查询。

#1.1 方案一:MyBatis XML

这个是 MyBatis 内置的使用方式,步骤如下:

分页案例 01

① 创建 AdminUserMapper.xml 文件,编写两个 SQL 查询语句:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper"><select id="selectPage01List"resultType="cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO" >SELECT * FROM system_users<where><if test="reqVO.username != null and reqVO.username !=''">AND username LIKE CONCAT('%',#{reqVO.username},'%')</if><if test="reqVO.createTime != null">AND create_time BETWEEN #{reqVO.createTime[0]}, #{reqVO.createTime[1]},</if><if test="reqVO.status != null">AND status = #{reqVO.status}</if></where>ORDER BY id DESCLIMIT #{reqVO.pageNo}, #{reqVO.pageSize}</select><select id="selectPage01Count" resultType="Long" >SELECT COUNT(1) FROM system_users<where><if test="reqVO.username != null and reqVO.username !=''">AND username LIKE CONCAT('%',#{reqVO.username},'%')</if><if test="reqVO.createTime != null">AND create_time BETWEEN #{reqVO.createTime[0]}, #{reqVO.createTime[1]},</if><if test="reqVO.status != null">AND status = #{reqVO.status}</if></where></select></mapper>

② 在 AdminUserMapper 创建这两 SQL 对应的方法:

@Mapper
public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {/*** 查询分页的列表*/List<AdminUserDO> selectPage01List(@Param("reqVO") UserPageReqVO reqVO);/*** 查询分页的条数*/Long selectPage01Count(@Param("reqVO") UserPageReqVO reqVO);}

其中 UserPageReqVO.java (opens new window)是分页查询的请求 VO。

③ 在 AdminUserServiceImplService 层,调用这两个方法,实现分页查询:

@Service
@Slf4j
public class AdminUserServiceImpl implements AdminUserService {@Overridepublic PageResult<AdminUserDO> getUserPage(UserPageReqVO reqVO) {return new PageResult<>(userMapper.selectPage01List(reqVO),userMapper.selectPage01Count(reqVO));}
}

④ 简单调用下,可以在 IDEA 控制台看到 2 条 SQL:

分页案例 01 的效果

#1.2 方案二:MyBatis Plus XML

这个是 MyBatis Plus 拓展的使用方式,可以简化只需要写一条 SQL,步骤如下:

分页案例 02

① 创建 AdminUserMapper.xml 文件,只编写一个 SQL 查询语句:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper"><select id="selectPage02"resultType="cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO" >SELECT * FROM system_users<where><if test="reqVO.username != null and reqVO.username !=''">AND username LIKE CONCAT('%',#{reqVO.username},'%')</if><if test="reqVO.createTime != null">AND create_time BETWEEN #{reqVO.createTime[0]}, #{reqVO.createTime[1]},</if><if test="reqVO.status != null">AND status = #{reqVO.status}</if></where>ORDER BY id DESC</select></mapper>

注意,不需要写 LIMIT 分页语句噢。

② 在 AdminUserMapper 创建这一 SQL 对应的方法:

@Mapper
public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {IPage<AdminUserDO> selectPage02(IPage<AdminUserDO> page, @Param("reqVO") UserPageReqVO reqVO);}

第一个参数、返回结果必须都是 IPage 类型,第二个参数可以放查询条件。

③ 在 AdminUserServiceImplService 层,调用这一个方法,实现分页查询:

@Service
@Slf4j
public class AdminUserServiceImpl implements AdminUserService {@Overridepublic PageResult<AdminUserDO> getUserPage(UserPageReqVO reqVO) {// 必须使用 MyBatis Plus 的分页对象IPage<AdminUserDO> page = new Page<>(reqVO.getPageNo(), reqVO.getPageSize());userMapper.selectPage02(page, reqVO);return new PageResult<>(page.getRecords(), page.getTotal());}
}

因为项目使用 PageParam 和 PageResult 作为分页对象,所以需要和 IPage 做下转换。

④ 简单调用下,可以在 IDEA 控制台看到 2 条 SQL:

分页案例 02 的效果

本质上,MyBatis Plus 是基于我们在 XML 编写的这条 SQL,计算出获得分页数量的 SQL。

一般情况下,建议采用方案二:MyBatis Plus XML,因为它开发效率更高,并且在分页数量为 0 时,就不多余查询分页的列表,一定程度上可以提升性能。

#2. 联表查询

对于需要链表查询的场景,建议也是写 MyBatis XML,使用方法比较简单,可以看下 《MyBatis学习总结(三)—— 多表关联查询与动态 SQL》 (opens new window)文章。

除了 XML 这种方式外,项目也集成了 MyBatis Plus Join (opens new window)框架,通过 Java 代码实现联表查询。

这里,以查询 system_users 和 system_dept 联表,查询部门名为  音娱乐行、用户状态为开启的用户列表。

#2.1 案例一:字段平铺

① 创建 AdminUserDetailDO 类,继承 AdminUserDO 类,并添加 deptName 平铺。代码如下:

@Data
public class AdminUserDetailDO extends AdminUserDO {private String deptName;}

② 在 AdminUserMapper 创建 selectListByStatusAndDeptName 方法,代码如下:

@Mapper
public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {default List<AdminUserDetailDO> selectList2ByStatusAndDeptName(Integer status, String deptName) {return selectJoinList(AdminUserDetailDO.class, new MPJLambdaWrapper<AdminUserDO>() // 查询 List.selectAll(AdminUserDO.class) // 查询 system_users 表的 all 所有字段.selectAs(DeptDO::getName, AdminUserDetailDO::getDeptName) // 查询 system_dept 表的 name 字段,使用 deptName 字段“部分”返回.eq(AdminUserDO::getStatus, status) // WHERE system_users.status = ? 【部门名为 `芋道源码`】.leftJoin(DeptDO.class, DeptDO::getId, AdminUserDO::getDeptId) // 联表 WHERE system_users.dept_id = system_dept.id .eq(DeptDO::getName, deptName) // WHERE system_dept.name = ? 【用户状态为开启】);}}

#2.2 案例二:字段内嵌

① 创建 AdminUserDetailDO 类,继承 AdminUserDO 类,并添加 dept 部门。代码如下:

@Data
public class AdminUserDetail2DO extends AdminUserDO {private DeptDO dept;}

② 在 AdminUserMapper 创建 selectListByStatusAndDeptName 方法,代码如下:

@Mapper
public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {default List<AdminUserDetail2DO> selectListByStatusAndDeptName(Integer status, String deptName) {return selectJoinList(AdminUserDetail2DO.class, new MPJLambdaWrapper<AdminUserDO>().selectAll(AdminUserDO.class).selectAssociation(DeptDO.class, AdminUserDetail2DO::getDept) // 重点差异点:查询 system_dept 表的 name 字段,使用 dept 字段“整个”返回.eq(AdminUserDO::getStatus, status).leftJoin(DeptDO.class, DeptDO::getId, AdminUserDO::getDeptId).eq(DeptDO::getName, deptName));}}

#2.3 总结

MyBatis Plus Join 相比 MyBatis XML 来说,一开始肯定是需要多看看它的文档 (opens new window)。

但是熟悉后,我还是更喜欢使用 MyBatis Plus Join 哈~

《MyBatis 数据库》MyBatis 是最容易读懂的 Java 框架之一

1. 实体类

BaseDO (opens new window) 是所有数据库实体的父类,代码如下:

@Data
public abstract class BaseDO implements Serializable {/*** 创建时间*/@TableField(fill = FieldFill.INSERT)private Date createTime;/*** 最后更新时间*/@TableField(fill = FieldFill.INSERT_UPDATE)private Date updateTime;/*** 创建者,目前使用 AdminUserDO / MemberUserDO 的 id 编号** 使用 String 类型的原因是,未来可能会存在非数值的情况,留好拓展性。*/@TableField(fill = FieldFill.INSERT)private String creator;/*** 更新者,目前使用 AdminUserDO / MemberUserDO 的 id 编号** 使用 String 类型的原因是,未来可能会存在非数值的情况,留好拓展性。*/@TableField(fill = FieldFill.INSERT_UPDATE)private String updater;/*** 是否删除*/@TableLogicprivate Boolean deleted;}
  • createTime + creator 字段,创建人相关信息。
  • updater + updateTime 字段,创建人相关信息。
  • deleted 字段,逻辑删除。

对应的 SQL 字段如下:

`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',

#1.1 主键编号

id 主键编号,推荐使用 Long 型自增,原因是:

  • 自增,保证数据库是按顺序写入,性能更加优秀。
  • Long 型,避免未来业务增长,超过 Int 范围。

对应的 SQL 字段如下:

`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',

项目的 id 默认采用数据库自增的策略,如果希望使用 Snowflake 雪花算法,可以修改 application.yaml 配置文件,将配置项 mybatis-plus.global-config.db-config.id-type 修改为 ASSIGN_ID。如下图所示:

配置 Snowflake 雪花算法

#1.2 逻辑删除

所有表通过 deleted 字段来实现逻辑删除,值为 0 表示未删除,值为 1 表示已删除,可见 application.yaml 配置文件的 logic-delete-value 和 logic-not-delete-value 配置项。如下图所示:

逻辑删除的配置

① 所有 SELECT 查询,都会自动拼接 WHERE deleted = 0 查询条件,过滤已经删除的记录。如果被删除的记录,只能通过在 XML 或者 @SELECT 来手写 SQL 语句。例如说:

不自动过滤逻辑删除

② 建立唯一索引时,需要额外增加 delete_time 字段,添加到唯一索引字段中,避免唯一索引冲突。例如说,system_users 使用 username 作为唯一索引:

  • 未添加前:先逻辑删除了一条 username = yudao 的记录,然后又插入了一条 username = yudao 的记录时,会报索引冲突的异常。
  • 已添加后:先逻辑删除了一条 username = yudao 的记录并更新 delete_time 为当前时间,然后又插入一条 username = yudao 并且 delete_time 为 0 的记录,不会导致唯一索引冲突。

#1.3 自动填充

DefaultDBFieldHandler (opens new window) 基于 MyBatis 自动填充机制,实现 BaseDO 通用字段的自动设置。代码如下如:

DefaultDBFieldHandler 自动填充

#1.4 “复杂”字段类型

MyBatis Plus 提供 TypeHandler 字段类型处理器,用于 JavaType 与 JdbcType 之间的转换。示例如下:

字段处理器的示例

常用的字段类型处理器有:

  • JacksonTypeHandler (opens new window):通用的 Jackson 实现 JSON 字段类型处理器。
  • JsonLongSetTypeHandler (opens new window):针对 Set<Long> 的 Jackson 实现 JSON 字段类型处理器。

另外,如果你后续要拓展自定义的 TypeHandler 实现,可以添加到 cn.iocoder.yudao.framework.mybatis.core.type (opens new window)包下。

注意事项:

使用 TypeHandler 时,需要设置实体的 @TableName 注解的 @autoResultMap = true

#2. 编码规范

① 数据库实体类放在 dal.dataobject 包下,以 DO 结尾;数据库访问类放在 dal.mysql 包下,以 Mapper 结尾。如下图所示:

包规范


② 数据库实体类的注释要完整,特别是哪些字段是关联(外键)、枚举、冗余等等。例如说:

包规范


③ 禁止在 Controller、Service 中,直接进行 MyBatis Plus 操作。原因是:大量 MyBatis 操作散落在 Service 中,会导致 Service 的代码越来乱,无法聚焦业务逻辑。

示例
错误

正确

并且,通过只允许将 MyBatis Plus 操作编写 Mapper 层,更好的实现 SELECT 查询的复用,而不是 Service 会存在很多相同且重复的 SELECT 查询的逻辑。


④ Mapper 的 SELECT 查询方法的命名,采用 Spring Data 的 "Query methods" (opens new window)策略,方法名使用 selectBy查询条件 规则。例如说:

SELECT 命名示例


⑤ 优先使用 LambdaQueryWrapper 条件构造器,使用方法获得字段名,避免手写 "字段" 可能写错的情况。例如说:

LambdaQueryWrapper 条件构造器


⑥ 简单的单表查询,优先在 Mapper 中通过 default 方法实现。例如说:

单表查询

#3. CRUD 接口

BaseMapperX (opens new window)接口,继承 MyBatis Plus 的 BaseMapper 接口,提供更强的 CRUD 操作能力。

#3.1 selectOne

#selectOne(...) (opens new window)方法,使用指定条件,查询单条记录。示例如下:

selectOne 示例

#3.2 selectCount

#selectCount(...) (opens new window)方法,使用指定条件,查询记录的数量。示例如下:

selectCount 示例

#3.3 selectList

#selectList(...) (opens new window)方法,使用指定条件,查询多条记录。示例如下:

selectList 示例

#3.4 selectPage

针对 MyBatis Plus 分页查询的二次分装,在 BaseMapperX (opens new window)中实现,目的是使用项目自己的分页封装:

  • 【入参】查询前,将项目的分页参数 PageParam (opens new window),转换成 MyBatis Plus 的 IPage 对象。
  • 【出参】查询后,将 MyBatis Plus 的分页结果 IPage,转换成项目的分页结果 ​​​​​​​PageResult (opens new window)。代码如下图:

BaseMapperX 实现

具体的使用示例,可见 ​​​​​​​TenantMapper (opens new window)类中,定义 selectPage 查询方法。代码如下:

@Mapper
public interface TenantMapper extends BaseMapperX<TenantDO> {default PageResult<TenantDO> selectPage(TenantPageReqVO reqVO) {return selectPage(reqVO, new LambdaQueryWrapperX<TenantDO>().likeIfPresent(TenantDO::getName, reqVO.getName()) // 如果 name 不为空,则进行 like 查询.likeIfPresent(TenantDO::getContactName, reqVO.getContactName()).likeIfPresent(TenantDO::getContactMobile, reqVO.getContactMobile()).eqIfPresent(TenantDO::getStatus, reqVO.getStatus()) // 如果 status 不为空,则进行 = 查询.betweenIfPresent(TenantDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) // 如果 create 不为空,则进行 between 查询.orderByDesc(TenantDO::getId)); // 按照 id 倒序}}

完整实战,可见 《开发指南 —— 分页实现》 文档。

#3.5 insertBatch

#insertBatch(...) (opens new window)方法,遍历数组,逐条插入数据库中,适合少量数据插入,或者对性能要求不高的场景。 示例如下:

insertBatch 示例

为什么不使用 insertBatchSomeColumn 批量插入?

  • 只支持 MySQL 数据库。其它 Oracle 等数据库使用会报错,可见 InsertBatchSomeColumn (opens new window)说明。
  • 未支持多租户。插入数据库时,多租户字段不会进行自动赋值。

#4. 批量插入

绝大多数场景下,推荐使用 MyBatis Plus 提供的 IService 的 #saveBatch() (opens new window)​​​​​​​方法。示例 PermissionServiceImpl (opens new window)如下:

saveBatch 示例

#5. 条件构造器

继承 MyBatis Plus 的条件构造器,拓展了 LambdaQueryWrapperX (opens new window)和 QueryWrapperX (opens new window)类,主要是增加 xxxIfPresent 方法,用于判断值不存在的时候,不要拼接到条件中。例如说:

xxxIfPresent 方法

具体的使用示例如下:

LambdaQueryWrapperX 使用示例

#6. Mapper XML

默认配置下,MyBatis Mapper XML 需要写在各 yudao-module-xxx-biz 模块的 resources/mapper 目录下。示例 TestDemoMapper.xml (opens new window)如下:

TestDemoMapper.xml 示例

尽量避免数据库的连表(多表)查询,而是采用多次查询,Java 内存拼接的方式替代。例如说:

UserController 示例

#7. 字段加密

EncryptTypeHandler (opens new window),基于 Hutool AES (opens new window)实现字段的解密与解密。

例如说,数据源配置 (opens new window)的 password 密码需要实现加密存储,则只需要在该字段上添加 EncryptTypeHandler 处理器。示例代码如下:

@TableName(value = "infra_data_source_config", autoResultMap = true) // ① 添加 autoResultMap = true
public class DataSourceConfigDO extends BaseDO {// ... 省略其它字段/*** 密码*/@TableField(typeHandler = EncryptTypeHandler.class) // ② 添加 EncryptTypeHandler 处理器private String password;}

另外,在 application.yaml 配置文件中,可使用 mybatis-plus.encryptor.password 设置加密密钥。

字段加密后,只允许使用精准匹配,无法使用模糊匹配。示例代码如下:

@Test // 测试使用 password 查询,可以查询到数据
public void testSelectPassword() {// mock 数据DataSourceConfigDO dbDataSourceConfig = randomPojo(DataSourceConfigDO.class);dataSourceConfigMapper.insert(dbDataSourceConfig);// @Sql: 先插入出一条存在的数据// 调用DataSourceConfigDO result = dataSourceConfigMapper.selectOne(DataSourceConfigDO::getPassword,EncryptTypeHandler.encrypt(dbDataSourceConfig.getPassword())); // 重点:需要使用 EncryptTypeHandler 去加密查询字段!!!
}

相关文章:

C#入坑JAVA MyBatis入门 CURD 批量 联表分页查询

本文&#xff0c;分享 MyBatis 各种常用操作&#xff0c;不限于链表查询、分页查询等等。 1. 分页查询 在 下文的 的「3.4 selectPage」小节&#xff0c;我们使用 MyBatis Plus 实现了分页查询。除了这种方式&#xff0c;我们也可以使用 XML 实现分页查询。 这里&#xff0c…...

RabbitMQ 安装(Windows版本)和使用

安装 安装包获取 可以自己找资源&#xff0c;我这里也有百度云的资源&#xff0c;如果没失效的话可以直接用。 通过百度网盘分享的文件&#xff1a;RabbitMQ 链接&#xff1a;https://pan.baidu.com/s/1rzcdeTIYQ4BqzHLDSwCgyw?pwdfj79 提取码&#xff1a;fj79 安装教程…...

Apache paimon表管理

表管理 2.9.4.1 管理快照 1)快照过期 Paimon Writer每次提交都会生成一个或两个快照。每个快照可能会添加一些新的数据文件或将一些旧的数据文件标记为已删除。然而,标记的数据文件并没有真正被删除,因为Paimon还支持时间旅行到更早的快照。它们仅在快照过期时被删除。 …...

java 第19天

一.Lambda表达式 前提是&#xff1a;参数是函数式接口才可以书写Lambda表达式 函数式接口条件&#xff1a; 1.接口 2.只有一个抽象方法 lambda表达式又称为匿名函数&#xff0c;允许匿名函数以参数的形式传入方法&#xff0c;简化代码 lambda表达式分为两部分()->{} …...

什么是服务器?服务器与客户端的关系?本地方访问不了网址与服务器访问不了是什么意思?有何区别

服务器是一种高性能的计算机&#xff0c;它通过网络为其他计算机&#xff08;称为客户端&#xff09;提供服务。这些服务可以包括文件存储、打印服务、数据库服务或运行应用程序等。服务器通常具有强大的处理器、大量的内存和大容量的存储空间&#xff0c;以便能够处理多个客户…...

Spring(1)—Spring 框架:Java 开发者的春天

一、关于Spring 1.1 简介 Spring 框架是一个功能强大的开源框架&#xff0c;主要用于简化 Java 企业级应用的开发&#xff0c;由被称为“Spring 之父”的 Rod Johnson 于 2002 年提出并创立&#xff0c;并由Pivotal团队维护。它提供了全面的基础设施支持&#xff0c;使开发者…...

MT1401-MT1410 码题集 (c 语言详解)

目录 MT1401归并排序 MT1402堆排序 MT1403后3位排序 MT1404小大大小排序 MT1405小大大小排序II MT1406数字重排 MT1407插入 MT1408插入 MT1409旋转数组 MT1410逆时针旋转数组 MT1401归并排序 c 语言实现代码 #include <stdio.h>// merge two subarrays void merge(int a…...

React基础语法

1.React介绍 React由Meta公司开发&#xff0c;是一个用于构建Web和原生交互界面的库 1.1 React优势 相较于传统基于DOM开发的优势 1.组件化的开发方式 2.不错的性能 相较于其他前端框架的优势 1.丰富的生态 2.跨平台支持 1.2React的时长情况 全球最流行&#xff0c;大厂…...

《Kadane‘s Algorithm专题:最大和连续子数组》

&#x1f680; 博主介绍&#xff1a;大家好&#xff0c;我是无休居士&#xff01;一枚任职于一线Top3互联网大厂的Java开发工程师&#xff01; &#x1f680; &#x1f31f; 在这里&#xff0c;你将找到通往Java技术大门的钥匙。作为一个爱敲代码技术人&#xff0c;我不仅热衷…...

Vue基础(5)

ref属性 在 Vue2 中&#xff0c;ref是一个特殊的属性&#xff0c;用于在模板中获取对某个 DOM 元素或子组件的引用。通过 ref&#xff0c;我们可以在 JavaScript 代码中直接访问该 DOM 元素或组件实例。 示例: <template><div><input ref"inputField&quo…...

面对复杂的软件需求:5大关键策略!

面对软件需求来源和场景的复杂性&#xff0c;有效地管理和处理需求资料是确保项目成功的关键&#xff0c;能够提高需求理解的准确性&#xff0c;增强团队协作和沟通&#xff0c;降低项目风险&#xff0c;提高开发效率。反之&#xff0c;项目可能面临需求理解不准确、团队沟通不…...

使用Git进行版本控制的最佳实践

文章目录 Git简介基本概念仓库&#xff08;Repository&#xff09;提交&#xff08;Commit&#xff09;分支&#xff08;Branching&#xff09; 常用命令初始化仓库添加文件提交修改查看状态克隆仓库分支操作合并分支推送更改 最佳实践使用有意义的提交信息定期推送至远程仓库使…...

【入门1】顺序结构 - B2025 输出字符菱形

题目描述 用 * 构造一个对角线长 55 个字符&#xff0c;倾斜放置的菱形。 输入格式 没有输入要求。 输出格式 如样例所示。用 * 构成的菱形。 输入输出样例 输入 #1 输出 #1**** ********* <C> : #include<stdio.h>int main() {printf(" *\n ***\n**…...

C#DLL热加载|动态替换

我有一个项目 开始取数据和结束数据部分是一样的&#xff0c;但中间处理数据是根据客户需求来转换的 又要求增加一个客户数据转换 主程序是不能停下来的 所以这个项目转数据转换部分做成插件式 每个客户的数据转换都是一个项目 都是一个DLL 主程序里面定义好接口类或者抽象…...

数据库三大范式

目录 第一范式(1NF) 第二范式(2NF) 第三范式(3NF) Oracle三大范式是数据库设计中的规范化过程,旨在减少数据冗余、提高数据一致性和数据库性能。这三大范式包括第一范式(1NF)、第二范式(2NF)和第三范式(3NF)。 第一范式(1NF) 数据库表的每一列都是不可分割…...

【linux】fdisk磁盘分区管理

介绍 fdisk是一个磁盘分区管理工具&#xff0c;可以用来创建、删除、修改和查看磁盘分区。 fdisk一般都是交互式使用&#xff0c;基础语法: fdisk /dev/sdd。进入交互窗口后&#xff0c;有一些选项&#xff0c;需要了解下&#xff1a; 选项含义n创建新分区p查看磁盘的分区情…...

asp.net core 入口 验证token,但有的接口要跳过验证

asp.net core 入口 验证token,但有的接口要跳过验证 在ASP.NET Core中&#xff0c;你可以使用中间件来验证token&#xff0c;并为特定的接口创建一个属性来标记是否跳过验证。以下是一个简化的例子&#xff1a; 创建一个自定义属性来标记是否跳过验证&#xff1a; public clas…...

[mysql]聚合函数GROUP BY和HAVING的使用和sql查询语句的底层执行逻辑

#GROUP BY的使用 还是先从需求出发,我们现在想求员工表里各个部门的平均工资,最高工资 SELECT department_id,AVG(salary) FROM employees GROUP BY department_id 我们就会知道它会把一样的id分组,没有部门的就会分为一组,我们也可以用其他字段来分组,我们想查询不同jb_id…...

从数据中台到数据飞轮:实现数据驱动的升级之路

从数据中台到数据飞轮&#xff1a;实现数据驱动的升级之路 随着数字化转型的推进&#xff0c;数据已经成为企业最重要的资产之一&#xff0c;企业普遍搭建了数据中台&#xff0c;用于整合、管理和共享数据&#xff1b;然而&#xff0c;近年来&#xff0c;数据中台的风潮逐渐减退…...

小记:SpringBoot中,@Alisa和@ApiModelProperty的区别

在 Spring Boot 中&#xff0c;Alias和ApiModelProperty 这两个注解用于不同的目的。 Alias Alias是一个用于定义别名的注解&#xff0c;通常用于 Bean 属性的别名功能&#xff0c;这样在使用某些框架&#xff08;如 JPA 或 Jackson&#xff09;时&#xff0c;可以将一个属性名…...

信捷 PLC C语言 定时器在FC中的使用

传统梯形图的定时器程序写起来简单&#xff0c;本文用C语言写定时器的使用。 定时器在c语言中使用&#xff0c;和普通梯形图中使用的区别之一是既有外部条件&#xff0c;也有内部条件。 1.建全局变量 2.建立FC POU 这个是功能POU程序。 这里的Enable是内部条件 3.调用包含定…...

k8s常用对象简介

Pod Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。 Pod 是一组&#xff08;一个或多个&#xff09; 容器&#xff1b; 这些容器共享存储、网络、以及怎样运行这些容器的声明。 Pod 中的内容总是并置&#xff08;colocated&#xff09;的并且一同调度&…...

【Kaggle | Pandas】练习2:索引,选择和分配

文章目录 数据总表1、读取列2、读取某列的第几行的值3、第一行数据4、读取列中前10个值5、读取索引标签为1 、 2 、 3 、 5和8的记录6、包含索引标签为0 、1 、10和100的记录的country 、province 、 region_1和region_2列7、 前 100 条记录的country和variety列8、包含Italy葡…...

【flask】 flask redis的使用

目的&#xff1a;如何使用在flask web项目中连接redis&#xff0c;并简单的使用 使用的库包&#xff1a;flask-redis pip install falsk-redis下面的写法是对项目代码进行模块化拆分的写法&#xff0c;在app.py中只进行对象的初始化等操作&#xff1b;exts.py中创建对象&…...

【Unity基础】Unity中的特殊文件夹详解

在Unity项目中&#xff0c;通常可以根据需要创建任意名称的文件夹来组织项目内容&#xff0c;但有一些特定的文件夹名称会触发Unity对其中资源和脚本的特殊处理。这篇文章将详细介绍这些特殊文件夹&#xff0c;帮助开发者在项目中合理地使用它们。 1. Assets 文件夹 Assets文…...

矩阵蠕虫,陈欣出品

第一章 陈欣是一名资深的软件工程师&#xff0c;专门从事分布式系统和人工智能的研究。她的最新项目叫做“MatrixWorm”&#xff0c;目标是创建一个简单而强大的远程控制系统。在这个系统中&#xff0c;控制端可以通过文字命令&#xff0c;让被控制端利用大语言模型的能力来理…...

python 爬虫 入门 五、抓取图片、视频

目录 一、图片、音频 二、下载视频&#xff1a; 一、图片、音频 抓取图片的手法在上一篇python 爬虫 入门 四、线程&#xff0c;进程&#xff0c;协程-CSDN博客里面其实有&#xff0c;就是文章中的图片部分&#xff0c;在那一篇文章&#xff0c;初始代码的28&#xff0c;29行…...

ubantu 编译安装ceph 18.2.4

下载ceph代码 git clone https://github.com/ceph/ceph.git #切换tag git checkout v18.2.4 -b v18.2.4 #下载子模块 会有报错重新执行即可 git submodule update --init --recursive安装ceph所需要的依赖 #curl命令安装 sudo apt install curl#安装ceph依赖 ./install-deps.…...

哈希封装“unordered_set·map“

本文与对setmap的封装高度相似&#xff0c;可以参考我之前的对setmap封装的文章&#xff1a; 链接&#xff1a;&#xff08;没看过的话就点点我吧&#x1f61a;&#x1f61a;&#x1f61a;&#x1f61a;&#x1f61a;&#x1f61a;&#x1f61a;&#x1f61a;&#x1f61a;&am…...

Bi-LSTM-CRF实现中文命名实体识别工具(TensorFlow)

项目源码获取方式见文章末尾&#xff01; 回复暗号&#xff1a;13&#xff0c;免费获取600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 **《------往期经典推荐------》**项目名称 1.【MobileNetV2实现实时口罩检测tensorflow】 2.【卫星图像道路检测DeepLabV3P…...

手机网站建设推广/杭州关键词排名工具

下面是我最近总结的一点点东西而已&#xff0c;以后还会更多1、.时间linux系统在时间上有比较多的东西。在游戏里&#xff0c;时间是一个非常重要的一个变量&#xff0c;涉及到前后端时间同步&#xff0c;游戏业务的倒计时&#xff0c;心跳等等的一系列功能点等等&#xff0c;如…...

wordpress 视频 主题/适合发软文的平台

新增的结构标签 section元素 表 示页面中的一个内容区块,比如章节、页眉、页脚或页面的其他部分。可以和h1、 h2……等元素结合起来使用&#xff0c;表示文档结构。例&#xff1a;HTML5中<section>……</section>;HTML4 中<div> ……</div>。 article元…...

滁州建设网站/自助建站系统下载

自动发现&#xff1a; 需要&#xff1a;zabbix-server安装完毕&#xff0c;zabbix-agent安装完毕 zabbix网页上的操作&#xff1a; 1.配置自动发现规则-发现主机 注意&#xff1a;这里的延时选项请按实际环境而定 2.配置添加主机动作-添加主机 添加完成后的结果如下 静静的等待…...

建筑设计资料网站/网站seo关键词优化

网络游戏的数据变动比较频繁&#xff0c;如果每次数据变动都刷往后端数据库&#xff0c;会导致数据库不负重荷。在游戏逻辑和数据库间提供一层缓冲服务&#xff0c;有利于减轻这重压力. 首先&#xff0c;网络游戏的数据在数据库中是以表的形式保存的&#xff0c;每个玩家的数据…...

怎样下一本wordpress/品牌搜索引擎服务优化

链表是一种常见的数据结构&#xff0c;它由一个个节点组成&#xff0c;每个节点都有一个数据域和一个指向下一个节点的指针域。链表中的节点并不是连续存储在内存中的&#xff0c;而是存储在稀疏分布的各个位置。 红黑树是一种自平衡二叉查找树&#xff0c;它在保证二叉查找树的…...

中交路桥建设网站/腾讯朋友圈广告怎么投放

分支预测 在stackoverflow上有一个非常有名的问题&#xff1a; 为什么处理有序数组要比非有序数组快&#xff0c;可见分支预测对代码运行效率有非常大的影响。 现代CPU都支持分支预测(branch prediction)和指令流水线(instruction pipeline)&#xff0c;这两个结合可以极大提高…...