Spring Boot原生查询结果集中无法查看伪列total问题
解决JPA原生查询伪列无法映射的问题
嘿,这个问题我太熟啦!你之所以看不到total伪列,核心原因是你的IceCreamModel实体类里压根没这个字段,JPA没法把查询结果里的total值映射到实体里去~下面给你几个靠谱的解决方案:
方案1:给原实体类添加临时字段
如果可以修改IceCreamModel,直接加一个total字段,并用@Transient标记它不是数据库表的列(避免JPA把它当成表字段处理),同时补上对应的getter/setter,再更新toString方法就能看到值了:
public class IceCreamModel { private Integer id; private String description; private Integer price; private Integer mulfactor; // 添加临时字段,@Transient表示这不是数据库表列 @Transient private Integer total; // 原有字段的getter/setter... // total字段的getter/setter public Integer getTotal() { return total; } public void setTotal(Integer total) { this.total = total; } // 更新toString方法,把total加进去 @Override public String toString() { return "IceCreamModel{id=" + id + ", description='" + description + '\'' + ", price=" + price + ", mulfactor=" + mulfactor + ", total=" + total + '}'; } }
修改后再调用getMul(),就能在打印结果里看到total的值了。
方案2:用DTO接收查询结果
如果不想修改原实体类,推荐创建一个专门的DTO(数据传输对象)来接收包含伪列的查询结果:
第一步:创建DTO类
public class IceCreamTotalDTO { private Integer id; private String description; private Integer price; private Integer mulfactor; private Integer total; // 必须提供包含所有字段的构造方法,JPA会通过构造方法映射结果 public IceCreamTotalDTO(Integer id, String description, Integer price, Integer mulfactor, Integer total) { this.id = id; this.description = description; this.price = price; this.mulfactor = mulfactor; this.total = total; } // 所有字段的getter方法 public Integer getId() { return id; } public String getDescription() { return description; } public Integer getPrice() { return price; } public Integer getMulfactor() { return mulfactor; } public Integer getTotal() { return total; } // 可选:重写toString方便查看结果 @Override public String toString() { return "IceCreamTotalDTO{id=" + id + ", description='" + description + '\'' + ", price=" + price + ", mulfactor=" + mulfactor + ", total=" + total + '}'; } }
第二步:修改Repository方法
把返回类型改成DTO列表:
public interface IceCreamRepository extends JpaRepository<IceCreamModel,Integer> { @Query(value = "SELECT id, description,price, mulfactor, price * mulfactor as total FROM ice WHERE id=101",nativeQuery = true) List<IceCreamTotalDTO> getMul(); }
这样调用getMul()就能拿到包含total的DTO对象了。
方案3:使用接口投影
还有一种轻量方式是用接口投影,不用写实体类或DTO,只需要定义一个包含所有需要字段getter的接口:
第一步:定义投影接口
public interface IceCreamTotalProjection { Integer getId(); String getDescription(); Integer getPrice(); Integer getMulfactor(); Integer getTotal(); // 方法名要和查询里的别名(total)完全一致 }
第二步:修改Repository方法
public interface IceCreamRepository extends JpaRepository<IceCreamModel,Integer> { @Query(value = "SELECT id, description,price, mulfactor, price * mulfactor as total FROM ice WHERE id=101",nativeQuery = true) List<IceCreamTotalProjection> getMul(); }
使用时,调用投影接口的getTotal()方法就能获取伪列值,不过这种方式返回的是JPA生成的代理对象,直接toString可能看不到完整内容,建议直接调用get方法取值。
内容的提问来源于stack exchange,提问作者Sekhar
相关产品推荐
相关产品推荐

