上篇讲述了最基本的实体类,本篇接着讲述HQL语句构造器,包括查询和更新等。
优点:通过面向对象的方式构造HQL语句,更快捷,不需要手动拼接HQL。
缺点:封装可能降低性能,只能支持常用的和较为简单的HQL构造。
部分功能不完善,待开发。
package cn.fansunion.hibernate.sql; import org.apache.commons.lang.text.StrBuilder; import cn.fansunion.hibernate.sql.entity.From; import cn.fansunion.hibernate.sql.entity.GroupBy; import cn.fansunion.hibernate.sql.entity.OrderGroup; import cn.fansunion.hibernate.sql.entity.SearchCondition; /** * HQL语句构造器。 * <p/> * 目前只适用于1张表的情况,只有查询条件支持占位符,建议使用完全构造的sql语句(是否会产生sql注入,待研究)。 * * @author [email protected] */ public class HqlQueryBuilder extends ConstantBase { // 查询条件组合策略 // ----------------------------------- // *************From****************** // ----------------------------------- private String select; private From from; // ----------------------------------- // *************Where****************** // ----------------------------------- private SearchCondition searchCondition; // ----------------------------------- // *************Group by************** // ----------------------------------- private GroupBy groupBy; // ----------------------------------- // *************Order by****************** // ----------------------------------- private OrderGroup orderGroup; // ----------------------------------- // 通过构造方法,创建查询构造器。各种字段组合形式的构造方法太多,只给出3种比较常见的。 // 建议使用链式构造或setter方法设置属性。 // ----------------------------------- public HqlQueryBuilder() { } public HqlQueryBuilder(From from) { this.from = from; } public HqlQueryBuilder(From from, SearchCondition searchCondition, GroupBy groupBy, OrderGroup orderGroup) { this.from = from; this.searchCondition = searchCondition; this.groupBy = groupBy; this.orderGroup = orderGroup; } public HqlQueryBuilder select(String select) { this.select = select; return this; } // ----------------------------------- // 支持链式用法,暂时不能很好地支持************** // ----------------------------------- public HqlQueryBuilder from(From from) { this.from = from; return this; } public HqlQueryBuilder from(String model) { doFrom(model, ""); return this; } public HqlQueryBuilder from(String model, String alias) { doFrom(model, alias); return this; } public HqlQueryBuilder from(Class<?> clazz) { doFrom(clazz.getSimpleName()); return this; } public HqlQueryBuilder from(Class<?> clazz, String alias) { doFrom(clazz.getSimpleName(), alias); return this; } private void doFrom(String model) { doFrom(model, null); } private void doFrom(String model, String alias) { this.from = new From(model, alias); } public HqlQueryBuilder searchCodition(SearchCondition searchCondition) { this.searchCondition = searchCondition; return this; } public HqlQueryBuilder groupBy(GroupBy groupBy) { this.groupBy = groupBy; return this; } public HqlQueryBuilder orderBy(OrderGroup orderGroup) { this.orderGroup = orderGroup; return this; } /** * 转换成HQL语句 */ public String toHql() { StrBuilder builder = new StrBuilder(); if (select != null) { builder.append(select).append(EMPTY); } if (from != null) { builder.append(from); } if (searchCondition != null) { builder.append(searchCondition); } if (groupBy != null) { builder.append(groupBy); } if (orderGroup != null) { builder.append(orderGroup); } return builder.toString(); } }
下面这个是构造更新HQL语句的构造器,待完善。
package cn.fansunion.hibernate.sql.update; import java.util.HashMap; import java.util.Map; import cn.fansunion.hibernate.util.Pair; /** * Hql更新语句构造器。(TODO 待完善) * * @author [email protected] */ public class HqlUpdateBuilder { private Map<String, Object> params; private String model; public HqlUpdateBuilder() { params = new HashMap<String, Object>(); } public HqlUpdateBuilder(String model) { } public HqlUpdateBuilder(Class<?> model) { this.model = model.getSimpleName(); } public HqlUpdateBuilder model(String model) { this.model = model; return this; } public HqlUpdateBuilder model(Class<?> model) { this.model = model.getSimpleName(); return this; } public HqlUpdateBuilder param(String key, Object value) { params.put(key, value); return this; } public HqlUpdateBuilder param(Pair... pair) { for (Pair p : pair) { params.put(p.getKey(), p.getValue()); } return this; } public HqlUpdateBuilder param(Map<String, Object> params) { this.params.putAll(params); return this; } public String toHql() { String hql = "update " + model + " set "; for (Map.Entry<String, Object> entry : params.entrySet()) { String key = entry.getKey(); hql += key + "=:" + key + " "; } return hql; } }
类似的,有时候,可能不用Hibernate的HQL,而是用原生的SQL。
这个时候,可以编写与HqlQueryBuilder和HqlUpdateBuilder相应的SQL版本。
package cn.fansunion.hibernate.sql; import cn.fansunion.hibernate.sql.entity.Limit; /** * 原生SQL语句构造器。(TODO 待完善) * * @author [email protected] */ public class SqlQueryBuilder { // limit只适用于nativeSQL // ----------------------------------- // *************limit************** // ----------------------------------- private Limit limit; /** * 转换成SQL语句 */ public String toSql(){ //TODO return null; } }
/** * HQL查询构造器使用例子。 * * @author [email protected] */ public class HqlQueryBuilderTest extends ConstantBase { @Test public void test() { From from = new From(HqlQueryBuilder.class); SearchCondition searchCondition = createSearchCondtion(); OrderGroup orderGroup = createOrderGroup(); GroupBy groupBy = createGroupBy(); HqlQueryBuilder builder = new HqlQueryBuilder(from, searchCondition, groupBy, orderGroup); // 直接打印,不使用“断言” println(builder.toHql()); } private GroupBy createGroupBy() { GroupBy groupBy = new GroupBy(); groupBy.addGroup("name"); groupBy.addGroup("id"); return groupBy; } private OrderGroup createOrderGroup() { Order order1 = new Order("id", false); Order order2 = new Order("name", "asc"); OrderGroup orderGroup = new OrderGroup(order1, order2); return orderGroup; } private SearchCondition createSearchCondtion() { GroupCondition groupCondition1 = oneGroupCondition(); GroupCondition groupCondition2 = oneGroupCondition(); //String groupStr1 = groupCondition1.toString(); //String groupStr2 = groupCondition2.toString(); // System.out.println(groupStr1); // System.out.println(groupStr2); SearchCondition searchCondition = new SearchCondition(); searchCondition.addGroupCondition(groupCondition1); searchCondition.addGroupCondition(groupCondition2, true); //String searchStr = searchCondition.toString(); // System.out.println(searchStr); return searchCondition; } private GroupCondition oneGroupCondition() { // =,Integer String age = "age"; Integer ageValue = 24; Condition condition2 = new Condition(age, Operator.EQUALS, ageValue); String str2 = condition2.toString(); Assert.assertEquals(str2, age + EQUALS_WITH_BLANK + ageValue); // =,String String name = "name"; String nameValue = "[email protected]"; Condition condition = new Condition(name, Operator.EQUALS, nameValue); String str = condition.toString(); Assert.assertEquals(str, name + EQUALS_WITH_BLANK + buildQuota(nameValue)); // =,Date String date = "date"; Date dateValue = new Date(); Condition condition3 = new Condition(date, Operator.EQUALS, dateValue); String str3 = condition3.toString(); Assert.assertEquals(str3, date + EQUALS_WITH_BLANK + buildQuota(dateValue)); GroupCondition groupCondition1 = new GroupCondition(); groupCondition1.addCondition(condition); groupCondition1.addCondition(condition2, true); groupCondition1.addCondition(condition3, false); return groupCondition1; } }
from HqlQueryBuilder where (name = '[email protected]' or age = 24 and date = 'Mon Dec 30 16:57:21 CST 2013')
or (name = '[email protected]' or age = 24 and date = 'Mon Dec 30 16:57:21 CST 2013')
group by name,id order by id desc,name asc
原文链接:http://blog.fansunion.cn/articles/3622(小雷博客-blog.fansunion.cn)