关键字: JPA复杂查询,JPA返回自定义实体,JPA返回自定义DTO,JPA联表查询,JPA原生SQL查询,JPA踩坑。
在灵活性上JPA比不上MyBatis,比如想联表查询返回一个自定义的实体Dto,结果发现不能直接返回自定义的实体,典型错误如下:
org.springframework.core.convert.ConverterNotFoundException:
No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [com.lmt.stock.data.XxxDto]
针对这个问题,上网搜寻一番,大概发现如下4个解决方案:
方案1.HQL查询+实体全参数的构造方法
该方法是最常见的方法
实体定义
@Getter
@Setter
public class XxxDto {
BigDecimal profitPercent;
String accountCode;
public XxxDto() {}
public XxxDto(String accountCode, BigDecimal profitPercent) {
this.accountCode = accountCode;
this.profitPercent = profitPercent;
}
}
查询接口
import com.lmt.stock.data.XxxDto;
import com.lmt.stock.data.entity.StockHisHq;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
/**
* @author bazhandao
* @date 2020/3/23 11:08
* @since JDK1.8
*/
public interface StockHisHqRepository extends JpaRepository<StockHisHq, Long> {
// 注意这里只能用HQL查询,不能加nativeQuery = true
@Query(value = "select new com.lmt.stock.data.XxxDto(a.accountCode as accountCode, b.profitPercent as profitPercent) from TradeAccount a, TradeOrder b where a.accountCode = b.accountCode and a.accountCode = ?1")
List<XxxDto> findXxxDtoByAccountCode(String accountCode);
}
方案2.实体定义成接口的形式(推荐)
该方式最直观!!推荐!!!
注意:YyyDto是interface接口,而不是class实体类
ps: 这里返回的是JPA生成的YyyDto的代理类,是可以直接json序列化成json字符串的
接口定义
// 只需要有get方法即可,注意命名要规范
public interface YyyDto {
String getAccountCode();
BigDecimal getProfitPercent();
}
查询接口
import com.lmt.stock.data.YyyDto;
import com.lmt.stock.data.entity.StockHisHq;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
/**
* @author bazhandao
* @date 2020/3/23 11:08
* @since JDK1.8
*/
public interface StockHisHqRepository extends JpaRepository<StockHisHq, Long> {
// 这里可以用HQL查询,也可以用原生SQL查询,YyyDto是一个接口,这里返回的是JPA生成的YyyDto的代理类
// 查寻出的字段命名要规范,否则与接口中的get方法对应不上
// @Query(value = "select a.account_code as accountCode, b.profit_percent as profitPercent from trade_account a, trade_order b where a.account_code = b.account_code and a.account_code = ?1", nativeQuery = true)
@Query(value = "select a.accountCode as accountCode, b.profitPercent as profitPercent from TradeAccount a, TradeOrder b where a.accountCode = b.accountCode and a.accountCode = ?1")
List<YyyDto> findXxxDtoByAccountCode(String accountCode);
}
。。。
。。。
转载自:JPA踩坑记:Spring Data Jpa 原生SQL联表查询返回自定义DTO_jpa原生sql返回自定义实体_滴水可藏海的博客-CSDN博客