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

MyBatis-Plus 通用 Service 与常用注解

MyBatis-Plus 通用 Service 与常用注解


目录

  • 1 通用 Service
    • 1.1 IService 接口简介
    • 1.2 创建 Service 接口与实现类
    • 1.3 测试通用 Service
      • 1.3.1 查询记录数
      • 1.3.2 批量插入
      • 1.3.3 修改操作
      • 1.3.4 批量删除
  • 2 常用注解
    • 2.1 @TableName —— 表名映射
      • 2.1.1 注解方式
      • 2.1.2 全局配置方式
    • 2.2 @TableId —— 主键映射
      • 2.2.1 value 属性:指定主键字段名
      • 2.2.2 type 属性:指定主键生成策略
      • 2.2.3 雪花算法简介
    • 2.3 @TableField —— 字段映射
    • 2.4 @TableLogic —— 逻辑删除

1 通用 Service

1.1 IService 接口简介

MyBatis-Plus 封装了IService接口,在BaseMapper的 CRUD 基础上做了进一步封装。Service 层的方法采用不同的前缀命名来区分 Mapper 层,避免混淆:

前缀含义示例方法
get查询单行getById()
list查询集合list()
remove删除removeById()removeBatchByIds()
save插入save()saveBatch()
update修改updateById()
count计数count()
page分页查询page()

IService接口由ServiceImpl类实现。如果内置方法无法满足业务需求,可以在自定义的 Service 接口中扩展方法。

1.2 创建 Service 接口与实现类

业务接口:

/** * UserService 继承 IService,获得模板提供的基础功能 */publicinterfaceUserServiceextendsIService<User>{}

业务实现类:

/** * ServiceImpl 实现了 IService,提供了基础功能的实现 * 若 ServiceImpl 无法满足业务需求,可在 UserService 中定义方法,并在此类中实现 */@ServicepublicclassUserServiceImplextendsServiceImpl<UserMapper,User>implementsUserService{}

ServiceImpl<UserMapper, User>的两个泛型参数分别是 Mapper 接口和实体类。

1.3 测试通用 Service

