news 2025/12/20 6:08:20

Mybatis-Plus进阶Druid数据源

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Mybatis-Plus进阶Druid数据源

MyBatis-Plus 插件

MyBatis-Plus(简称 MP)是基于 MyBatis 的增强工具,在保留原生功能的基础上,提供了简化开发、自动 CRUD、分页、代码生成等特性。以下从核心功能、插件模块及使用示例展开说明。


核心功能

代码生成器
通过AutoGenerator可快速生成 Entity、Mapper、Service、Controller 层代码,支持自定义模板。

条件构造器
提供QueryWrapperUpdateWrapper,通过链式调用构建动态 SQL 条件,无需手动拼接 SQL。

分页插件
内置PaginationInnerInterceptor,支持多种数据库分页逻辑,与Page对象配合实现物理分页。

乐观锁插件
通过@Version注解标记版本号字段,自动实现乐观锁控制。

性能分析插件
PerformanceInterceptor可输出 SQL 执行时间,帮助优化慢查询。


常用插件配置示例

分页插件配置

在 Spring Boot 中配置分页插件:

@Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }
代码生成器示例
AutoGenerator generator = new AutoGenerator(); generator.setDataSource(new DataSourceConfig() .setUrl("jdbc:mysql://localhost:3306/test") .setUsername("root") .setPassword("123456")); StrategyConfig strategy = new StrategyConfig() .setInclude("user", "order") // 指定生成表 .setEntityLombokModel(true); // 使用 Lombok generator.setStrategy(strategy); generator.execute();

动态表名插件

适用于分库分表场景,通过实现TableNameHandler动态解析表名:

public class DynamicTableNameParser implements TableNameHandler { @Override public String dynamicTableName(String sql, String tableName) { return tableName + "_2023"; // 动态拼接表名 } }

注意事项
  • 避免在 Wrapper 中直接拼接用户输入,防止 SQL 注入。
  • 分页插件需依赖数据库方言(如DbType.MYSQL)。
  • 乐观锁字段需为数值类型,且更新时自动递增版本号。

通过合理使用插件,可显著减少样板代码,提升开发效率。

mybatis-Plus扩展功能

逻辑删除

逻辑删除是一种软删除方式,通过标记字段(如is_deleted)的状态区分数据是否被删除,而非物理删除数据库记录。MyBatis-Plus提供了内置支持,简化逻辑删除的实现。

配置逻辑删除字段

在实体类中标记逻辑删除字段,使用@TableLogic注解:

@Data public class User { private Long id; private String name; @TableLogic private Integer isDeleted; // 1表示删除,0表示未删除 }
全局配置(可选)

application.yml中配置逻辑删除的默认值,避免在每个实体类中重复定义:

mybatis-plus: global-config: db-config: logic-delete-field: isDeleted # 全局逻辑删除字段名 logic-not-delete-value: 0 # 未删除时的值 logic-delete-value: 1 # 删除时的值
自动过滤逻辑删除数据

MyBatis-Plus会在查询时自动过滤标记为已删除的数据,无需手动添加条件。例如:

userMapper.selectList(null); // 自动生成SQL: WHERE is_deleted = 0
手动调用删除方法

使用deleteByIddelete方法会触发逻辑删除:

userMapper.deleteById(1L); // 执行UPDATE语句,设置is_deleted = 1
查询包含已删除数据

若需查询包含逻辑删除的数据,需自定义SQL或使用条件构造器忽略逻辑删除字段:

QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.isNull("is_deleted").or().eq("is_deleted", 1); userMapper.selectList(wrapper);
注意事项
  • 数据库表需存在逻辑删除字段(如is_deleted)。
  • 逻辑删除与唯一索引冲突时,需调整业务逻辑或索引设计。
  • 关联查询时需手动处理逻辑删除条件。

通过上述配置,MyBatis-Plus可无缝集成逻辑删除功能,减少冗余代码。

自动填充功能

MyBatis-Plus的自动填充功能用于在数据库操作时自动填充字段值,例如创建时间、更新时间、操作人等。通过实现MetaObjectHandler接口,可以自定义填充逻辑。

实现自动填充的步骤
定义填充字段注解

在实体类字段上使用@TableField注解标记自动填充行为,例如:

@TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime;
  • FieldFill.INSERT:仅在插入时填充
  • FieldFill.UPDATE:仅在更新时填充
  • FieldFill.INSERT_UPDATE:插入和更新时均填充
实现MetaObjectHandler接口

创建类实现MetaObjectHandler,重写insertFillupdateFill方法:

@Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); } @Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); } }
  • strictInsertFill/strictUpdateFill:严格模式填充,要求字段类型匹配
  • 非严格模式可使用setFieldValByName方法
