最近刚进入项目,好多都不太熟悉,而且公司的项目框架大部分都是SSH。由于之前接触的大部分是SSM,所以好多也需要自己去学习。
没多长时间,上面就给我安排了一个追加功能,那就是对所有信息的一个统计--求平均值、总和。他们的写法是这样的。好多都是HQL写法,对这个不是很了解。自己也都是边做边学。
Finder f = Finder.create("from ChannelTrade a ");
String where = " where ";
if (channelTradeForm.getTradeNo() != null && channelTradeForm.getTradeNo().length() > 0) {
f.append(where + " a.tradeNo like :tradeNo").setParam("tradeNo", "%" + channelTradeForm.getTradeNo() + "%");
where = " and ";
}
if(channelTradeForm.getCrsNo()!= null && channelTradeForm.getCrsNo().length()>0){
f.append(where + " a.crsNo like :crsNo").setParam("crsNo", "%"+ channelTradeForm.getCrsNo()+"%");
where = " and ";
}
if (channelTradeForm.getHotel() != null && !StringUtils.isEmpty(channelTradeForm.getHotel().getCode()) && !StringUtils.isEmpty(channelTradeForm.getHotel().getName())) {
f.append(where + " a.hotel.code = :hotelCode").setParam("hotelCode", channelTradeForm.getHotel().getCode());
where = " and";
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
if (channelTradeForm.getArrDateStart() != null && channelTradeForm.getArrDateStart().length()>0 && channelTradeForm.getArrDateEnd() != null && channelTradeForm.getArrDateEnd().length()>0) {
f.append(where + " a.arrDate >= :arrDateStart").setParam("arrDateStart", sdf.parse(channelTradeForm.getArrDateStart()));
where = " and";
f.append(where + " a.arrDate <= :arrDateEnd").setParam("arrDateEnd", sdf.parse(channelTradeForm.getArrDateEnd()));
where = " and";
}
if (channelTradeForm.getDepDateStart() != null && channelTradeForm.getDepDateStart().length()>0 && channelTradeForm.getDepDateEnd() != null && channelTradeForm.getDepDateEnd().length()>0) {
f.append(where + " a.depDate >= :depDateStart").setParam("depDateStart", sdf.parse(channelTradeForm.getDepDateStart()));
where = " and";
f.append(where + " a.depDate <= :depDateEnd").setParam("depDateEnd", sdf.parse(channelTradeForm.getDepDateEnd()));
where = " and";
}
f.append(" order by a.createDatetime desc");
return find(f, channelTradeForm.getPageNo(), channelTradeForm.getPageSize());
这个HQL写法是用Finder封装好了的,基本上不用你去怎么写sql语句,为了更好的知道这个FInder里面都封装了那些方法,你可以点进去查看一下,是这样了。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.kaiyuan.common.hibernate4;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.type.Type;
public class Finder {
private StringBuilder hqlBuilder;
private List<String> params;
private List<Object> values;
private List<Type> types;
private List<String> paramsList;
private List<Collection<Object>> valuesList;
private List<Type> typesList;
private List<String> paramsArray;
private List<Object[]> valuesArray;
private List<Type> typesArray;
private int firstResult = 0;
private int maxResults = 0;
public static final String ROW_COUNT = "select count(*) ";
public static final String FROM = "from";
public static final String DISTINCT = "distinct";
public static final String HQL_FETCH = "fetch";
public static final String ORDER_BY = "order";
public static final String GROUP_BY = "group";
protected Finder() {
}
public Finder(String hql) {
this.hqlBuilder = new StringBuilder(hql);
}
public static Finder create(String hql) {
Finder finder = new Finder(hql);
return finder;
}
public Finder append(String hql) {
this.hqlBuilder.append(hql);
return this;
}
public String getOrigHql() {
return this.hqlBuilder.toString();
}
public String getRowCountHql() {
String hql = this.hqlBuilder.toString();
int fromIndex = hql.toLowerCase().indexOf("from");
String projectionHql = hql.substring(0, fromIndex);
hql = hql.substring(fromIndex);
String rowCountHql = hql.replace("fetch", "");
int index = rowCountHql.indexOf("order");
if (index > 0) {
rowCountHql = rowCountHql.substring(0, index);
}
hql = this.wrapProjection(projectionHql) + rowCountHql;
return hql;
}
public int getFirstResult() {
return this.firstResult;
}
public void setFirstResult(int firstResult) {
this.firstResult = firstResult;
}
public int getMaxResults() {
return this.maxResults;
}
public void setMaxResults(int maxResults) {
this.maxResults = maxResults;
}
public Finder setParam(String param, Object value) {
return this.setParam(param, value, (Type)null);
}
public Finder setParam(String param, Object value, Type type) {
this.getParams().add(param);
this.getValues().add(value);
this.getTypes().add(type);
return this;
}
public Finder setParams(Map<String, Object> paramMap) {
Iterator var3 = paramMap.entrySet().iterator();
while(var3.hasNext()) {
Entry entry = (Entry)var3.next();
this.setParam((String)entry.getKey(), entry.getValue());
}
return this;
}
public Finder setParamList(String name, Collection<Object> vals, Type type) {
this.getParamsList().add(name);
this.getValuesList().add(vals);
this.getTypesList().add(type);
return this;
}
public Finder setParamList(String name, Collection<Object> vals) {
return this.setParamList(name, (Collection)vals, (Type)null);
}
public Finder setParamList(String name, Object[] vals, Type type) {
this.getParamsArray().add(name);
this.getValuesArray().add(vals);
this.getTypesArray().add(type);
return this;
}
public Finder setParamList(String name, Object[] vals) {
return this.setParamList(name, (Object[])vals, (Type)null);
}
public Query setParamsToQuery(Query query) {
int i;
if (this.params != null) {
for(i = 0; i < this.params.size(); ++i) {
if (this.types.get(i) == null) {
query.setParameter((String)this.params.get(i), this.values.get(i));
} else {
query.setParameter((String)this.params.get(i), this.values.get(i), (Type)this.types.get(i));
}
}
}
if (this.paramsList != null) {
for(i = 0; i < this.paramsList.size(); ++i) {
if (this.typesList.get(i) == null) {
query.setParameterList((String)this.paramsList.get(i), (Collection)this.valuesList.get(i));
} else {
query.setParameterList((String)this.paramsList.get(i), (Collection)this.valuesList.get(i), (Type)this.typesList.get(i));
}
}
}
if (this.paramsArray != null) {
for(i = 0; i < this.paramsArray.size(); ++i) {
if (this.typesArray.get(i) == null) {
query.setParameterList((String)this.paramsArray.get(i), (Object[])this.valuesArray.get(i));
} else {
query.setParameterList((String)this.paramsArray.get(i), (Object[])this.valuesArray.get(i), (Type)this.typesArray.get(i));
}
}
}
return query;
}
public Query createQuery(Session s) {
return this.setParamsToQuery(s.createQuery(this.getOrigHql()));
}
private String wrapProjection(String projection) {
return projection.indexOf("select") == -1 ? "select count(*) " : projection.replace("select", "select count(") + ") ";
}
private List<String> getParams() {
if (this.params == null) {
this.params = new ArrayList();
}
return this.params;
}
private List<Object> getValues() {
if (this.values == null) {
this.values = new ArrayList();
}
return this.values;
}
private List<Type> getTypes() {
if (this.types == null) {
this.types = new ArrayList();
}
return this.types;
}
private List<String> getParamsList() {
if (this.paramsList == null) {
this.paramsList = new ArrayList();
}
return this.paramsList;
}
private List<Collection<Object>> getValuesList() {
if (this.valuesList == null) {
this.valuesList = new ArrayList();
}
return this.valuesList;
}
private List<Type> getTypesList() {
if (this.typesList == null) {
this.typesList = new ArrayList();
}
return this.typesList;
}
private List<String> getParamsArray() {
if (this.paramsArray == null) {
this.paramsArray = new ArrayList();
}
return this.paramsArray;
}
private List<Object[]> getValuesArray() {
if (this.valuesArray == null) {
this.valuesArray = new ArrayList();
}
return this.valuesArray;
}
private List<Type> getTypesArray() {
if (this.typesArray == null) {
this.typesArray = new ArrayList();
}
return this.typesArray;
}
public static void main(String[] args) {
Finder find = create("select distinct p FROM BookType join fetch p");
System.out.println(find.getRowCountHql());
System.out.println(find.getOrigHql());
}
}
是不是感觉特别方便,里面有StringBuilder可以帮你去拼接(优势自己下去去百度哦)、distinct(去重)、fetch、order by(分组)。这样写确实有很多好处,比如你不用MyBatis在映射文件中写很复杂的sql语句了,Hibernate本来就是一个对象关系映射框架--ORM。而我现在也越来越对hibernate这种写法情有独钟,慢慢习惯这种写法带来的开心。不过,这种写法也有一定的局限性,比如在我进行统计的时候,我发现这样写根本就不正确
String hql = "select new com.yyf.demo.pojo.ChannelTradeVo(c.hotel.name ," +
"sum(c.nights) ," +
"arrDate ," +
"depDate ," +
"(c.tradeAmount)/sum(c.nights) ," +
"sum(c.hotelTradeAmount) ," +
"sum(c.otherAmount))" +
"from ChannelTrade c where 1=1";
Finder f = new Finder(hql);
项目运行的时候总是报错,也就是用HQl写法的时候,不能像SQL语句那样直接在语句中进行加减乘除
String hql = "select new com.yyf.demo.pojo.ChannelTradeVo(c.hotel.name ," +
"sum(c.nights) ," +
"arrDate ," +
"depDate ," +
"(c.tradeAmount) ," +
"sum(c.hotelTradeAmount) ," +
"sum(c.otherAmount))" +
"from ChannelTrade c where 1=1";
Finder f = new Finder(hql);
这样改过之后,并且,我直接在前台进行一个计算,也是可以的就可以正常运行。
其实,到这,我想说一句,程序员一定要熟悉业务,不然真的会走弯路,这都是我的前车之鉴。比如,交代我的任务是对所有酒店、间夜、平均房价、总收入进行统计报表,我以为这个平均房价是所有酒店的一个平均值,做出来之后,刚开始我们组长也没仔细看,没什么错就通过测试了,没过两天,我们组长就跟我说这个报表有问题,平均房价是房费收入和间夜量的平均值。通过这个教训让我吸取了不少教训。同时也让我深刻明白了对熟悉业务的高要求。