在使用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;
}
终于成功成功了
一步步的排坑 终于解决了这个问题。