后端常用注解
# MyBatis Plus # EasyExcel # Lombok
# MyBatis Plus注解
## 核心注解
-
@TableName
-
作用:标识实体类对应的数据库表名(当类名与表名不一致时使用)。
-
在实体类entity文件中的示例:
@TableName("sys_user") // 指定表名为 sys_user public class User { ... }
-
-
@TableId
-
作用:标识主键字段,可指定主键类型(自增、UUID等)。
-
属性:
-
value
:数据库主键列名(默认匹配字段名)。 -
type
:主键生成策略(如IdType.AUTO
自增)。
-
-
在实体类entity文件中的示例:
public class User {@TableId(value = "id", type = IdType.AUTO)private Long userId; // 映射到表字段 id }
-
-
@TableField
-
作用:标识非主键字段与数据库列的映射关系。
-
常用属性:
-
value
:数据库列名(默认匹配字段名)。 -
exist
:是否为数据库字段(默认true
,若为false
表示非表字段)。 -
fill
:字段自动填充策略(如插入时填充FieldFill.INSERT
)。
-
-
示例:
public class User {@TableField("user_name") // 映射到表字段 user_nameprivate String name;@TableField(exist = false) // 非表字段private String remark; }
-
## 查询条件注解
-
条件构造器注解
-
通过
@TableField
的condition
属性动态生成 SQL 条件:public class User {@TableField(condition = SqlCondition.LIKE)private String name; // 查询时自动生成 LIKE 条件 }
-
使用示例:
QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.lambda().like(User::getName, "Tom"); // 生成 SQL: WHERE name LIKE '%Tom%'
-
## 高级功能注解
-
@Version
-
作用:乐观锁注解(确保更新操作时数据未被修改)。
-
示例:
public class User {@Versionprivate Integer version; // 版本号字段 }
-
-
@TableLogic
-
作用:逻辑删除注解(标记记录为“已删除”而非物理删除)。
-
配置(在
application.yml
中):mybatis-plus:global-config:db-config:logic-delete-field: deleted # 全局逻辑删除字段名logic-delete-value: 1 # 删除值logic-not-delete-value: 0 # 未删除值
-
实体类示例:
public class User {@TableLogicprivate Integer deleted; // 逻辑删除字段 }
-
## 自动填充注解
-
@TableField(fill = ...)
-
作用:定义字段自动填充策略(如创建时间、更新时间)。
-
填充策略:
-
FieldFill.INSERT
:插入时填充。 -
FieldFill.UPDATE
:更新时填充。 -
FieldFill.INSERT_UPDATE
:插入和更新时填充。
-
-
示例:
public class User {@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime; }
-
实现
MetaObjectHandler
:@Component public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);}@Overridepublic void updateFill(MetaObject metaObject) {this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);} }
-
## 其他注解
-
@OrderBy
-
作用:指定查询结果的排序方式(优先级高于 Wrapper 中的排序)。
-
示例:
@OrderBy(sort = Priority.DESC, value = "create_time") public class User { ... }
-
-
@InterceptorIgnore
-
作用:忽略插件拦截(如分页插件、租户插件)。
-
示例:
@InterceptorIgnore(tenantLine = "true") // 忽略多租户拦截 public interface UserMapper extends BaseMapper<User> { ... }
-
# EasyExcel注解
专用于 Excel 文件的读写映射。
## 核心注解一览
注解 | 作用 | 示例 |
---|---|---|
| 字段与 Excel 列的映射关系 |
|
| 忽略字段(不参与读写) |
|
| 日期格式转换 |
|
| 数字格式转换 |
|
| 设置列宽度(字符数) |
|
| 设置内容行高(磅值) |
|
| 设置表头行高(磅值) |
|
| 设置单元格内容样式 |
|
| 设置表头样式 |
|
| 忽略未标注注解的字段(类级别) |
|
## 详细注解说明
1. @ExcelProperty
- 字段与 Excel 列的映射关系 -超级常用
public class User {// 基础用法:映射列名@ExcelProperty("姓名")private String name;// 多级表头(支持数组)@ExcelProperty({"部门", "员工信息", "工号"})private String employeeId;// 按索引绑定(优先级高于列名)@ExcelProperty(index = 2) // 绑定第3列(索引从0开始)private Integer age;// 自定义转换器@ExcelProperty(value = "状态", converter = StatusConverter.class)private Integer status;
}
2. @ExcelIgnore
- 忽略字段
@ExcelProperty("邮箱")
private String email;@ExcelIgnore // 该字段不会出现在Excel中
private String internalCode;
3. 日期/数字格式化
// 日期格式化
@DateTimeFormat("yyyy/MM/dd HH:mm")
private Date hireDate;// 数字格式化(保留两位小数)
@NumberFormat("#.##")
private BigDecimal salary;
4. 样式控制注解
// 列宽设置(单位:字符)
@ColumnWidth(15)
@ExcelProperty("地址")
private String address;// 行高设置(类级别)
@HeadRowHeight(40) // 表头行高
@ContentRowHeight(20) // 内容行高
public class User { ... }
5. 高级样式控制
// 表头样式(蓝色背景+白色粗体)
@HeadStyle(fillForegroundColor = 40, // 蓝色fillPatternType = FillPatternType.SOLID_FOREGROUND,fontName = "微软雅黑",fontSize = 12,bold = true,fgColor = IndexedColors.WHITE.getIndex()
)
@ExcelProperty("部门")
private String department;// 内容样式(居中对齐)
@ContentStyle(horizontalAlignment = HorizontalAlignment.CENTER,verticalAlignment = VerticalAlignment.CENTER
)
@ExcelProperty("绩效评分")
private Double score;
完整使用示例
@Data // Lombok注解
@HeadRowHeight(25) // 表头行高
@ContentRowHeight(15) // 内容行高
@ExcelIgnoreUnannotated // 忽略未注解字段
public class Employee {@ExcelProperty(value = "员工ID", index = 0) // 字段映射@ColumnWidth(10) // 列宽private Long id;@ExcelProperty({"基本信息", "姓名"})@ColumnWidth(20)@HeadStyle(fillForegroundColor = 42) // 浅绿色表头private String name;@ExcelProperty({"基本信息", "年龄"})@ContentStyle(horizontalAlignment = HorizontalAlignment.CENTER)private Integer age;@ExcelProperty("入职日期")@DateTimeFormat("yyyy-MM-dd")private Date joinDate;@ExcelProperty("月薪")@NumberFormat("¥#,##0.00")private BigDecimal salary;@ExcelIgnoreprivate String secretToken; // 不导出
}
## 读写操作示例
1. 写入 Excel:EasyExcel.write
List<Employee> list = getEmployees();
String fileName = "员工数据.xlsx";// 写入文件(自动关闭流)
EasyExcel.write(fileName, Employee.class).sheet("员工列表").doWrite(list);
2. 读取 Excel :EasyExcel.read
List<Employee> result = EasyExcel.read(fileName, Employee.class, null).sheet().doReadSync();
## 常见问题解决
-
中文乱码问题
添加响应头(Web导出):
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
-
大数据量内存溢出
使用分页查询 + 异步导出:
// 分页读取数据库 PageHelper.startPage(page, pageSize); List<Employee> data = employeeMapper.selectList();// 异步写入(使用SXSSF模式) ExcelWriter writer = EasyExcel.write(fileName).build(); WriteSheet sheet = EasyExcel.writerSheet().head(Employee.class).build(); writer.write(data, sheet); writer.finish();
-
自定义表头样式
实现
WriteHandler
接口:public class CustomHeaderHandler implements WriteHandler {@Overridepublic void afterCellCreate(WriteSheetHolder holder, WriteTableHolder tableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {if (isHead) {CellStyle style = holder.getSheet().getWorkbook().createCellStyle();style.setFillForegroundColor(IndexedColors.GOLD.getIndex());cell.setCellStyle(style);}} }
## 最佳实践
-
复杂表头:使用数组形式的多级表头
@ExcelProperty({"2023年", "Q1季度", "销售额"}) private BigDecimal q1Sales;
-
动态列:配合
List<Object>
实现动态表头List<List<String>> head = Arrays.asList(Arrays.asList("主要信息", "姓名"),Arrays.asList("主要信息", "年龄"),Arrays.asList("财务信息", "薪资") );
-
混合注解:结合样式和格式注解
@ExcelProperty("奖金") @NumberFormat("#,##0.00") @ContentStyle(fillForegroundColor = 42) private BigDecimal bonus;
# Lombok 常用注解
🔧 核心开发注解
-
@Getter
/@Setter
-
自动生成字段的 getter/setter 方法
-
可单独用于类或字段
-
-
@ToString
-
生成
toString()
方法 -
支持
exclude
排除字段,callSuper
包含父类
-
-
@EqualsAndHashCode
-
生成
equals()
和hashCode()
方法 -
需配合
callSuper=true
处理继承关系
-
-
构造器注解
-
@NoArgsConstructor
:无参构造器 -
@AllArgsConstructor
:全字段构造器 -
@RequiredArgsConstructor
:final/@NonNull 字段构造器
-
🧩 组合注解
-
@Data
-
全能 POJO 注解 =
@Getter
+@Setter
+@ToString
+@EqualsAndHashCode
+@RequiredArgsConstructor
-
-
@Value
-
不可变对象注解 =
final
字段 +@Getter
+@ToString
+@EqualsAndHashCode
+@AllArgsConstructor
-
⚙️ 实用工具注解
-
@Builder
-
生成流畅的构建器模式
User.builder().name("Tom").build();
-
-
@SneakyThrows
-
静默抛出受检异常(无需声明 throws)
@SneakyThrows public void readFile() { ... }
-
-
@NonNull
-
用于明确标记某个变量、方法参数、返回值或字段不允许为
null
public User(@NonNull String name) { ... }
-
-
@Cleanup
-
用于自动管理资源释放(如关闭文件流、数据库连接等)。它通过简化 try-finally或 try-with-resources代码块,减少模板代码,避免资源泄漏风险。
核心作用
@Cleanup InputStream in = new FileInputStream("file.txt"); // 未使用 @Cleanup(手动管理资源): InputStream input = new FileInputStream("file.txt"); try {// 使用 input 读取数据 } finally {if (input != null) {input.close(); // 需手动关闭} }
-
📝 日志注解
-
日志系列(最常用):自动生成日志记录器
-
@Slf4j
:SLF4J 日志 -
@Log4j2
:Log4j2 日志 -
@CommonsLog
:Apache Commons 日志
@Slf4j public class Service {void run() {log.info("Running...");log.trace("Detailed debug message"); // 最细粒度日志log.debug("Debug information");log.warn("Potential issue detected");log.error("Critical error occurred");log.info("User created: {}", userId); // 参数化日志} }
-
⚠️ 实验性注解(谨慎使用)
-
@With
-
为不可变对象生成克隆方法
User newUser = user.withName("Updated");
-
-
@Accessors
-
定制 getter/setter 行为
@Accessors(fluent = true) // 生成 name() 代替 getName()
-
📌 关键注意事项
-
继承处理:
@Data @EqualsAndHashCode(callSuper = true) // 必须显式声明 @ToString(callSuper = true) public class Child extends Parent { ... }
-
构造器冲突:
@Data
不生成无参构造,需配合@NoArgsConstructor
-
不可变对象:
优先用
@Value
替代@Data
保证线程安全
💎 精简总结表
场景 | 推荐注解 |
---|---|
标准 POJO/DTO |
|
不可变对象 |
|
链式构建 |
|
资源自动关闭 |
|
日志记录 |
|
静默抛出异常 |
|
空值检查 |
|
工具类(静态方法) |
|
注:所有注解均需配合 Lombok 依赖和 IDE 插件使用