You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot+Spring Data JPA实现创建部门时记录创建用户ID

基于Spring Data JPA实现创建部门时记录创建人ID的方案

1. 定义实体与DTO

首先完善Department实体,确保包含CREATE_USER_ID字段;同时创建用于接收请求的DTO,DTO中无需包含创建人ID(该字段由系统自动填充)。

// Department 实体
@Entity
@Table(name = "department")
public class Department {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    // 对应数据库CREATE_USER_ID字段
    @Column(name = "CREATE_USER_ID")
    private Long createUserId;
    
    // 省略getter、setter及其他业务字段
}

// 创建部门请求DTO
public class CreateDepartmentDTO {
    private String name;
    // 省略其他业务字段及getter、setter
}

2. 封装获取当前用户ID的工具方法

从Spring Security上下文获取当前授权用户的ID,封装成工具类便于复用:

public class SecurityUtils {
    public static Long getCurrentUserId() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        // 此处假设自定义UserDetails实现类为CustomUserDetails,包含userId属性
        if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails) {
            CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
            return userDetails.getUserId();
        }
        throw new RuntimeException("未检测到登录用户");
    }
}

注:若使用JWT或其他认证方式,只需调整Principal的转换逻辑,核心是从SecurityContext中提取用户ID。

3. 业务层实现创建逻辑

在部门业务类中,完成DTO到实体的转换,手动设置创建人ID后通过Spring Data JPA保存:

@Service
public class DepartmentService {
    private final DepartmentRepository departmentRepository;

    // 构造器注入(替代@Autowired)
    public DepartmentService(DepartmentRepository departmentRepository) {
        this.departmentRepository = departmentRepository;
    }

    public Department createDepartment(CreateDepartmentDTO dto) {
        Department department = new Department();
        department.setName(dto.getName());
        // 设置创建人ID
        department.setCreateUserId(SecurityUtils.getCurrentUserId());
        // 其他字段赋值
        return departmentRepository.save(department);
    }
}

4. 进阶:用JPA监听器自动填充(通用方案)

如果多个实体都需要记录创建人,可通过JPA的@PrePersist监听器实现自动填充,避免重复代码:

步骤4.1 定义审计接口

public interface CreateUserAuditable {
    void setCreateUserId(Long userId);
}

步骤4.2 让实体实现接口

@Entity
@Table(name = "department")
public class Department implements CreateUserAuditable {
    // 原有字段
    
    @Override
    public void setCreateUserId(Long userId) {
        this.createUserId = userId;
    }
}

步骤4.3 实现监听器

@Component
public class CreateUserAuditListener {
    @PrePersist
    public void fillCreateUserId(CreateUserAuditable auditable) {
        Long userId = SecurityUtils.getCurrentUserId();
        auditable.setCreateUserId(userId);
    }
}

步骤4.4 绑定监听器到实体

@Entity
@Table(name = "department")
@EntityListeners(CreateUserAuditListener.class)
public class Department implements CreateUserAuditable {
    // 原有字段及实现方法
}

配置完成后,业务层无需手动设置createUserId,JPA会在实体持久化前自动调用监听器填充。

5. 控制器接收请求

编写REST接口接收前端请求,调用业务层方法完成创建:

@RestController
@RequestMapping("/departments")
public class DepartmentController {
    private final DepartmentService departmentService;

    public DepartmentController(DepartmentService departmentService) {
        this.departmentService = departmentService;
    }

    @PostMapping
    public ResponseEntity<Department> createDepartment(@RequestBody CreateDepartmentDTO dto) {
        Department created = departmentService.createDepartment(dto);
        return ResponseEntity.ok(created);
    }
}

内容的提问来源于stack exchange,提问作者user20572341

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 22:07:42