注意事项
  1. 字段类型需与填充值类型一致,否则会抛出异常。
  2. 填充字段需在数据库中存在,且为非主键字段。
  3. 若填充逻辑依赖其他服务(如获取当前用户),可通过Spring上下文注入依赖。
高级用法
动态填充

通过MetaObject获取当前操作数据,实现条件填充:

@Override public void insertFill(MetaObject metaObject) { Object status = metaObject.getValue("status"); if ("draft".equals(status)) { this.setFieldValByName("publishTime", null, metaObject); } else { this.setFieldValByName("publishTime", LocalDateTime.now(), metaObject); } }
多数据源适配

在多数据源场景下,需确保MetaObjectHandler实现类被所有数据源识别,通常将其声明为Spring Bean即可自动生效。

常见问题解决
  • 填充不生效:检查字段注解fill值是否与操作类型匹配,或是否漏注@Component
  • 类型不匹配错误:使用strictFill方法时,确认填充值与字段类型一致。
  • 覆盖问题:手动设置的字段值会优先于自动填充值。

SpringBoot集成Druid数据源

Druid 概述

Druid 是一个开源的分布式实时数据分析系统,专为快速查询和实时摄入大规模数据而设计。它结合了数据仓库、时序数据库和搜索系统的特性,适用于高性能的 OLAP(在线分析处理)场景。

核心特性

  • 实时与批量摄入:支持从 Kafka 等流式数据源实时摄入数据,也支持批量导入历史数据。
  • 列式存储:数据按列存储,优化聚合和扫描性能。
  • 分布式架构:通过横向扩展处理 PB 级数据,支持高可用和容错。
  • 时间分区:数据按时间分片,便于高效查询和时间范围过滤。
  • 近似计算:提供 HyperLogLog 等算法,支持快速去重和近似计算。

适用场景

  • 实时监控与日志分析
  • 用户行为分析
  • 广告技术(AdTech)中的点击流分析
  • IoT 设备数据时序分析

架构组件

  • Coordinator:管理数据分片的分布和负载均衡。
  • Overlord:控制数据摄入任务的分配。
  • Broker:接收查询请求并路由到数据节点。
  • Historical:存储和提供历史数据查询。
  • MiddleManager:处理实时数据摄入。

查询能力

  • 支持 SQL 和原生 JSON 查询。
  • 提供聚合、过滤、分组、排序等操作。
  • 低延迟响应,适用于交互式分析。

与其他工具的对比

  • 对比 Elasticsearch:Druid 更擅长聚合分析,Elasticsearch 侧重全文检索。
  • 对比 Hadoop:Druid 提供亚秒级查询,Hadoop 更适合离线批处理。

部署方式

  • 可独立部署或集成 Kubernetes 等容器化平台。
  • 社区版开源,企业版提供额外功能和支持。

Druid 的官方文档和社区资源丰富,适合需要高性能实时分析的企业级应用。

依赖

<dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-3-starter</artifactId> <version>1.2.23</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>

application.yml相关配置

