如何在Spring Boot中通过JPA执行MySQL自定义查询获取指定列?
嘿,这个问题我很熟!在JPA里实现只返回指定列的查询有几种实用的方案,我给你一步步讲清楚:
方案1:DTO + JPQL构造查询
这是最常用的方式,通过自定义数据传输对象(DTO)来接收你需要的字段:
首先,创建一个DTO类,用来封装devname、hrs、ot这三个字段:
public class DevHoursDTO { private String devname; private Integer hrs; private Integer ot; // 注意:构造方法的参数顺序要和查询语句里的字段顺序完全一致 public DevHoursDTO(String devname, Integer hrs, Integer ot) { this.devname = devname; this.hrs = hrs; this.ot = ot; } // 必须添加getter方法,这样Spring才能序列化对象返回JSON public String getDevname() { return devname; } public Integer getHrs() { return hrs; } public Integer getOt() { return ot; } }
接下来,在你的Repository接口中,使用@Query注解编写JPQL查询,调用DTO的构造方法:
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import java.util.List; // 替换YourModelClass为你实际的实体类,Long为实体的主键类型 public interface YourRepository extends JpaRepository<YourModelClass, Long> { // 注意:JPQL里的表名是实体类的名称,字段是实体类的属性名(不是数据库表/列名) @Query("SELECT NEW com.yourpackage.DevHoursDTO(t.devname, t.hrs, t.ot) FROM imaginaryTable t") List<DevHoursDTO> findDevHours(); }
最后在Controller里调用这个方法,返回结果即可:
@RestController @RequestMapping("/api") public class YourController { private final YourRepository yourRepository; // 构造注入(推荐的依赖注入方式) public YourController(YourRepository yourRepository) { this.yourRepository = yourRepository; } @GetMapping("/dev-hours") public List<DevHoursDTO> getDevHours() { return yourRepository.findDevHours(); } }
方案2:接口投影(Interface Projection)
如果不想创建DTO类,可以用接口投影的方式,更简洁:
首先定义一个投影接口,包含对应字段的getter方法:
public interface DevHoursProjection { // 方法名要和实体类的属性名对应(比如实体类里的属性是devname,这里就叫getDevname) String getDevname(); Integer getHrs(); Integer getOt(); }
然后在Repository里直接返回这个接口类型:
public interface YourRepository extends JpaRepository<YourModelClass, Long> { @Query("SELECT t.devname, t.hrs, t.ot FROM imaginaryTable t") List<DevHoursProjection> findDevHours(); }
Controller里的调用和方案1几乎一样,返回List<DevHoursProjection>即可,Spring会自动生成代理类实现这个接口,序列化时也能正常输出JSON格式的指定字段。
方案3:原生SQL查询
如果你更习惯写原生MySQL语句,可以开启原生查询模式:
public interface YourRepository extends JpaRepository<YourModelClass, Long> { @Query(value = "SELECT devname, hrs, ot FROM imaginaryTable", nativeQuery = true) List<DevHoursProjection> findDevHours(); // 同样可以用接口投影接收结果 }
小提示
- JPQL中的表名是你的实体类名称,字段是实体类的属性名,如果实体类和数据库表/列名不一致(比如用了
@Table或@Column注解),要注意对应关系。 - 如果需要添加查询条件,直接在JPQL或原生SQL后面加
WHERE子句即可,比如SELECT ... FROM imaginaryTable t WHERE t.hrs > 40。
内容的提问来源于stack exchange,提问作者Amithash
相关产品推荐
相关产品推荐

