1. 程式人生 > >SpringBootDataJpa自定義查詢返回自定義實體類

SpringBootDataJpa自定義查詢返回自定義實體類

在使用jpa的時候,jpa雖然封裝了大量的crud操作,但是有時也會根據業務需要自定義查詢語句以及返回的自定義實體類

接下來就將一步一步的排坑

電信計費系統:

實體類介紹
費用表實體類

@Entity
@Table(name = "t_costs")
public class Costs {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	@Column(name="phone")
	private String phone;//電話號碼
    @Column(name="rateid")
	private Long rateId;//費率的id
	@Column(name="money")
	private Float money;//消費金額
	
	
	public Long getRateId() {
		return rateId;
	}
	public void setRateId(Long rateId) {
		this.rateId = rateId;
	}
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	
	public Float getMoney() {
		return money;
	}
	public void setMoney(Float money) {
		this.money = money;
	}
	@Override
	public String toString() {
		return "Costs [id=" + id + ", phone=" + phone + ", rateId=" + rateId + ", money=" + money + "]";
	}
}

費率實體類

@Entity
@Table(name = "t_rates")
public class Rates {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	@Column(name="name")
	private String name;//費率名稱
	@Column(name="rate")
	private float rate; //費率價格
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public float getRate() {
		return rate;
	}
	public void setRate(float rate) {
		this.rate = rate;
	}
    	


**自定義結果類:**

public class SearchResult {

	private String phone;// 電話名稱
	private String name;// 分組名稱
	private double sum;// 總消費


	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getSum() {
		return sum;
	}

	public void setSum(double sum) {
		this.sum = sum;
	}

}

要根據業務需要從費用表中查詢費率表的名稱,並分組查詢出不同費率的總額度
sql程式碼如下:

select *,SUM(c.money) as sum from t_costs c left join t_rates r
	 * on r.id=c.rateId where c.phone =? GROUP BY r.name

但是在@Query中查詢***報錯:

  • Path expected for join!**

解釋:查詢語句中不能使用join語句。由於jpa是hibernate的封裝,更支援的是其自帶的hql語句。

這裡有兩個解決方案,任選擇其一

  • 一:改為hql語句查詢,jpa使用hql語句的效率也會更高些
  • 二:增加nativeQuery=true

程式碼如下:

@Query(value="select *,SUM(c.money) as sum
 from t_costs c left join t_rates r  on r.id=c.rateId where c.phone =?  GROUP BY r.name",nativeQuery=true) 

但是問題又來來了
報錯:
- No converter found capable of converting from type**

無法轉化型別
參考這邊文章的解決方案二:
https://blog.csdn.net/pp_fzp/article/details/80530588

將sql語句改為hql語句,

@Query(value = "select new  com.billing.demo.entity.SearchResult(c.phone,r.name,sum(c.money) 
as sum) from Costs c, Rates r  where c.phone =?1  GROUP BY r.name")

報錯

  • Unable to locate appropriate constructor on class、

根據報錯資訊,發現自己的建構函式與需要的建構函式不一致。

修改後的建構函式

	public SearchResult(String phone, String name,
    	double sum)
    	{
    		super();
    		this.phone = phone;
    		this.name = name;
    		this.sum = sum;
    	}
    

終於成功成功了
一步步的排坑 終於解決了這個問題。在這裡插入圖片描述