上篇讲述了最基本的实体类,本篇接着讲述HQL语句构造器,包括查询和更新等。
优点:通过面向对象的方式构造HQL语句,更快捷,不需要手动拼接HQL。
缺点:封装可能降低性能,只能支持常用的和较为简单的HQL构造。
部分功能不完善,待开发。
1.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语句构造器。
*
* 目前只适用于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();
}
}
2.Hql更新语句构造器
下面这个是构造更新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 params;
private String model;
public HqlUpdateBuilder() {
params = new HashMap();
}
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 params) {
this.params.putAll(params);
return this;
}
public String toHql() {
String hql = "update " + model + " set ";
for (Map.Entry entry : params.entrySet()) {
String key = entry.getKey();
hql += key + "=:" + key + " ";
}
return hql;
}
}
3.原生SQL语句构造器
类似的,有时候,可能不用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;
}
}
4.HQL查询构造器使用例子
/**
* 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;
}
}
5.输出结果
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)