1.3.1 查询记录数
@AutowiredprivateUserServiceuserService;@TestpublicvoidtestGetCount(){longcount=userService.count();System.out.println("总记录数:"+count);}
1.3.2 批量插入
@TestpublicvoidtestSaveBatch(){ArrayList<User>users=newArrayList<>();for(inti=0;i<5;i++){Useruser=newUser();user.setName("abc"+i);user.setAge(20+i);users.add(user);}// SQL: INSERT INTO t_user (username, age) VALUES (?, ?)userService.saveBatch(users);}

saveBatch()会将集合中的数据分批执行插入,是 Service 层相比 Mapper 层额外提供的便利方法。

1.3.3 修改操作
@TestpublicvoidtestUpdate(){Useruser=newUser(1778690964123090947L,"miller",30,"miller@qq.com");// SQL: UPDATE user SET name=?, age=?, email=? WHERE id=?userService.updateById(user);}
1.3.4 批量删除
@TestpublicvoidtestDelete(){List<Long>ids=newArrayList<>();ids.add(1778690963879821313L);ids.add(1778690964114702337L);ids.add(1778690964114702338L);ids.add(1778690964123090946L);ids.add(1778690964123090947L);// SQL: DELETE FROM user WHERE id IN (?, ?, ?, ?, ?)userService.removeBatchByIds(ids);}

2 常用注解

MyBatis-Plus 提供了一系列注解,用于处理实体类与数据库表之间的映射关系。核心注解汇总如下:

注解作用位置功能
@TableName指定实体类对应的表名
@TableId主键字段指定主键字段名及主键生成策略
@TableField普通字段指定实体属性对应的表字段名
@TableLogic逻辑删除字段标记该字段为逻辑删除标志位

2.1 @TableName —— 表名映射

MyBatis-Plus 默认将实体类的类名作为表名。当实体类名与表名不一致时(例如实体类为User,表名为tb_user),查询会报错:

Table 'mybatis_plus.user' doesn't exist

有两种解决方式。

2.1.1 注解方式

在实体类上添加@TableName注解,指定对应的表名:

@Data@NoArgsConstructor@AllArgsConstructor@TableName("tb_user")publicclassUser{privateLongid;privateStringname;privateIntegerage;privateStringemail;}
2.1.2 全局配置方式

如果所有表都有统一前缀(如tb_),可以在application.yml中全局配置,无需逐个添加注解:

mybatis-plus:global-config:db-config:table-prefix:tb_

2.2 @TableId —— 主键映射

MyBatis-Plus 默认将名为id的字段作为主键。当主键字段名不是id(例如为uid)时,需要使用@TableId注解手动指定。

2.2.1 value 属性:指定主键字段名

当实体属性名与数据库主键字段名不一致时,通过value属性指定数据库中的字段名:

@Data@NoArgsConstructor@AllArgsConstructorpublicclassUser{@TableId(value="uid")// 实体属性为 id,数据库字段为 uidprivateLongid;privateStringname;privateIntegerage;privateStringemail;}
2.2.2 type 属性:指定主键生成策略

type属性用于指定主键的生成策略。MyBatis-Plus 通过IdType枚举类定义了以下策略:

IdType 值描述
AUTO数据库 ID 自增。前提:表中主键字段必须设置为自增,否则插入时会报错
NONE无状态,未设置主键类型。等同于跟随全局配置,全局默认为ASSIGN_ID
INPUT插入前由用户自行设置主键值
ASSIGN_ID自动分配 ID,适用于LongIntegerString类型。默认策略,使用雪花算法
ASSIGN_UUID自动分配 UUID,适用于String类型

使用自增策略的示例:

@Data@NoArgsConstructor@AllArgsConstructorpublicclassUser{@TableId(value="uid",type=IdType.AUTO)privateLongid;privateStringname;privateIntegerage;privateStringemail;}

也可以在application.yml中全局配置主键策略:

mybatis-plus:global-config:db-config:table-prefix:tb_id-type:auto

IdType枚举源码如下:

publicenumIdType{AUTO(0),NONE(1),INPUT(2),ASSIGN_ID(3),ASSIGN_UUID(4);}
2.2.3 雪花算法简介

雪花算法(Snowflake)是 Twitter 开源的分布式主键生成算法,能够保证不同表的主键不重复,且同一表的主键按时间有序。

产生背景:随着数据量增长,单表可能需要进行水平分表。分表后需要一种全局唯一的 ID 生成方案,常见方案有三种:

方案原理优点缺点
主键自增分段按固定范围分配 ID 段,如 1~999999 放表1,1000000~1999999 放表2可平滑扩充新表,原有数据不受影响数据分布可能不均匀
取模ID % 表数量决定数据归属数据分布均匀扩充新表时所有数据需要重新分布
雪花算法64 bit 组合:符号位(1) + 时间戳(41) + 机器ID(10) + 序列号(12)按时间有序,分布式环境无 ID 碰撞,效率高依赖机器时钟

雪花算法 ID 结构(64 bit):

  • 1 bit:符号位,固定为 0(正数)
  • 41 bit:时间戳(毫秒级),存储当前时间与起始时间的差值,约可使用 69.73 年
  • 10 bit:机器 ID(5 bit 数据中心 + 5 bit 机器 ID),支持 1024 个节点
  • 12 bit:序列号,每个节点每毫秒可生成 4096 个 ID

2.3 @TableField —— 字段映射

MyBatis-Plus 要求实体类属性名与表字段名能对应上。存在两种情况:

情况一:驼峰命名 ↔ 下划线命名(自动转换)

实体类属性使用驼峰命名(如userName),表字段使用下划线命名(如user_name)时,MyBatis-Plus会自动转换,无需额外配置。

@Data@NoArgsConstructor@AllArgsConstructorpublicclassUser{@TableId(value="uid")privateLongid;privateStringuserName;// 自动映射到表字段 user_nameprivateIntegerage;privateStringemail;}

情况二:属性名与字段名完全不一致(需手动映射)

当属性名与字段名不满足驼峰/下划线转换规则时(如属性为userName,字段为name),需要使用@TableField注解手动指定:

@Data@NoArgsConstructor@AllArgsConstructorpublicclassUser{@TableId(value="uid")privateLongid;@TableField("name")// 手动映射:属性 userName → 字段 nameprivateStringuserName;privateIntegerage;privateStringemail;}

2.4 @TableLogic —— 逻辑删除

数据删除有两种方式:

删除方式说明
物理删除执行DELETE语句,数据从数据库中真实移除,不可恢复
逻辑删除执行UPDATE语句,将删除标志字段修改为"已删除"状态,数据仍保留在表中

使用@TableLogic注解实现逻辑删除的步骤如下:

第一步:在数据表中添加逻辑删除字段

添加is_deleted字段,默认值为 0(0 表示未删除,1 表示已删除):

ALTERTABLEtb_userADDCOLUMNis_deletedINTDEFAULT0;

第二步:在实体类中添加对应属性并标注注解

@Data@NoArgsConstructor@AllArgsConstructorpublicclassUser{@TableId(value="uid")privateLongid;@TableField("name")privateStringuserName;privateIntegerage;privateStringemail;@TableLogic// 标记为逻辑删除字段privateIntegerisDeleted;}

第三步:测试逻辑删除

@TestpublicvoidtestDeleteById(){intresult=userMapper.deleteById(7L);System.out.println("受影响行数:"+result);}

添加@TableLogic注解后,调用deleteById()等删除方法时,MyBatis-Plus 实际执行的 SQL 会从:

-- 物理删除DELETEFROMtb_userWHEREuid=?

变为:

-- 逻辑删除UPDATEtb_userSETis_deleted=1WHEREuid=?ANDis_deleted=0

同时,后续的查询操作会自动在 WHERE 条件中追加AND is_deleted = 0,自动过滤已逻辑删除的数据。

http://www.cnnetsun.cn/news/3026177.html

相关文章:

  • 【数据库系统原理】第35篇:自主访问控制与强制访问控制:权限传递与安全标记
  • 用Matlab进行无线电信号逆向实战2——立体声 FM 广播的分离与解密 从频谱迷宫到相干解调的避坑指南
  • 数据分析转大模型:从工具接入到项目提效
  • OWTB 3PL 智慧仓储管理系统 - AI员工增强版工种清单
  • 滑动文本控件样例工程以及使用详解
  • 2026年下半年量化工具怎么选,先匹配能力基础
  • Vatee:用框架方式看外汇市场服务体验,更容易形成稳定判断
  • 房产销售做客户介绍总冷场?掌握AI优化项目卖点表达,构建高转化销冠工作流
  • 2026年小策略练习,帮零基础看见量化流程
  • 常用面试题
  • 2026年超耐磨TPU厂家口碑排行情况大揭秘
  • 放大50倍看二手劳力士女款满天星,这组机芯加工公差才是底牌
  • 如何批量删除edge同步到微软账户中的密码
  • 希尔排序算法
  • 二维码签到系统
  • 40岁重新学工具,AI给了我第二次职业选择
  • 视频孪生全域穿透 营区物理空间动态数字映射综合平台
  • JVM篇-JVM主要组成部分
  • 2026打工人必看:这些看似正常的文件,可能是木马的入口
  • 在POSIX线程中正确处理无参数函数
  • 我终于知道,Codex 为什么需要一块无限画布了
  • CSS Flexbox布局的精妙应用
  • 解决django.db.utils.OperationalError: attempt to write a readonly database错误
  • 如何快速上手SDR++:跨平台软件定义无线电的终极解决方案
  • 《多级标签并行筛选》一、Flex弹性布局使用指南
  • 全栈 API 设计与 GraphQL 实践:从 N+1 查询到 DataLoader 优化的工程化方案
  • 数据结构(六)
  • Loop 工程:从 prompter 到 loop 设计师 [翻译]
  • 2026命理软件做批量检索怎么选?八字排盘App要看标签体系和条件筛选
  • Windows热键神秘失踪案:Hotkey Detective一键破案的神奇体验