5.8 KiB
5.8 KiB
OpenHIS 系统审计字段填充最佳实践
概述
本文档介绍如何在 OpenHIS 系统中确保所有实体的审计字段(create_by、create_time、update_by、update_time)能够正确自动填充。
自动填充机制
1. 基础实体类
所有需要审计字段的实体类都应该继承自 HisBaseEntity:
import com.core.common.core.domain.HisBaseEntity;
@Data
@TableName("adm_practitioner")
public class Practitioner extends HisBaseEntity {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
// 其他业务字段...
}
2. 自动填充处理器
系统使用 MybastisColumnsHandler 来自动填充审计字段:
@Component
public class MybastisColumnsHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
// 填充创建时间和创建人
this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
this.strictInsertFill(metaObject, "create_time", Date.class, new Date());
String username = getCurrentUsername(); // 获取当前用户名
this.strictInsertFill(metaObject, "createBy", String.class, username);
this.strictInsertFill(metaObject, "create_by", String.class, username);
}
@Override
public void updateFill(MetaObject metaObject) {
// 填充更新时间和更新人
this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
this.strictUpdateFill(metaObject, "update_time", Date.class, new Date());
String username = getCurrentUsername(); // 获取当前用户名
this.strictUpdateFill(metaObject, "updateBy", String.class, username);
this.strictUpdateFill(metaObject, "update_by", String.class, username);
}
private String getCurrentUsername() {
String username = "system";
try {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null) {
username = loginUser.getUsername();
}
} catch (Exception ignored) {
}
return username;
}
}
确保自动填充正常工作的要点
1. 检查实体类继承关系
确保所有实体类都正确继承了 HisBaseEntity:
// 正确的做法
public class Practitioner extends HisBaseEntity { ... }
// 如果不能继承 HisBaseEntity,则需要手动添加审计字段
public class CustomEntity {
@TableField(fill = FieldFill.INSERT)
private String createBy;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.UPDATE)
private String updateBy;
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;
}
2. 验证安全上下文
确保在执行数据库操作时有有效的安全上下文:
@Service
public class PractitionerService {
public void savePractitioner(Practitioner practitioner) {
// 确保调用此方法时用户已登录
// SecurityUtils.getLoginUser() 应该能返回有效的 LoginUser 对象
// MyBatis-Plus 会在保存时自动调用 MybastisColumnsHandler
practitionerMapper.insert(practitioner);
}
}
3. 检查配置
确保自动填充处理器被正确配置:
# application.yml
mybatis-plus:
global-config:
db-config:
# 其他配置...
configuration:
# 其他配置...
4. 手动填充(特殊情况)
在某些特殊情况下,如果自动填充不工作,可以手动设置:
@Service
public class PractitionerService {
public void savePractitionerManually(Practitioner practitioner) {
// 手动设置审计字段
Date now = new Date();
String currentUser = getCurrentUsername();
practitioner.setCreateTime(now);
practitioner.setCreateBy(currentUser);
practitioner.setUpdateTime(now);
practitioner.setUpdateBy(currentUser);
practitionerMapper.insert(practitioner);
}
}
常见问题及解决方案
问题1:自动填充不生效
原因:
- 实体类没有继承
HisBaseEntity MybastisColumnsHandler没有被Spring管理(缺少@Component注解)- 没有有效的安全上下文
解决方案:
- 确保实体类继承
HisBaseEntity - 检查
MybastisColumnsHandler是否有@Component注解 - 确保在调用保存方法时用户已登录
问题2:获取不到当前用户
原因:
- 用户未登录
- 安全上下文配置错误
解决方案:
- 在调用保存方法前确保用户已登录
- 检查安全配置是否正确
问题3:批量操作时审计字段未填充
原因:
- 批量操作可能绕过了自动填充机制
解决方案:
- 对于批量操作,手动设置审计字段
- 或者使用 MyBatis-Plus 的批量操作方法,确保它们支持自动填充
测试验证
创建一个简单的测试来验证自动填充是否正常工作:
@SpringBootTest
public class AuditFieldTest {
@Autowired
private PractitionerMapper practitionerMapper;
@Test
public void testAuditFieldsAutoFill() {
Practitioner practitioner = new Practitioner();
practitioner.setName("Test Practitioner");
// 保存实体
practitionerMapper.insert(practitioner);
// 验证审计字段是否被正确填充
assertThat(practitioner.getCreateBy()).isNotNull();
assertThat(practitioner.getCreateTime()).isNotNull();
// 清理测试数据
practitionerMapper.deleteById(practitioner.getId());
}
}
总结
通过遵循以上最佳实践,可以确保 OpenHIS 系统中的所有实体在保存时都能正确填充审计字段,避免因缺少这些字段而引发的数据库约束错误。