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

如何在Spring Data JPA中关联表返回type_name而非type_id

实现步骤

1. 创建EmployeeType实体类

首先为employeetype表创建对应的JPA实体,映射表字段并定义主键:

@Entity
@Table(name = "employeetype")
public class EmployeeType {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "type_name")
    private String typeName;

    // 生成无参、全参构造方法,以及getter/setter
}

2. 修改Employee实体类,建立关联关系

替换原有的typeId字段,用@ManyToOne注解建立与EmployeeType的多对一关联,映射两张表的外键关系:

@Entity
@Table(name = "employee")
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="emp_id")
    private Long id;
    
    @Column(name="emp_name")
    private String empName;
    
    @Column(name="emp_mail")
    private String empMail;
    
    @Column(name="emp_no")
    private String empNo;

    @Column(name="emp_salary")
    private Long empSalary;
    
    // 替换原typeId字段,建立多对一关联
    @ManyToOne(fetch = FetchType.LAZY) // 根据业务需求选择懒加载(LAZY)或急加载(EAGER)
    @JoinColumn(name = "type_id", referencedColumnName = "id")
    private EmployeeType employeeType;

    // 生成getter/setter,通过getEmployeeType()可获取类型对象,进而得到typeName
}

3. 三种方式返回包含type_name的结果

方式一:使用DTO对象映射结果

创建一个DTO类,封装需要返回的字段:

public class EmployeeDTO {
    private Long id;
    private String empName;
    private String empMail;
    private String empNo;
    private Long empSalary;
    private String typeName;

    // 全参构造方法
    public EmployeeDTO(Long id, String empName, String empMail, String empNo, Long empSalary, String typeName) {
        this.id = id;
        this.empName = empName;
        this.empMail = empMail;
        this.empNo = empNo;
        this.empSalary = empSalary;
        this.typeName = typeName;
    }

    // 生成getter方法
}

在JpaRepository中编写JPQL查询,直接构造DTO返回:

public interface EmployeeRepository extends JpaRepository<Employee, Long> {
    @Query("SELECT new com.yourpackage.dto.EmployeeDTO(e.id, e.empName, e.empMail, e.empNo, e.empSalary, et.typeName) " +
           "FROM Employee e JOIN e.employeeType et")
    List<EmployeeDTO> findAllWithTypeName();
}

方式二:使用Spring Data投影(Projection)

创建一个投影接口,定义需要返回的属性方法:

public interface EmployeeProjection {
    Long getId();
    String getEmpName();
    String getEmpMail();
    String getEmpNo();
    Long getEmpSalary();
    // 遵循嵌套属性访问规则:employeeType是Employee的属性,typeName是EmployeeType的属性
    String getEmployeeTypeTypeName();
}

在Repository中直接调用投影查询方法:

public interface EmployeeRepository extends JpaRepository<Employee, Long> {
    List<EmployeeProjection> findAllProjectedBy();
}

方式三:原生SQL查询(不修改实体关联时使用)

如果不想修改原Employee实体的字段,可直接用原生SQL关联查询:

public interface EmployeeRepository extends JpaRepository<Employee, Long> {
    @Query(value = "SELECT e.emp_id AS id, e.emp_name AS empName, e.emp_mail AS empMail, e.emp_no AS empNo, " +
                   "e.emp_salary AS empSalary, et.type_name AS typeName " +
                   "FROM employee e JOIN employeetype et ON e.type_id = et.id", nativeQuery = true)
    List<EmployeeDTO> findAllWithTypeNameNative();
}

注意事项

  • 关联的fetch策略:LAZY懒加载会在首次访问employeeType属性时才执行关联查询,适合不频繁需要类型名称的场景;EAGER急加载会在查询Employee时同时查询关联的EmployeeType,适合每次都需要类型名称的场景,但要注意避免N+1查询问题。
  • DTO方式灵活性更高,适合复杂字段组合;投影方式更简洁,适合简单的字段提取场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 09:15:33