# 服务器配置(核心修正:端口key) server: port: 8080 servlet: context-path: / # 上下文路径(默认/,可省略) # Spring 核心配置 spring: application: name: mybatis-xml # 数据源配置(Druid) datasource: type: com.alibaba.druid.pool.DruidDataSource druid: # 数据库连接信息(适配MySQL 8.x) url: jdbc:mysql://localhost:3306/text_book_db?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver # 连接池核心参数 initial-size: 5 min-idle: 5 max-active: 20 max-wait: 60000 time-between-eviction-runs-millis: 60000 min-evictable-idle-time-millis: 300000 validation-query: SELECT 1 FROM DUAL test-while-idle: true test-on-borrow: false test-on-return: false # PreparedStatement 缓存 pool-prepared-statements: true max-pool-prepared-statement-per-connection-size: 20 # 过滤器(stat=SQL监控,wall=防注入,slf4j=日志) filters: stat,wall,slf4j # 修正:connection-properties 改用行内写法,避免解析失败 connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000;druid.stat.logSlowSql=true # Druid 监控页面配置 stat-view-servlet: enabled: true url-pattern: /druid/* login-username: admin login-password: admin123 reset-enable: false allow: 127.0.0.1 # 仅允许本地访问(生产按需扩展) deny: 192.168.1.100 # Web 请求监控过滤器 web-stat-filter: enabled: true url-pattern: /* exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" session-stat-enable: true session-stat-max-count: 1000 principal-session-name: loginUser principal-cookie-name: loginUser # MyBatis-Plus 配置(适配XML开发) mybatis-plus: type-aliases-package: com.ktjy.crm.entity mapper-locations: classpath:generator/mapper/**/*.xml # 确保XML文件在该路径下 configuration: map-underscore-to-camel-case: true # 下划线转驼峰(必须开) cache-enabled: false call-setters-on-nulls: true # 空值字段返回(前端不缺字段) log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl # 打印SQL到日志 global-config: db-config: # 关键修正:根据数据库主键策略调整(二选一) # 若主键自增(AUTO_INCREMENT),用这个: id-type: auto # 若主键是雪花算法(手动生成),用这个: # id-type: assign_id update-strategy: not_null logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0 # 日志配置(打印SQL和Druid日志) logging: level: root: WARN com.ktjy.crm.mapper: DEBUG # 打印Mapper执行的SQL(关键调试) com.alibaba.druid: INFO # Druid监控日志 com.baomidou.mybatisplus: INFO # MyBatis-Plus日志 pattern: console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n"
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2025/12/16 18:46:07

HC32F460 DMA的链式传输(SPI从机+DMA发送/接收)

1、SPI从机DMA接收SPI从机的接收机制与串口接收类似&#xff08;参考前面文章&#xff09;&#xff0c;在使用DMA进行数据接收时&#xff0c;其配置方式也较为相似&#xff0c;因此不再重复说明DMA的具体配置过程。由于SPI外设本身不提供接收超时中断机制&#xff0c;因此无法依…

作者头像 李华
网站建设 2025/12/19 9:44:09

Zynq MPSoC 调试实录:AXI 寄存器地址重叠与 Vitis Bitstream 版本陷阱

1. 问题背景 在调试 Zynq MPSoC 的视频通路时,遇到一个诡异的现象:无法配置 v_frmbuf_wr (Video Frame Buffer Write) IP 核的 Width (0x10) 和 Height (0x18) 寄存器。 故障表现: 软件写入 Width = 800 (0x320)。 软件回读 Width,得到的值却是 0x00 或者与 Control 寄存…

作者头像 李华
网站建设 2025/12/16 18:44:41

爱舞功小程序+SaaS管理系统项目平台介绍说明书

爱舞功小程序SaaS管理系统项目平台介绍说明书一: 项目背景及简介随着舞蹈行业的发展&#xff0c;舞蹈机构在日常运营中面临着会员管理、课堂预约、数据统计、营销获客等多方面的挑战。传统的管理方式效率低下&#xff0c;难以满足机构高效盈利的需求。爱舞功项目应运而生&#…

作者头像 李华
网站建设 2025/12/16 18:44:06

一文搞懂AI大语言模型工作原理,初中生都能看懂

01 神经网络1&#xff0c;神经元&#xff1a;神经网络的最小单元神经网络的灵感来源于人类大脑的神经元&#xff0c;每个神经元就像一棵 “小树”&#xff0c;树突接收其它神经元的信号&#xff0c;细胞体处理信号&#xff0c;轴突把处理后的信号传给下一个神经元。生物神经元示…

作者头像 李华
网站建设 2025/12/16 18:43:35

3.2IT审计

1、IT审计范围的确定&#xff1a;总体范围、组织范围、物理范围、逻辑范围、其他相关内容 2、IT审计风险主要包括&#xff1a;固有风险、控制风险、检查风险和总体审计风险。 3、常用审计方法包括&#xff1a;访谈法、调查法、检查法、观察法、测试法、程序代码检查法 4、常用的…

作者头像 李华