开发用的工具
diff --git a/tools/hqlbuilder/pom.xml b/tools/hqlbuilder/pom.xml
new file mode 100755
index 0000000..ab5ad47
--- /dev/null
+++ b/tools/hqlbuilder/pom.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0"?>
+<project
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>com.ekingstar.hibernate</groupId>
+	<artifactId>hql-builder</artifactId>
+	<version>1.0.0</version>
+	<name>HQL Builder</name>
+	<properties>
+		<mockito.version>1.9.5</mockito.version>
+		<testng.version>6.5.2</testng.version>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<downloadJavadocs>true</downloadJavadocs>
+		<logback.version>1.0.7</logback.version>
+		<slf4j.version>1.6.6</slf4j.version>
+	</properties>
+	<distributionManagement>
+		<repository>
+			<id>ekingstar-releases</id>
+			<name>internal release</name>
+			<url>http://app.supwisdom.com:81/artifactory/libs-release-local</url>
+		</repository>
+		<snapshotRepository>
+			<id>ekingstar-snapshots</id>
+			<name>internal Snapshots</name>
+			<url>http://app.supwisdom.com:81/artifactory/libs-snapshot-local</url>
+		</snapshotRepository>
+		<downloadUrl>http://app.supwisdom.com:81/artifactory</downloadUrl>
+	</distributionManagement>
+	<dependencyManagement>
+		<dependencies>
+			<dependency>
+				<groupId>org.slf4j</groupId>
+				<artifactId>slf4j-api</artifactId>
+				<version>1.6.6</version>
+			</dependency>
+			<dependency>
+				<groupId>ch.qos.logback</groupId>
+				<artifactId>logback-core</artifactId>
+				<version>1.0.7</version>
+				<scope>test</scope>
+			</dependency>
+			<dependency>
+				<groupId>ch.qos.logback</groupId>
+				<artifactId>logback-classic</artifactId>
+				<version>1.0.7</version>
+				<scope>test</scope>
+			</dependency>
+			<dependency>
+				<groupId>org.mockito</groupId>
+				<artifactId>mockito-all</artifactId>
+				<version>1.9.5</version>
+				<scope>test</scope>
+			</dependency>
+			<dependency>
+				<groupId>org.testng</groupId>
+				<artifactId>testng</artifactId>
+				<version>6.5.2</version>
+				<scope>test</scope>
+			</dependency>
+			<dependency>
+				<groupId>com.ekingstar.commons</groupId>
+				<artifactId>commons</artifactId>
+				<version>1.0.0</version>
+			</dependency>
+		</dependencies>
+	</dependencyManagement>
+	<dependencies>
+		<dependency>
+			<groupId>com.ekingstar.commons</groupId>
+			<artifactId>commons</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>net.sf.jxls</groupId>
+			<artifactId>jxls-core</artifactId>
+			<version>1.0.3</version>
+			<scope>compile</scope>
+			<optional>true</optional>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-api</artifactId>
+			<version>1.6.6</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.testng</groupId>
+			<artifactId>testng</artifactId>
+			<version>6.5.2</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.mockito</groupId>
+			<artifactId>mockito-all</artifactId>
+			<version>1.9.5</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>ch.qos.logback</groupId>
+			<artifactId>logback-core</artifactId>
+			<version>1.0.7</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>ch.qos.logback</groupId>
+			<artifactId>logback-classic</artifactId>
+			<version>1.0.7</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.hibernate</groupId>
+			<artifactId>hibernate-core</artifactId>
+			<version>4.2.4.Final</version>
+			<scope>provided</scope>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>3.0</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+					<encoding>UTF-8</encoding>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-source-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>attach-sources</id>
+						<phase>deploy</phase>
+						<goals>
+							<goal>jar-no-fork</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<artifactId>maven-javadoc-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>attach-javadocs</id>
+						<phase>deploy</phase>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<!-- explicitly define maven-deploy-plugin after other to force exec 
+					order -->
+				<artifactId>maven-deploy-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>deploy</id>
+						<phase>deploy</phase>
+						<goals>
+							<goal>deploy</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+
+</project>
+
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/QuerySupport.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/QuerySupport.java
new file mode 100644
index 0000000..97ec96a
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/QuerySupport.java
@@ -0,0 +1,159 @@
+package com.ekingstar.hibernate;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.Query;
+import org.hibernate.Session;
+
+import com.ekingstar.commons.lang.Strings;
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.hibernate.query.LimitQuery;
+import com.ekingstar.hibernate.query.builder.Condition;
+
+ public final class QuerySupport {
+    private QuerySupport() {
+      super();
+    }
+
+    private static Query buildHibernateQuery(com.ekingstar.hibernate.query.Query<?> bquery,
+        final Session session) {
+      Query hibernateQuery = null;
+      if (bquery.getLang().equals(com.ekingstar.hibernate.query.Lang.HQL)) {
+        hibernateQuery = session.createQuery(bquery.getStatement());
+      } else {
+        hibernateQuery = session.createSQLQuery(bquery.getStatement());
+      }
+      if (bquery.isCacheable()) hibernateQuery.setCacheable(bquery.isCacheable());
+      setParameter(hibernateQuery, bquery.getParams());
+      return hibernateQuery;
+    }
+
+    /**
+     * 统计该查询的记录数
+     * 
+     * @param limitQuery
+     * @param hibernateSession
+     * @return data count
+     */
+    public static int count(final com.ekingstar.hibernate.query.LimitQuery<?> limitQuery,
+        final Session hibernateSession) {
+      final com.ekingstar.hibernate.query.Query<?> cntQuery = limitQuery.getCountQuery();
+      if (null == cntQuery) {
+        Query hibernateQuery = buildHibernateQuery(limitQuery, hibernateSession);
+        return hibernateQuery.list().size();
+      } else {
+        Query hibernateQuery = buildHibernateQuery(cntQuery, hibernateSession);
+        final Number count = (Number) (hibernateQuery.uniqueResult());
+        if (null == count) {
+          return 0;
+        } else {
+          return count.intValue();
+        }
+      }
+    }
+
+    /**
+     * 查询结果集
+     * 
+     * @param query
+     * @param session
+     * @return result list
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> List<T> find(final com.ekingstar.hibernate.query.Query<T> query, final Session session) {
+      if (query instanceof LimitQuery<?>) {
+        LimitQuery<T> limitQuery = (LimitQuery<T>) query;
+        Query hibernateQuery = buildHibernateQuery(limitQuery, session);
+        if (null == limitQuery.getLimit()) {
+          return hibernateQuery.list();
+        } else {
+          final PageLimit limit = limitQuery.getLimit();
+          hibernateQuery.setFirstResult((limit.getPageNo() - 1) * limit.getPageSize()).setMaxResults(
+              limit.getPageSize());
+          return hibernateQuery.list();
+        }
+      } else {
+        return buildHibernateQuery(query, session).list();
+      }
+    }
+
+    /**
+     * 为query设置JPA style参数
+     * 
+     * @param query
+     * @param argument
+     */
+    public static Query setParameter(final Query query, final Object[] argument) {
+      if (argument != null && argument.length > 0) {
+        for (int i = 0; i < argument.length; i++)
+          query.setParameter(String.valueOf(i + 1), argument[i]);
+      }
+      return query;
+    }
+
+    /**
+     * 为query设置参数
+     * 
+     * @param query
+     * @param parameterMap
+     * @return query
+     */
+    public static Query setParameter(final Query query, final Map<String, Object> parameterMap) {
+      if (parameterMap != null && !parameterMap.isEmpty()) {
+        for (final Iterator<String> ite = parameterMap.keySet().iterator(); ite.hasNext();) {
+          final String parameterName = ite.next();
+          if (null == parameterName) {
+            break;
+          }
+          final Object parameterValue = parameterMap.get(parameterName);
+          if (null == parameterValue) {
+            query.setParameter(parameterName, (Object) null);
+          } else if (parameterValue.getClass().isArray()) {
+            query.setParameterList(parameterName, (Object[]) parameterValue);
+          } else if (parameterValue instanceof Collection<?>) {
+            query.setParameterList(parameterName, (Collection<?>) parameterValue);
+          } else {
+            query.setParameter(parameterName, parameterValue);
+          }
+        }
+      }
+      return query;
+    }
+
+    /**
+     * 针对查询条件绑定查询的值
+     * 
+     * @param query
+     * @param conditions
+     */
+    public static void bindValues(final Query query, final List<Condition> conditions) {
+      int position = 0;
+      boolean hasInterrogation = false; // 含有问号
+      for (final Iterator<Condition> iter = conditions.iterator(); iter.hasNext();) {
+        final Condition condition = (Condition) iter.next();
+        if (Strings.contains(condition.getContent(), "?")) {
+          hasInterrogation = true;
+        }
+        if (hasInterrogation) {
+          for (final Iterator<?> iterator = condition.getParams().iterator(); iterator.hasNext();) {
+            query.setParameter(position++, iterator.next());
+          }
+        } else {
+          final List<String> paramNames = condition.getParamNames();
+          for (int i = 0; i < paramNames.size(); i++) {
+            final String name = paramNames.get(i);
+            final Object value = condition.getParams().get(i);
+            if (value.getClass().isArray()) {
+              query.setParameterList(name, (Object[]) value);
+            } else if (value instanceof Collection<?>) {
+              query.setParameterList(name, (Collection<?>) value);
+            } else {
+              query.setParameter(name, value);
+            }
+          }
+        }
+      }
+    }
+  }
\ No newline at end of file
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/EmptyKeyPredicate.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/EmptyKeyPredicate.java
new file mode 100755
index 0000000..d3b6eb3
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/EmptyKeyPredicate.java
@@ -0,0 +1,48 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.entity;
+
+import com.ekingstar.commons.lang.Strings;
+import com.ekingstar.commons.lang.functor.Predicate;
+
+/**
+ * <p>
+ * EmptyKeyPredicate class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class EmptyKeyPredicate implements Predicate<Object> {
+
+  public Boolean apply(final Object value) {
+    boolean success = false;
+    if (null != value) {
+      if (value instanceof String) {
+        success = Strings.isEmpty((String) value);
+      } else if (value instanceof Number) {
+        success = (0 == ((Number) value).intValue());
+      } else {
+        throw new RuntimeException("unsupported key type");
+      }
+    }
+    return success;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/EntityUtils.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/EntityUtils.java
new file mode 100644
index 0000000..421269c
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/EntityUtils.java
@@ -0,0 +1,99 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.entity;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ekingstar.commons.lang.Strings;
+
+/**
+ * 实体类辅助工具箱
+ * 
+ * @author chaostone 2005-10-31
+ * @version $Id: $
+ */
+public final class EntityUtils {
+
+  private static final Logger logger = LoggerFactory.getLogger(EntityUtils.class);
+
+  private EntityUtils() {
+  }
+
+  /**
+   * <p>
+   * getCommandName.
+   * </p>
+   * 
+   * @param clazz a {@link java.lang.Class} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String getCommandName(Class<?> clazz) {
+    String name = clazz.getName();
+    return Strings.uncapitalize(name.substring(name.lastIndexOf('.') + 1));
+  }
+
+  /**
+   * <p>
+   * getCommandName.
+   * </p>
+   * 
+   * @param entityName a {@link java.lang.String} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String getCommandName(String entityName) {
+    return Strings.uncapitalize(Strings.substringAfterLast(entityName, "."));
+  }
+
+  /**
+   * <p>
+   * getCommandName.
+   * </p>
+   * 
+   * @param obj a {@link java.lang.Object} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String getCommandName(Object obj) {
+    String name = obj.getClass().getName();
+    int dollar = name.indexOf('$');
+    if (-1 == dollar) {
+      name = name.substring(name.lastIndexOf('.') + 1);
+    } else {
+      name = name.substring(name.lastIndexOf('.') + 1, dollar);
+    }
+    return Strings.uncapitalize(name);
+  }
+
+  /**
+   * 为了取出CGLIB代来的代理命名
+   * 
+   * @param clazz a {@link java.lang.Class} object.
+   * @return a {@link java.lang.String} object.
+   */
+  public static String getEntityClassName(Class<?> clazz) {
+    String name = clazz.getName();
+    int dollar = name.indexOf('$');
+    if (-1 == dollar) {
+      return name;
+    } else {
+      return name.substring(0, dollar);
+    }
+  }
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/ValidEntityKeyPredicate.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/ValidEntityKeyPredicate.java
new file mode 100755
index 0000000..69d6866
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/ValidEntityKeyPredicate.java
@@ -0,0 +1,40 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.entity;
+
+import com.ekingstar.commons.lang.functor.NotEmptyStringPredicate;
+import com.ekingstar.commons.lang.functor.NotZeroNumberPredicate;
+import com.ekingstar.commons.lang.functor.Predicate;
+
+/**
+ * 判断实体类中的主键是否是有效主键
+ * 
+ * @author chaostone
+ */
+public class ValidEntityKeyPredicate implements Predicate<Object> {
+
+  public Boolean apply(Object value) {
+    if (null == value) return Boolean.FALSE;
+    if (value instanceof Number) return NotZeroNumberPredicate.Instance.apply((Number) value);
+    return NotEmptyStringPredicate.Instance.apply(value.toString());
+  }
+
+  public static final ValidEntityKeyPredicate Instance = new ValidEntityKeyPredicate();
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/ValidEntityPredicate.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/ValidEntityPredicate.java
new file mode 100755
index 0000000..0c307da
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/entity/ValidEntityPredicate.java
@@ -0,0 +1,57 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.entity;
+
+import java.io.Serializable;
+
+import com.ekingstar.commons.bean.PropertyUtils;
+import com.ekingstar.commons.lang.functor.Predicate;
+
+/**
+ * 有效实体判断谓词
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class ValidEntityPredicate implements Predicate<Object> {
+
+  public Boolean apply(final Object value) {
+    if (null == value) { return false; }
+    try {
+      Serializable key = PropertyUtils.getProperty(value, "id");
+      return ValidEntityKeyPredicate.Instance.apply(key);
+    } catch (Exception e) {
+      return false;
+    }
+  }
+
+  /** Constant <code>INSTANCE</code> */
+  public static final ValidEntityPredicate Instance = new ValidEntityPredicate();
+
+  /**
+   * <p>
+   * getInstance.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.entity.ValidEntityPredicate} object.
+   */
+  public static ValidEntityPredicate getInstance() {
+    return Instance;
+  }
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/Lang.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/Lang.java
new file mode 100755
index 0000000..fc14f24
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/Lang.java
@@ -0,0 +1,48 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query;
+
+/**
+ * <p>
+ * Lang class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public enum Lang {
+  SQL("sql"), HQL("hql");
+  private final String lang;
+
+  private Lang(String name) {
+    this.lang = name;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>lang</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String getLang() {
+    return lang;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/LimitQuery.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/LimitQuery.java
new file mode 100755
index 0000000..0f982cd
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/LimitQuery.java
@@ -0,0 +1,60 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query;
+
+import com.ekingstar.commons.page.PageLimit;
+
+/**
+ * <p>
+ * LimitQuery interface.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public interface LimitQuery<T> extends Query<T> {
+
+  /**
+   * <p>
+   * getLimit.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.page.PageLimit} object.
+   */
+  PageLimit getLimit();
+
+  /**
+   * <p>
+   * limit.
+   * </p>
+   * 
+   * @param limit a {@link com.ekingstar.commons.page.PageLimit} object.
+   * @return a {@link com.ekingstar.hibernate.query.LimitQuery} object.
+   */
+  LimitQuery<T> limit(final PageLimit limit);
+
+  /**
+   * <p>
+   * getCountQuery.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.Query} object.
+   */
+  Query<T> getCountQuery();
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/Query.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/Query.java
new file mode 100755
index 0000000..16e53cb
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/Query.java
@@ -0,0 +1,62 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query;
+
+import java.util.Map;
+
+/**
+ * 数据查询接口
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public interface Query<T> {
+
+  /**
+   * Returns query statement.
+   */
+  String getStatement();
+
+  /**
+   * <p>
+   * getParams.
+   * </p>
+   * 
+   * @return a {@link java.util.Map} object.
+   */
+  Map<String, Object> getParams();
+
+  /**
+   * <p>
+   * isCacheable.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  boolean isCacheable();
+
+  /**
+   * <p>
+   * getLang.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.Lang} object.
+   */
+  Lang getLang();
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/QueryBuilder.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/QueryBuilder.java
new file mode 100755
index 0000000..d65ba0f
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/QueryBuilder.java
@@ -0,0 +1,72 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query;
+
+import java.util.Map;
+
+import com.ekingstar.commons.page.PageLimit;
+
+/**
+ * <p>
+ * QueryBuilder interface.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public interface QueryBuilder<T> {
+
+  /**
+   * <p>
+   * build.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.Query} object.
+   */
+  Query<T> build();
+
+  /**
+   * <p>
+   * limit.
+   * </p>
+   * 
+   * @param limit a {@link com.ekingstar.commons.page.PageLimit} object.
+   * @return a {@link com.ekingstar.hibernate.query.QueryBuilder} object.
+   */
+  QueryBuilder<T> limit(PageLimit limit);
+
+  /**
+   * <p>
+   * getParams.
+   * </p>
+   * 
+   * @return a {@link java.util.Map} object.
+   */
+  Map<String, Object> getParams();
+
+  /**
+   * <p>
+   * params.
+   * </p>
+   * 
+   * @param newParams a {@link java.util.Map} object.
+   * @return a {@link com.ekingstar.hibernate.query.QueryBuilder} object.
+   */
+  QueryBuilder<T> params(Map<String, Object> newParams);
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/AbstractQuery.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/AbstractQuery.java
new file mode 100755
index 0000000..4986430
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/AbstractQuery.java
@@ -0,0 +1,174 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.builder;
+
+import java.util.Map;
+
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.hibernate.query.QueryBuilder;
+
+/**
+ * 抽象查询
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public abstract class AbstractQuery<T> implements QueryBuilder<T> {
+  /** query 查询语句 */
+  protected String queryStr;
+
+  /** count 计数语句 */
+  protected String countStr;
+
+  /** 分页 */
+  protected PageLimit limit;
+
+  /** 参数 */
+  protected Map<String, Object> params;
+
+  /** 缓存查询结果 */
+  protected boolean cacheable = false;
+
+  /**
+   * Returns limit
+   */
+  public PageLimit getLimit() {
+    return limit;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>limit</code>.
+   * </p>
+   * 
+   * @param limit a {@link com.ekingstar.commons.page.PageLimit} object.
+   */
+  public void setLimit(final PageLimit limit) {
+    this.limit = limit;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>params</code>.
+   * </p>
+   * 
+   * @return a {@link java.util.Map} object.
+   */
+  public Map<String, Object> getParams() {
+    return params;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>countStr</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String getCountStr() {
+    return countStr;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>countStr</code>.
+   * </p>
+   * 
+   * @param countStr a {@link java.lang.String} object.
+   */
+  public void setCountStr(final String countStr) {
+    this.countStr = countStr;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>queryStr</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String getQueryStr() {
+    return queryStr;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>queryStr</code>.
+   * </p>
+   * 
+   * @param queryStr a {@link java.lang.String} object.
+   */
+  public void setQueryStr(final String queryStr) {
+    this.queryStr = queryStr;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>params</code>.
+   * </p>
+   * 
+   * @param params a {@link java.util.Map} object.
+   */
+  public void setParams(final Map<String, Object> params) {
+    this.params = params;
+  }
+
+  /**
+   * <p>
+   * toQueryString.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public abstract String toQueryString();
+
+  /**
+   * <p>
+   * toCountString.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String toCountString() {
+    return countStr;
+  }
+
+  /**
+   * <p>
+   * isCacheable.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean isCacheable() {
+    return cacheable;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>cacheable</code>.
+   * </p>
+   * 
+   * @param cacheable a boolean.
+   */
+  public void setCacheable(final boolean cacheable) {
+    this.cacheable = cacheable;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/AbstractQueryBuilder.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/AbstractQueryBuilder.java
new file mode 100755
index 0000000..7a66f9c
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/AbstractQueryBuilder.java
@@ -0,0 +1,193 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.builder;
+
+import java.util.List;
+import java.util.Map;
+
+import com.ekingstar.commons.collection.CollectUtils;
+import com.ekingstar.commons.collection.Order;
+import com.ekingstar.commons.lang.Strings;
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.hibernate.query.Lang;
+import com.ekingstar.hibernate.query.Query;
+import com.ekingstar.hibernate.query.QueryBuilder;
+
+/**
+ * <p>
+ * Abstract AbstractQueryBuilder class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public abstract class AbstractQueryBuilder<T> implements QueryBuilder<T> {
+
+  /** Constant <code>INNER_JOIN=" left join "</code> */
+  public static final String INNER_JOIN = " left join ";
+
+  /** Constant <code>OUTER_JOIN=" outer join "</code> */
+  public static final String OUTER_JOIN = " outer join ";
+
+  /** Constant <code>LEFT_OUTER_JOIN=" left outer join "</code> */
+  public static final String LEFT_OUTER_JOIN = " left outer join ";
+
+  /** Constant <code>RIGHT_OUTER_JOIN=" right outer join "</code> */
+  public static final String RIGHT_OUTER_JOIN = " right outer join ";
+
+  /** query 查询语句 */
+  protected String statement;
+
+  /** 分页 */
+  protected PageLimit limit;
+
+  /** 参数 */
+  protected Map<String, Object> params;
+
+  protected String select;
+
+  protected String from;
+
+  /** 别名 */
+  protected String alias;
+
+  protected List<Condition> conditions = CollectUtils.newArrayList();
+
+  protected List<Order> orders = CollectUtils.newArrayList();
+
+  protected List<String> groups = CollectUtils.newArrayList();
+
+  protected String having;
+
+  /** 缓存查询结果 */
+  protected boolean cacheable = false;
+
+  /**
+   * Returns params.
+   */
+  public Map<String, Object> getParams() {
+    return (null == params) ? Conditions.getParamMap(conditions) : CollectUtils.newHashMap(params);
+  }
+
+  /**
+   * Return entity's alias
+   */
+  public String getAlias() {
+    return alias;
+  }
+
+  /**
+   * <p>
+   * isCacheable.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean isCacheable() {
+    return cacheable;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>limit</code>.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.page.PageLimit} object.
+   */
+  public PageLimit getLimit() {
+    return limit;
+  }
+
+  /**
+   * <p>
+   * build.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.Query} object.
+   */
+  public Query<T> build() {
+    QueryBean<T> queryBean = new QueryBean<T>();
+    queryBean.setStatement(genStatement());
+    queryBean.setParams(getParams());
+    if (null != limit) {
+      queryBean.setLimit(new PageLimit(limit.getPageNo(), limit.getPageSize()));
+    }
+    queryBean.setCountStatement(genCountStatement());
+    queryBean.setCacheable(cacheable);
+    queryBean.setLang(getLang());
+    return queryBean;
+  }
+
+  /**
+   * <p>
+   * getLang.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.Lang} object.
+   */
+  abstract protected Lang getLang();
+
+  /**
+   * 生成查询语句(如果查询语句已经存在则不进行生成)
+   */
+  protected String genStatement() {
+    if (Strings.isNotEmpty(statement)) return statement;
+    else return genQueryStatement(true);
+  }
+
+  /**
+   * <p>
+   * genCountStatement.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  abstract protected String genCountStatement();
+
+  /**
+   * <p>
+   * genQueryStatement.
+   * </p>
+   * 
+   * @param hasOrder a boolean.
+   * @return a {@link java.lang.String} object.
+   */
+  protected String genQueryStatement(final boolean hasOrder) {
+    if (null == from) return statement;
+    final StringBuilder buf = new StringBuilder(50);
+    buf.append((select == null) ? "" : (select + " ")).append(from);
+    if (!conditions.isEmpty()) buf.append(" where ").append(Conditions.toQueryString(conditions));
+
+    if (!groups.isEmpty()) {
+      buf.append(" group by ");
+      for (final String groupBy : groups)
+        buf.append(groupBy).append(',');
+      buf.deleteCharAt(buf.length() - 1);
+    }
+    if (hasOrder && !CollectUtils.isEmpty(orders)) buf.append(' ').append(Order.toSortString(orders));
+
+    if (null != having) buf.append(" having ").append(having);
+    return buf.toString();
+  }
+
+  public List<Condition> getConditions() {
+    return conditions;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/Condition.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/Condition.java
new file mode 100755
index 0000000..35f44f9
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/Condition.java
@@ -0,0 +1,324 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.builder;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import com.ekingstar.commons.lang.Strings;
+
+/**
+ * 查询条件 使用例子如下
+ * <p>
+ * <blockquote>
+ * 
+ * <pre>
+ *      new Condition(&quot;std.id=?&quot;,new Long(2));
+ *      或者 Condition(&quot;std.id=:std_id&quot;,new Long(2));
+ *      ?绑定单值.命名参数允许绑定多值.但是只能由字母,数组和下划线组成
+ *      一组condition只能采取上面一种形式
+ * </pre>
+ * 
+ * </blockquote>
+ * <p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class Condition {
+
+  private final String content;
+
+  private final List<Object> params = new ArrayList<Object>(1);
+
+  /**
+   * <p>
+   * Constructor for Condition.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   */
+  public Condition(final String content) {
+    this.content = content;
+  }
+
+  /**
+   * <p>
+   * Constructor for Condition.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   */
+  public Condition(final String content, Object param1) {
+    this.content = content;
+    params.add(param1);
+  }
+
+  /**
+   * <p>
+   * Constructor for Condition.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   * @param param2 a {@link java.lang.Object} object.
+   */
+  public Condition(final String content, Object param1, Object param2) {
+    this(content, param1, param2, null);
+  }
+
+  /**
+   * <p>
+   * Constructor for Condition.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   * @param param2 a {@link java.lang.Object} object.
+   * @param param3 a {@link java.lang.Object} object.
+   */
+  public Condition(final String content, Object param1, Object param2, Object param3) {
+    this.content = content;
+    if (null != param1) {
+      params.add(param1);
+    }
+    if (null != param2) {
+      params.add(param2);
+    }
+    if (null != param3) {
+      params.add(param3);
+    }
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>content</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String getContent() {
+    return content;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>params</code>.
+   * </p>
+   * 
+   * @return a {@link java.util.List} object.
+   */
+  public List<Object> getParams() {
+    return params;
+  }
+
+  /**
+   * <p>
+   * isNamed.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean isNamed() {
+    return !Strings.contains(content, "?");
+  }
+
+  /**
+   * 得到查询条件中所有的命名参数.
+   * 
+   * @return a {@link java.util.List} object.
+   */
+  public List<String> getParamNames() {
+    if (!Strings.contains(content, ":")) { return Collections.emptyList(); }
+    final List<String> params = new ArrayList<String>();
+    int index = 0;
+    do {
+      final int colonIndex = content.indexOf(':', index);
+      if (-1 == colonIndex) {
+        break;
+      }
+      index = colonIndex + 1;
+      while (index < content.length()) {
+        final char c = content.charAt(index);
+        if (isValidIdentifierStarter(c)) {
+          index++;
+        } else {
+          break;
+        }
+      }
+      final String paramName = content.substring(colonIndex + 1, index);
+      if (!params.contains(paramName)) {
+        params.add(paramName);
+      }
+    } while (index < content.length());
+    return params;
+  }
+
+  private static boolean isValidIdentifierStarter(final char ch) {
+    return (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || (ch == '_') || ('0' <= ch && ch <= '9'));
+  }
+
+  /**
+   * <p>
+   * param.
+   * </p>
+   * 
+   * @param value a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   */
+  public Condition param(final Object value) {
+    params.add(value);
+    return this;
+  }
+
+  /**
+   * <p>
+   * params.
+   * </p>
+   * 
+   * @param values a {@link java.util.List} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   */
+  public Condition params(final List<?> values) {
+    params.clear();
+    params.addAll(values);
+    return this;
+  }
+
+  /**
+   * <p>
+   * toString.
+   * </p>
+   * 
+   * @see java.lang.Object#toString()
+   * @return a {@link java.lang.String} object.
+   */
+  public String toString() {
+    final StringBuilder str = new StringBuilder(content).append(" ");
+    for (final Object value : params) {
+      str.append(value);
+    }
+    return str.toString();
+  }
+
+  /** {@inheritDoc} */
+  public boolean equals(final Object obj) {
+    if (null == getContent() || !(obj instanceof Condition)) {
+      return false;
+    } else {
+      return getContent().equals(((Condition) obj).getContent());
+    }
+  }
+
+  /**
+   * <p>
+   * hashCode.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int hashCode() {
+    if (null == content) {
+      return 0;
+    } else {
+      return content.hashCode();
+    }
+  }
+
+  // 以下是几个方便的方法
+  /**
+   * <p>
+   * eq.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param value a {@link java.lang.Number} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   */
+  public static Condition eq(final String content, final Number value) {
+    return new Condition(content + " = " + value);
+  }
+
+  /**
+   * <p>
+   * eq.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param value a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   */
+  public static Condition eq(final String content, final String value) {
+    return new Condition(content + " = '" + value + "'");
+  }
+
+  /**
+   * <p>
+   * le.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param value a {@link java.lang.Number} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   */
+  public static Condition le(final String content, final Number value) {
+    return new Condition(content + " <= " + value);
+  }
+
+  /**
+   * <p>
+   * ge.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param value a {@link java.lang.Number} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   */
+  public static Condition ge(final String content, final Number value) {
+    return new Condition(content + " >= " + value);
+  }
+
+  /**
+   * <p>
+   * ne.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param value a {@link java.lang.Number} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   */
+  public static Condition ne(final String content, final Number value) {
+    return new Condition(content + " <> " + value);
+  }
+
+  /**
+   * <p>
+   * like.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param value a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   */
+  public static Condition like(final String content, final String value) {
+    return new Condition(content + " like '%" + value + "%'");
+  }
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/Conditions.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/Conditions.java
new file mode 100755
index 0000000..75603ec
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/Conditions.java
@@ -0,0 +1,123 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.builder;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ekingstar.commons.collection.CollectUtils;
+import com.ekingstar.commons.lang.Assert;
+import com.ekingstar.commons.lang.Strings;
+
+/**
+ * 条件提取辅助类
+ * 
+ * @author chaostone
+ */
+public final class Conditions {
+  private static final Logger logger = LoggerFactory.getLogger(Conditions.class);
+
+  private Conditions() {
+    super();
+  }
+
+  public static Condition and(Condition... conditions) {
+    return concat(Arrays.asList(conditions), "and");
+  }
+
+  public static Condition and(List<Condition> conditions) {
+    return concat(conditions, "and");
+  }
+
+  public static Condition or(Condition... conditions) {
+    return concat(Arrays.asList(conditions), "or");
+  }
+
+  public static Condition or(List<Condition> conditions) {
+    return concat(conditions, "or");
+  }
+
+  static Condition concat(List<Condition> conditions, String andor) {
+    Assert.isTrue(!conditions.isEmpty(), "conditions shouldn't be empty!");
+    if (conditions.size() == 1) return conditions.get(0);
+    StringBuffer sb = new StringBuffer();
+    List<Object> params = CollectUtils.newArrayList();
+    sb.append("(");
+    for (Condition con : conditions) {
+      sb.append(" " + andor + " (");
+      sb.append(con.getContent());
+      sb.append(')');
+      params.addAll(con.getParams());
+    }
+    sb.append(")");
+    sb.replace(0, (" " + andor + " ").length() + 1, "(");
+    return new Condition(sb.toString()).params(params);
+  }
+
+  public static String toQueryString(final List<Condition> conditions) {
+    if (null == conditions || conditions.isEmpty()) { return ""; }
+    final StringBuilder buf = new StringBuilder("");
+    for (final Iterator<Condition> iter = conditions.iterator(); iter.hasNext();) {
+      final Condition con = iter.next();
+      buf.append('(').append(con.getContent()).append(')');
+      if (iter.hasNext()) {
+        buf.append(" and ");
+      }
+    }
+    return buf.toString();
+  }
+
+  /**
+   * 获得条件的绑定参数映射
+   * 
+   * @param conditions
+   */
+  public static Map<String, Object> getParamMap(final List<Condition> conditions) {
+    final Map<String, Object> params = new HashMap<String, Object>();
+    for (final Condition con : conditions) {
+      params.putAll(getParamMap(con));
+    }
+    return params;
+  }
+
+  /**
+   * 获得条件的绑定参数映射
+   * 
+   * @param condition
+   */
+  public static Map<String, Object> getParamMap(final Condition condition) {
+    final Map<String, Object> params = new HashMap<String, Object>();
+    if (!Strings.contains(condition.getContent(), "?")) {
+      final List<String> paramNames = condition.getParamNames();
+      if (paramNames.size() > condition.getParams().size()) { throw new RuntimeException(
+          "condition params not set [" + condition.getContent() + "] with value:" + condition.getParams()); }
+      for (int i = 0; i < paramNames.size(); i++) {
+        params.put(paramNames.get(i), condition.getParams().get(i));
+      }
+    }
+    return params;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/OqlBuilder.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/OqlBuilder.java
new file mode 100755
index 0000000..5e11130
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/OqlBuilder.java
@@ -0,0 +1,561 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.builder;
+
+import static com.ekingstar.commons.lang.Strings.concat;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.ekingstar.commons.collection.CollectUtils;
+import com.ekingstar.commons.collection.Order;
+import com.ekingstar.commons.lang.Assert;
+import com.ekingstar.commons.lang.Strings;
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.hibernate.entity.EntityUtils;
+import com.ekingstar.hibernate.query.Lang;
+
+/**
+ * 实体类查询 Object Query Language Builder
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class OqlBuilder<T> extends AbstractQueryBuilder<T> {
+
+  /** 查询实体类 */
+  protected Class<T> entityClass;
+
+  /**
+   * <p>
+   * Constructor for OqlBuilder.
+   * </p>
+   */
+  protected OqlBuilder() {
+    super();
+  }
+
+  /**
+   * <p>
+   * hql.
+   * </p>
+   * 
+   * @param hql a {@link java.lang.String} object.
+   * @param <E> a E object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public static <E> OqlBuilder<E> hql(final String hql) {
+    OqlBuilder<E> query = new OqlBuilder<E>();
+    query.statement = hql;
+    return query;
+  }
+
+  /**
+   * <p>
+   * from.
+   * </p>
+   * 
+   * @param from a {@link java.lang.String} object.
+   * @param <E> a E object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public static <E> OqlBuilder<E> from(final String from) {
+    OqlBuilder<E> query = new OqlBuilder<E>();
+    query.newFrom(from);
+    return query;
+  }
+
+  /**
+   * <p>
+   * from.
+   * </p>
+   * 
+   * @param entityName a {@link java.lang.String} object.
+   * @param alias a {@link java.lang.String} object.
+   * @param <E> a E object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  @SuppressWarnings("unchecked")
+  public static <E> OqlBuilder<E> from(final String entityName, final String alias) {
+    OqlBuilder<E> query = new OqlBuilder<E>();
+    query.alias = alias;
+    query.select = "select " + alias;
+    query.from = concat("from ", entityName, " ", alias);
+    return query;
+  }
+
+  /**
+   * <p>
+   * from.
+   * </p>
+   * 
+   * @param entityClass a {@link java.lang.Class} object.
+   * @param <E> a E object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public static <E> OqlBuilder<E> from(final Class<E> entityClass) {
+    return from(entityClass, EntityUtils.getCommandName(entityClass.getName()));
+  }
+
+  /**
+   * <p>
+   * from.
+   * </p>
+   * 
+   * @param entityClass a {@link java.lang.Class} object.
+   * @param alias a {@link java.lang.String} object.
+   * @param <E> a E object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  @SuppressWarnings("unchecked")
+  public static <E> OqlBuilder<E> from(final Class<E> entityClass, final String alias) {
+    OqlBuilder<E> query = new OqlBuilder<E>();
+    query.entityClass = entityClass;
+    query.alias = alias;
+    query.select = "select " + alias;
+    query.from = concat("from ", entityClass.getName(), " ", alias);
+    return query;
+  }
+
+  /**
+   * <p>
+   * alias.
+   * </p>
+   * 
+   * @param alias a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> alias(final String alias) {
+    this.alias = alias;
+    return this;
+  }
+
+  /**
+   * <p>
+   * join.
+   * </p>
+   * 
+   * @param path a {@link java.lang.String} object.
+   * @param alias a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> join(final String path, final String alias) {
+    from = concat(from, " join ", path, " ", alias);
+    return this;
+  }
+
+  /**
+   * <p>
+   * join.
+   * </p>
+   * 
+   * @param joinMode a {@link java.lang.String} object.
+   * @param path a {@link java.lang.String} object.
+   * @param alias a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> join(final String joinMode, final String path, final String alias) {
+    from = concat(from, " ", joinMode, " join ", path, " ", alias);
+    return this;
+  }
+
+  /** {@inheritDoc} */
+  public OqlBuilder<T> params(final Map<String, Object> params) {
+    this.params = CollectUtils.newHashMap(params);
+    return this;
+  }
+
+  /**
+   * <p>
+   * param.
+   * </p>
+   * 
+   * @param name a {@link java.lang.String} object.
+   * @param value a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> param(String name, Object value) {
+    if (null == this.params) {
+      params = new HashMap<String, Object>();
+    }
+    params.put(name, value);
+    return this;
+  }
+
+  /** {@inheritDoc} */
+  public OqlBuilder<T> limit(final PageLimit limit) {
+    this.limit = limit;
+    return this;
+  }
+
+  /**
+   * <p>
+   * limit.
+   * </p>
+   * 
+   * @param pageNo a int.
+   * @param pageSize a int.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> limit(final int pageNo, final int pageSize) {
+    this.limit = new PageLimit(pageNo, pageSize);
+    return this;
+  }
+
+  /**
+   * <p>
+   * cacheable.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> cacheable() {
+    this.cacheable = true;
+    return this;
+  }
+
+  /**
+   * <p>
+   * cacheable.
+   * </p>
+   * 
+   * @param cacheable a boolean.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> cacheable(final boolean cacheable) {
+    this.cacheable = cacheable;
+    return this;
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param condition a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> where(final Condition condition) {
+    if (Strings.isNotEmpty(statement)) { throw new RuntimeException(
+        "cannot add condition to a exists statement"); }
+    conditions.add(condition);
+    return this;
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> where(final String content) {
+    return where(new Condition(content));
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> where(final String content, Object param1) {
+    return where(new Condition(content, param1));
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   * @param param2 a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> where(final String content, Object param1, Object param2) {
+    return where(new Condition(content, param1, param2, null));
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   * @param param2 a {@link java.lang.Object} object.
+   * @param param3 a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> where(final String content, Object param1, Object param2, Object param3) {
+    return where(new Condition(content, param1, param2, param3));
+  }
+
+  /**
+   * 添加一组条件<br>
+   * query中不能添加条件集合作为一个条件,因此这里命名没有采用有区别性的addAll
+   * 
+   * @param cons a {@link java.util.Collection} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> where(final Collection<Condition> cons) {
+    conditions.addAll(cons);
+    return this;
+  }
+
+  /**
+   * 声明排序字符串
+   * 
+   * @param orderBy 排序字符串
+   * @return 查询构建器
+   */
+  public OqlBuilder<T> orderBy(final String orderBy) {
+    return orderBy(Order.parse(orderBy));
+  }
+
+  /**
+   * 指定排序字符串的位置
+   * 
+   * @param index 从0开始
+   * @param orderBy 排序字符串
+   * @return 查询构建器
+   */
+  public OqlBuilder<T> orderBy(final int index, final String orderBy) {
+    if (null != orders) {
+      if (Strings.isNotEmpty(statement)) { throw new RuntimeException(
+          "cannot add order by to a exists statement."); }
+      this.orders.addAll(index, Order.parse(orderBy));
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * orderBy.
+   * </p>
+   * 
+   * @param order a {@link com.ekingstar.commons.collection.Order} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> orderBy(final Order order) {
+    if (null != order) { return orderBy(Collections.singletonList(order)); }
+    return this;
+  }
+
+  /**
+   * <p>
+   * cleanOrders.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> clearOrders() {
+    this.orders.clear();
+    return this;
+  }
+
+  /**
+   * <p>
+   * orderBy.
+   * </p>
+   * 
+   * @param orders a {@link java.util.List} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> orderBy(final List<Order> orders) {
+    if (null != orders) {
+      if (Strings.isNotEmpty(statement)) { throw new RuntimeException(
+          "cannot add order by to a exists statement."); }
+      this.orders.addAll(orders);
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * select.
+   * </p>
+   * 
+   * @param what a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> select(final String what) {
+    if (null == what) {
+      this.select = null;
+    } else {
+      if (what.toLowerCase().trim().startsWith("select")) {
+        this.select = what;
+      } else {
+        this.select = "select " + what;
+      }
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * newFrom.
+   * </p>
+   * 
+   * @param from a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> newFrom(final String from) {
+    if (null == from) {
+      this.from = null;
+    } else {
+      if (Strings.contains(from.toLowerCase(), "from")) {
+        this.from = from;
+      } else {
+        this.from = "from " + from;
+      }
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * groupBy.
+   * </p>
+   * 
+   * @param what a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> groupBy(final String what) {
+    if (Strings.isNotEmpty(what)) {
+      groups.add(what);
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * Having subclause.
+   * </p>
+   * 
+   * @param what having subclause
+   * @return this
+   */
+  public OqlBuilder<T> having(final String what) {
+    Assert.isTrue(null != groups && !groups.isEmpty());
+    if (Strings.isNotEmpty(what)) having = what;
+    return this;
+  }
+
+  /**
+   * 形成计数查询语句,如果不能形成,则返回""
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  protected String genCountStatement() {
+    StringBuilder countString = new StringBuilder("select count(*) ");
+    // 原始查询语句
+    final String genQueryStr = genQueryStatement(false);
+    if (Strings.isEmpty(genQueryStr)) { return ""; }
+    final String lowerCaseQueryStr = genQueryStr.toLowerCase();
+
+    if (Strings.contains(lowerCaseQueryStr, " group ")) { return ""; }
+    if (Strings.contains(lowerCaseQueryStr, " union ")) { return ""; }
+
+    final int indexOfFrom = findIndexOfFrom(lowerCaseQueryStr);
+    final String selectWhat = lowerCaseQueryStr.substring(0, indexOfFrom);
+    final int indexOfDistinct = selectWhat.indexOf("distinct");
+    // select distinct a from table;
+    if (-1 != indexOfDistinct) {
+      if (Strings.contains(selectWhat, ",")) {
+        return "";
+      } else {
+        countString = new StringBuilder("select count(");
+        countString.append(genQueryStr.substring(indexOfDistinct, indexOfFrom)).append(") ");
+      }
+    }
+
+    int orderIdx = genQueryStr.lastIndexOf(" order ");
+    if (-1 == orderIdx) orderIdx = genQueryStr.length();
+    countString.append(genQueryStr.substring(indexOfFrom, orderIdx));
+    return countString.toString();
+  }
+
+  /**
+   * Find index of from
+   * 
+   * @param query
+   * @return -1 or from index
+   */
+  private int findIndexOfFrom(String query) {
+    if (query.startsWith("from")) return 0;
+    int fromIdx = query.indexOf(" from ");
+    if (-1 == fromIdx) return -1;
+    final int first = query.substring(0, fromIdx).indexOf("(");
+    if (first > 0) {
+      int leftCnt = 1;
+      int i = first + 1;
+      while (leftCnt != 0 && i < query.length()) {
+        if (query.charAt(i) == '(') leftCnt++;
+        else if (query.charAt(i) == ')') leftCnt--;
+        i++;
+      }
+      if (leftCnt > 0) return -1;
+      else {
+        fromIdx = query.indexOf(" from ", i);
+        return (fromIdx == -1) ? -1 : fromIdx + 1;
+      }
+    } else {
+      return fromIdx + 1;
+    }
+  }
+
+  /**
+   * <p>
+   * forEntity.
+   * </p>
+   * 
+   * @param entityClass a {@link java.lang.Class} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public OqlBuilder<T> forEntity(final Class<T> entityClass) {
+    this.entityClass = entityClass;
+    return this;
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected Lang getLang() {
+    return Lang.HQL;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>entityClass</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.Class} object.
+   */
+  public Class<T> getEntityClass() {
+    return entityClass;
+  }
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/QueryBean.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/QueryBean.java
new file mode 100755
index 0000000..5dda29d
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/QueryBean.java
@@ -0,0 +1,198 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.builder;
+
+import java.util.Map;
+
+import com.ekingstar.commons.lang.Strings;
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.hibernate.query.Lang;
+import com.ekingstar.hibernate.query.LimitQuery;
+import com.ekingstar.hibernate.query.Query;
+
+/**
+ * <p>
+ * QueryBean class.
+ * </p>
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class QueryBean<T> implements LimitQuery<T> {
+
+  private Lang lang;
+
+  private String statement;
+
+  private String countStatement;
+
+  private PageLimit limit;
+
+  private boolean cacheable;
+
+  private Map<String, Object> params;
+
+  /**
+   * Returns count query {@link com.ekingstar.hibernate.query.Query}.
+   */
+  public Query<T> getCountQuery() {
+    if (Strings.isEmpty(countStatement)) { return null; }
+    QueryBean<T> bean = new QueryBean<T>();
+    bean.setStatement(countStatement);
+    bean.setLang(lang);
+    bean.setParams(params);
+    bean.setCacheable(cacheable);
+    return bean;
+  }
+
+  /**
+   * Returns statement.
+   */
+  public String getStatement() {
+    return statement;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>countStatement</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String getCountStatement() {
+    return countStatement;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>limit</code>.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.page.PageLimit} object.
+   */
+  public PageLimit getLimit() {
+    return limit;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>params</code>.
+   * </p>
+   * 
+   * @return a {@link java.util.Map} object.
+   */
+  public Map<String, Object> getParams() {
+    return params;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>statement</code>.
+   * </p>
+   * 
+   * @param statement a {@link java.lang.String} object.
+   */
+  public void setStatement(String statement) {
+    this.statement = statement;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>countStatement</code>.
+   * </p>
+   * 
+   * @param countStatement a {@link java.lang.String} object.
+   */
+  public void setCountStatement(String countStatement) {
+    this.countStatement = countStatement;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>limit</code>.
+   * </p>
+   * 
+   * @param limit a {@link com.ekingstar.commons.page.PageLimit} object.
+   */
+  public void setLimit(PageLimit limit) {
+    this.limit = limit;
+  }
+
+  /** {@inheritDoc} */
+  public LimitQuery<T> limit(PageLimit limit) {
+    this.limit = new PageLimit(limit.getPageNo(), limit.getPageSize());
+    return this;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>cacheable</code>.
+   * </p>
+   * 
+   * @param cacheable a boolean.
+   */
+  public void setCacheable(boolean cacheable) {
+    this.cacheable = cacheable;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>params</code>.
+   * </p>
+   * 
+   * @param params a {@link java.util.Map} object.
+   */
+  public void setParams(Map<String, Object> params) {
+    this.params = params;
+  }
+
+  /**
+   * <p>
+   * isCacheable.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean isCacheable() {
+    return cacheable;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>lang</code>.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.Lang} object.
+   */
+  public Lang getLang() {
+    return lang;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>lang</code>.
+   * </p>
+   * 
+   * @param lang a {@link com.ekingstar.hibernate.query.Lang} object.
+   */
+  public void setLang(Lang lang) {
+    this.lang = lang;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/SqlBuilder.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/SqlBuilder.java
new file mode 100755
index 0000000..42d8bf0
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/SqlBuilder.java
@@ -0,0 +1,384 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.builder;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.ekingstar.commons.collection.CollectUtils;
+import com.ekingstar.commons.collection.Order;
+import com.ekingstar.commons.lang.Assert;
+import com.ekingstar.commons.lang.Strings;
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.hibernate.query.Lang;
+
+/**
+ * sql查询
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class SqlBuilder extends AbstractQueryBuilder<Object[]> {
+  /**
+   * <p>
+   * sql.
+   * </p>
+   * 
+   * @param queryStr a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public static SqlBuilder sql(final String queryStr) {
+    SqlBuilder sqlQuery = new SqlBuilder();
+    sqlQuery.statement = queryStr;
+    return sqlQuery;
+  }
+
+  /**
+   * <p>
+   * genCountStatement.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  protected String genCountStatement() {
+    return "select count(*) from (" + genQueryStatement(false) + ")";
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected Lang getLang() {
+    return Lang.SQL;
+  }
+
+  /**
+   * <p>
+   * alias.
+   * </p>
+   * 
+   * @param alias a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder alias(final String alias) {
+    this.alias = alias;
+    return this;
+  }
+
+  /**
+   * <p>
+   * join.
+   * </p>
+   * 
+   * @param path a {@link java.lang.String} object.
+   * @param alias a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder join(final String path, final String alias) {
+    from += " join " + path + " " + alias;
+    return this;
+  }
+
+  /**
+   * <p>
+   * join.
+   * </p>
+   * 
+   * @param joinMode a {@link java.lang.String} object.
+   * @param path a {@link java.lang.String} object.
+   * @param alias a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder join(final String joinMode, final String path, final String alias) {
+    from += " " + joinMode + " join " + path + " " + alias;
+    return this;
+  }
+
+  /** {@inheritDoc} */
+  public SqlBuilder params(final Map<String, Object> params) {
+    this.params = CollectUtils.newHashMap(params);
+    ;
+    return this;
+  }
+
+  /**
+   * <p>
+   * param.
+   * </p>
+   * 
+   * @param name a {@link java.lang.String} object.
+   * @param value a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder param(String name, Object value) {
+    if (null == this.params) {
+      params = new HashMap<String, Object>();
+    }
+    params.put(name, value);
+    return this;
+  }
+
+  /** {@inheritDoc} */
+  public SqlBuilder limit(final PageLimit limit) {
+    this.limit = limit;
+    return this;
+  }
+
+  /**
+   * <p>
+   * limit.
+   * </p>
+   * 
+   * @param pageNo a int.
+   * @param pageSize a int.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder limit(final int pageNo, final int pageSize) {
+    this.limit = new PageLimit(pageNo, pageSize);
+    return this;
+  }
+
+  /**
+   * <p>
+   * cacheable.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder cacheable() {
+    this.cacheable = true;
+    return this;
+  }
+
+  /**
+   * <p>
+   * cacheable.
+   * </p>
+   * 
+   * @param cacheable a boolean.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder cacheable(final boolean cacheable) {
+    this.cacheable = cacheable;
+    return this;
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param condition a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder where(final Condition condition) {
+    conditions.add(condition);
+    return this;
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder where(final String content) {
+    return where(new Condition(content));
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder where(final String content, Object param1) {
+    return where(new Condition(content, param1));
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   * @param param2 a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder where(final String content, Object param1, Object param2) {
+    return where(new Condition(content, param1, param2, null));
+  }
+
+  /**
+   * <p>
+   * where.
+   * </p>
+   * 
+   * @param content a {@link java.lang.String} object.
+   * @param param1 a {@link java.lang.Object} object.
+   * @param param2 a {@link java.lang.Object} object.
+   * @param param3 a {@link java.lang.Object} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder where(final String content, Object param1, Object param2, Object param3) {
+    return where(new Condition(content, param1, param2, param3));
+  }
+
+  /**
+   * 添加一组条件<br>
+   * query中不能添加条件集合作为一个条件,因此这里命名没有采用有区别性的addAll
+   * 
+   * @param cons a {@link java.util.Collection} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder where(final Collection<Condition> cons) {
+    conditions.addAll(cons);
+    return this;
+  }
+
+  /**
+   * <p>
+   * orderBy.
+   * </p>
+   * 
+   * @param orderBy a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder orderBy(final String orderBy) {
+    this.orders.addAll(Order.parse(orderBy));
+    return this;
+  }
+
+  /**
+   * <p>
+   * orderBy.
+   * </p>
+   * 
+   * @param order a {@link com.ekingstar.commons.collection.Order} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder orderBy(final Order order) {
+    if (null != order) {
+      this.orders.add(order);
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * cleanOrders.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder clearOrders() {
+    this.orders.clear();
+    return this;
+  }
+
+  /**
+   * <p>
+   * orderBy.
+   * </p>
+   * 
+   * @param orders a {@link java.util.List} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder orderBy(final List<Order> orders) {
+    if (null != orders) {
+      this.orders.addAll(orders);
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * select.
+   * </p>
+   * 
+   * @param what a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder select(final String what) {
+    if (null == what) {
+      this.select = null;
+    } else {
+      if (Strings.contains(what.toLowerCase(), "select")) {
+        this.select = what;
+      } else {
+        this.select = "select " + what;
+      }
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * newFrom.
+   * </p>
+   * 
+   * @param from a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder newFrom(final String from) {
+    if (null == from) {
+      this.from = null;
+    } else {
+      if (Strings.contains(from.toLowerCase(), "from")) {
+        this.from = from;
+      } else {
+        this.from = " from " + from;
+      }
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * groupBy.
+   * </p>
+   * 
+   * @param what a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlBuilder} object.
+   */
+  public SqlBuilder groupBy(final String what) {
+    if (Strings.isNotEmpty(what)) groups.add(what);
+    return this;
+  }
+
+  /**
+   * <p>
+   * Having subclause.
+   * </p>
+   * 
+   * @param what having subclause
+   * @return a {@link com.ekingstar.hibernate.query.builder.OqlBuilder} object.
+   */
+  public SqlBuilder having(final String what) {
+    Assert.isTrue(null != groups && !groups.isEmpty());
+    if (Strings.isNotEmpty(what)) having = what;
+    return this;
+  }
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/SqlQuery.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/SqlQuery.java
new file mode 100755
index 0000000..bc632c3
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/builder/SqlQuery.java
@@ -0,0 +1,389 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.builder;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import com.ekingstar.commons.collection.CollectUtils;
+import com.ekingstar.commons.collection.Order;
+import com.ekingstar.commons.lang.Strings;
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.hibernate.query.Lang;
+import com.ekingstar.hibernate.query.Query;
+
+/**
+ * sql查询
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public class SqlQuery extends AbstractQuery<Object> {
+
+  /** Constant <code>INNER_JOIN=" left join "</code> */
+  public static final String INNER_JOIN = " left join ";
+
+  /** Constant <code>OUTER_JOIN=" outer join "</code> */
+  public static final String OUTER_JOIN = " outer join ";
+
+  /** Constant <code>LEFT_OUTER_JOIN=" left outer join "</code> */
+  public static final String LEFT_OUTER_JOIN = " left outer join ";
+
+  /** Constant <code>RIGHT_OUTER_JOIN=" right outer join "</code> */
+  public static final String RIGHT_OUTER_JOIN = " right outer join ";
+
+  protected String select;
+
+  protected String from;
+
+  protected List<Condition> conditions = CollectUtils.newArrayList();
+
+  protected List<Order> orders = CollectUtils.newArrayList();
+
+  protected List<String> groups = CollectUtils.newArrayList();
+
+  /**
+   * <p>
+   * Constructor for SqlQuery.
+   * </p>
+   */
+  public SqlQuery() {
+    super();
+  }
+
+  /**
+   * <p>
+   * Constructor for SqlQuery.
+   * </p>
+   * 
+   * @param queryStr a {@link java.lang.String} object.
+   */
+  public SqlQuery(final String queryStr) {
+    super();
+    this.queryStr = queryStr;
+  }
+
+  /**
+   * <p>
+   * add.
+   * </p>
+   * 
+   * @param condition a {@link com.ekingstar.hibernate.query.builder.Condition} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlQuery} object.
+   */
+  public SqlQuery add(final Condition condition) {
+    conditions.add(condition);
+    return this;
+  }
+
+  /**
+   * 添加一组条件<br>
+   * query中不能添加条件集合作为一个条件,因此这里命名没有采用有区别性的addAll
+   * 
+   * @param cons a {@link java.util.Collection} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlQuery} object.
+   */
+  public SqlQuery add(final Collection<Condition> cons) {
+    conditions.addAll(cons);
+    return this;
+  }
+
+  /**
+   * <p>
+   * addOrder.
+   * </p>
+   * 
+   * @param order a {@link com.ekingstar.commons.collection.Order} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlQuery} object.
+   */
+  public SqlQuery addOrder(final Order order) {
+    if (null != order) {
+      this.orders.add(order);
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * addOrder.
+   * </p>
+   * 
+   * @param orders a {@link java.util.List} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlQuery} object.
+   */
+  public SqlQuery addOrder(final List<Order> orders) {
+    if (null != orders) {
+      this.orders.addAll(orders);
+    }
+    return this;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>select</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String getSelect() {
+    return select;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>select</code>.
+   * </p>
+   * 
+   * @param select a {@link java.lang.String} object.
+   */
+  public void setSelect(final String select) {
+    if (null == select) {
+      this.select = null;
+    } else {
+      if (Strings.contains(select.toLowerCase(), "select")) {
+        this.select = select;
+      } else {
+        this.select = "select " + select;
+      }
+    }
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>conditions</code>.
+   * </p>
+   * 
+   * @return a {@link java.util.List} object.
+   */
+  public List<Condition> getConditions() {
+    return conditions;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>conditions</code>.
+   * </p>
+   * 
+   * @param conditions a {@link java.util.List} object.
+   */
+  public void setConditions(final List<Condition> conditions) {
+    this.conditions = conditions;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>from</code>.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String getFrom() {
+    return from;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>from</code>.
+   * </p>
+   * 
+   * @param from a {@link java.lang.String} object.
+   */
+  public void setFrom(final String from) {
+    if (null == from) {
+      this.from = null;
+    } else {
+      if (Strings.contains(from.toLowerCase(), "from")) {
+        this.from = from;
+      } else {
+        this.from = " from " + from;
+      }
+    }
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>orders</code>.
+   * </p>
+   * 
+   * @return a {@link java.util.List} object.
+   */
+  public List<Order> getOrders() {
+    return orders;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>orders</code>.
+   * </p>
+   * 
+   * @param orders a {@link java.util.List} object.
+   */
+  public void setOrders(final List<Order> orders) {
+    this.orders = orders;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>groups</code>.
+   * </p>
+   * 
+   * @return a {@link java.util.List} object.
+   */
+  public List<String> getGroups() {
+    return groups;
+  }
+
+  /**
+   * <p>
+   * Setter for the field <code>groups</code>.
+   * </p>
+   * 
+   * @param groups a {@link java.util.List} object.
+   */
+  public void setGroups(final List<String> groups) {
+    this.groups = groups;
+  }
+
+  /**
+   * <p>
+   * groupBy.
+   * </p>
+   * 
+   * @param what a {@link java.lang.String} object.
+   * @return a {@link com.ekingstar.hibernate.query.builder.SqlQuery} object.
+   */
+  public SqlQuery groupBy(final String what) {
+    if (Strings.isNotEmpty(what)) {
+      groups.add(what);
+    }
+    return this;
+  }
+
+  /**
+   * 生成查询语句(如果查询语句已经存在则不进行生成)
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String toQueryString() {
+    if (Strings.isNotEmpty(queryStr)) {
+      return queryStr;
+    } else {
+      return genQueryString(true);
+    }
+  }
+
+  /**
+   * <p>
+   * toCountString.
+   * </p>
+   * 
+   * @return a {@link java.lang.String} object.
+   */
+  public String toCountString() {
+    if (Strings.isNotEmpty(countStr)) {
+      return countStr;
+    } else {
+      return "select count(*) from (" + genQueryString(false) + ")";
+    }
+  }
+
+  /**
+   * <p>
+   * genQueryString.
+   * </p>
+   * 
+   * @param hasOrder a boolean.
+   * @return a {@link java.lang.String} object.
+   */
+  protected String genQueryString(final boolean hasOrder) {
+    if (null == from) { return queryStr; }
+    final StringBuilder buf = new StringBuilder(50);
+    buf.append((select == null) ? "" : select).append(' ').append(from);
+    if (!conditions.isEmpty()) {
+      buf.append(" where ").append(Conditions.toQueryString(conditions));
+    }
+    if (!groups.isEmpty()) {
+      buf.append(" group by ");
+      for (final String groupBy : groups) {
+        buf.append(groupBy).append(',');
+      }
+      buf.deleteCharAt(buf.length() - 1);
+    }
+    if (hasOrder && !CollectUtils.isEmpty(orders)) {
+      buf.append(' ').append(Order.toSortString(orders));
+    }
+    return buf.toString();
+  }
+
+  /**
+   * <p>
+   * getParams.
+   * </p>
+   * 
+   * @return a {@link java.util.Map} object.
+   */
+  public Map<String, Object> getParams() {
+    return (null == params) ? Conditions.getParamMap(conditions) : CollectUtils.newHashMap(params);
+  }
+
+  /**
+   * <p>
+   * build.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.Query} object.
+   */
+  public Query<Object> build() {
+    QueryBean<Object> queryBean = new QueryBean<Object>();
+    queryBean.setStatement(toQueryString());
+    queryBean.setParams(CollectUtils.newHashMap(getParams()));
+    if (null != limit) {
+      queryBean.setLimit(new PageLimit(limit.getPageNo(), limit.getPageSize()));
+    }
+    queryBean.setCountStatement(toCountString());
+    queryBean.setCacheable(cacheable);
+    queryBean.setLang(getLang());
+    return queryBean;
+  }
+
+  /**
+   * <p>
+   * getLang.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.hibernate.query.Lang} object.
+   */
+  protected Lang getLang() {
+    return Lang.SQL;
+  }
+
+  /** {@inheritDoc} */
+  public SqlQuery limit(PageLimit limit) {
+    this.limit = limit;
+    return this;
+  }
+
+  /** {@inheritDoc} */
+  public SqlQuery params(Map<String, Object> newParams) {
+    this.params = CollectUtils.newHashMap(newParams);
+    return this;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/limit/AbstractQueryPage.java b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/limit/AbstractQueryPage.java
new file mode 100755
index 0000000..cea01b4
--- /dev/null
+++ b/tools/hqlbuilder/src/main/java/com/ekingstar/hibernate/query/limit/AbstractQueryPage.java
@@ -0,0 +1,249 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.query.limit;
+
+import java.util.Iterator;
+
+import com.ekingstar.commons.page.Page;
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.commons.page.PageWapper;
+import com.ekingstar.commons.page.SinglePage;
+import com.ekingstar.hibernate.query.LimitQuery;
+
+/**
+ * 基于查询的分页。<br>
+ * 当使用或导出大批量数据时,使用者仍以List的方式进行迭代。<br>
+ * 该实现则是内部采用分页方式。
+ * 
+ * @author chaostone
+ * @version $Id: $
+ */
+public abstract class AbstractQueryPage<T> extends PageWapper<T> {
+
+  protected int pageNo = 0;
+
+  protected int maxPageNo = 0;
+
+  protected LimitQuery<T> query;
+
+  /** {@inheritDoc} */
+  abstract public Page<T> moveTo(int pageNo);
+
+  /**
+   * <p>
+   * Constructor for AbstractQueryPage.
+   * </p>
+   */
+  public AbstractQueryPage() {
+    super();
+  }
+
+  /**
+   * <p>
+   * Constructor for AbstractQueryPage.
+   * </p>
+   * 
+   * @param query a {@link com.ekingstar.hibernate.query.LimitQuery} object.
+   */
+  public AbstractQueryPage(LimitQuery<T> query) {
+    this.query = query;
+    if (null != query) {
+      if (null == query.getLimit()) {
+        query.limit(new PageLimit(pageNo, Page.DEFAULT_PAGE_SIZE));
+      } else {
+        pageNo = query.getLimit().getPageNo() - 1;
+      }
+    }
+  }
+
+  /**
+   * 按照单个分页数据设置.
+   * 
+   * @param page a {@link com.ekingstar.commons.collection.page.SinglePage} object.
+   */
+  protected void setPageData(SinglePage<T> page) {
+    setPage(page);
+    this.pageNo = page.getPageNo();
+    this.maxPageNo = page.getMaxPageNo();
+  }
+
+  /**
+   * <p>
+   * next.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.collection.page.Page} object.
+   */
+  public Page<T> next() {
+    return moveTo(pageNo + 1);
+  }
+
+  /**
+   * <p>
+   * previous.
+   * </p>
+   * 
+   * @return a {@link com.ekingstar.commons.collection.page.Page} object.
+   */
+  public Page<T> previous() {
+    return moveTo(pageNo - 1);
+  }
+
+  /**
+   * <p>
+   * hasNext.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean hasNext() {
+    return maxPageNo > pageNo;
+  }
+
+  /**
+   * <p>
+   * hasPrevious.
+   * </p>
+   * 
+   * @return a boolean.
+   */
+  public boolean hasPrevious() {
+    return pageNo > 1;
+  }
+
+  /**
+   * <p>
+   * getFirstPageNo.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getFirstPageNo() {
+    return 1;
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>maxPageNo</code>.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getMaxPageNo() {
+    return maxPageNo;
+  }
+
+  /**
+   * <p>
+   * getNextPageNo.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getNextPageNo() {
+    return getPage().getNextPageNo();
+  }
+
+  /**
+   * <p>
+   * Getter for the field <code>pageNo</code>.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getPageNo() {
+    return pageNo;
+  }
+
+  /**
+   * <p>
+   * getPageSize.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getPageSize() {
+    return query.getLimit().getPageSize();
+  }
+
+  /**
+   * <p>
+   * getPreviousPageNo.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getPreviousPageNo() {
+    return getPage().getPreviousPageNo();
+  }
+
+  /**
+   * <p>
+   * getTotal.
+   * </p>
+   * 
+   * @return a int.
+   */
+  public int getTotal() {
+    return getPage().getTotal();
+  }
+
+  /**
+   * <p>
+   * iterator.
+   * </p>
+   * 
+   * @return a {@link java.util.Iterator} object.
+   */
+  public Iterator<T> iterator() {
+    return new PageIterator<T>(this);
+  }
+
+}
+
+class PageIterator<T> implements Iterator<T> {
+
+  private final AbstractQueryPage<T> queryPage;
+
+  private int dataIndex;
+
+  public PageIterator(AbstractQueryPage<T> queryPage) {
+    this.queryPage = queryPage;
+    this.dataIndex = 0;
+  }
+
+  public boolean hasNext() {
+    return (dataIndex < queryPage.getPage().getItems().size()) || (queryPage.hasNext());
+  }
+
+  public T next() {
+    if (dataIndex < queryPage.getPage().size()) {
+      return queryPage.getPage().getItems().get(dataIndex++);
+    } else {
+      queryPage.next();
+      dataIndex = 0;
+      return queryPage.getPage().getItems().get(dataIndex++);
+    }
+  }
+
+  public void remove() {
+
+  }
+
+}
diff --git a/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/TestModel.java b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/TestModel.java
new file mode 100755
index 0000000..e583d2f
--- /dev/null
+++ b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/TestModel.java
@@ -0,0 +1,33 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate;
+
+public class TestModel {
+
+  private String name;
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/ConditionTest.java b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/ConditionTest.java
new file mode 100755
index 0000000..d7e34db
--- /dev/null
+++ b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/ConditionTest.java
@@ -0,0 +1,51 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.builder;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+import com.ekingstar.hibernate.query.builder.Condition;
+import com.ekingstar.hibernate.query.builder.Conditions;
+
+@Test
+public class ConditionTest {
+
+  public void testGetNamedParams() {
+    Condition condition = new Condition("std.id =:stAd_id1 and std.name like :name");
+    List<String> names = condition.getParamNames();
+    assertEquals(names.size(), 2);
+    assertEquals(names.get(0), "stAd_id1");
+    assertEquals(names.get(1), "name");
+  }
+
+  public void testVarArgs() {
+    Condition c = new Condition("entity.code =:code  entity.id in (:ids)", "aa", new Long[] { 1L });
+    assertEquals(2, Conditions.getParamMap(c).size());
+
+    Condition c1 = new Condition("entity.id in (:ids)", new Long[] { 1L, 2L });
+    assertEquals(1, Conditions.getParamMap(c1).size());
+    assertTrue((Conditions.getParamMap(c1).get("ids").getClass().isArray()));
+  }
+
+}
diff --git a/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/ConditionsTest.java b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/ConditionsTest.java
new file mode 100755
index 0000000..8b9ca02
--- /dev/null
+++ b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/ConditionsTest.java
@@ -0,0 +1,64 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.builder;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.ekingstar.commons.collection.CollectUtils;
+import com.ekingstar.hibernate.query.builder.Condition;
+import com.ekingstar.hibernate.query.builder.Conditions;
+
+@Test
+public class ConditionsTest {
+
+  @BeforeClass
+  protected void setUp() throws Exception {
+
+  }
+
+  public void testGetParamMap() throws Exception {
+    List<Condition> conditions = CollectUtils.newArrayList();
+    conditions.add(new Condition("std.id=:std_id", 1L));
+    Map<String, Object> params = Conditions.getParamMap(conditions);
+    assertEquals(params.size(), 1);
+    assertEquals(params.get("std_id"), 1L);
+  }
+
+  public void testToQueryString() {
+    List<Condition> conditions = CollectUtils.newArrayList();
+    conditions.add(new Condition("user.id=:user_id", 1L));
+    conditions.add(new Condition("user.name=:std_name", "name"));
+    assertEquals(Conditions.toQueryString(conditions), "(user.id=:user_id) and (user.name=:std_name)");
+  }
+
+  public void testConcat() {
+    List<Condition> conditions = CollectUtils.newArrayList();
+    conditions.add(new Condition("user.id=:user_id", 1L));
+    conditions.add(new Condition("user.name=:std_name", "name"));
+    Condition rs = Conditions.or(conditions);
+    assertEquals(rs.getContent(), "((user.id=:user_id) or (user.name=:std_name))");
+  }
+
+}
diff --git a/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/OqlBuilderTest.java b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/OqlBuilderTest.java
new file mode 100755
index 0000000..f5f75d2
--- /dev/null
+++ b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/builder/OqlBuilderTest.java
@@ -0,0 +1,88 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.builder;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.ekingstar.hibernate.TestModel;
+import com.ekingstar.hibernate.query.LimitQuery;
+import com.ekingstar.hibernate.query.builder.Condition;
+import com.ekingstar.hibernate.query.builder.OqlBuilder;
+
+@Test
+public class OqlBuilderTest {
+
+  public void testToCountString1() throws Exception {
+    OqlBuilder<TestModel> queryBuilder = OqlBuilder.from(TestModel.class, "model");
+    LimitQuery<?> query = (LimitQuery<?>) queryBuilder.build();
+    assertEquals("select count(*) from com.ekingstar.hibernate.TestModel model", query.getCountQuery()
+        .getStatement());
+    queryBuilder.where(new Condition("name like :name", "testName"));
+    query = (LimitQuery<?>) queryBuilder.build();
+    assertTrue(query.getCountQuery().getStatement().endsWith("(name like :name)"));
+  }
+
+  public void testToCountString2() throws Exception {
+    OqlBuilder<Object> queryBuilder = OqlBuilder
+        .hql("from Ware where price is not null order by releaseDate desc "
+            + " union all from Ware where price is null order by releaseDate desc");
+    LimitQuery<Object> query = (LimitQuery<Object>) queryBuilder.build();
+    assertNull(query.getCountQuery());
+  }
+
+  public void testToCountString3() throws Exception {
+    OqlBuilder<Object> queryBuilder = OqlBuilder.from("Ware", "w");
+    queryBuilder.select("(select count(*) from Product p where p.ware=w) pcount,w.id");
+    queryBuilder.where("w.price is not null and exists (select * from Orders o where o.product=p)").orderBy(
+        "w.releaseDate desc");
+    LimitQuery<Object> query = (LimitQuery<Object>) queryBuilder.build();
+    assertEquals(
+        query.getStatement(),
+        "select (select count(*) from Product p where p.ware=w) pcount,w.id from Ware w "
+            + "where (w.price is not null and exists (select * from Orders o where o.product=p)) order by w.releaseDate desc");
+    assertEquals(
+        query.getCountQuery().getStatement(),
+        "select count(*) from Ware w where (w.price is not null and exists (select * from Orders o where o.product=p))");
+  }
+
+  public void testToCountString4() throws Exception {
+    OqlBuilder<Object> queryBuilder = OqlBuilder
+        .hql("from Ware where price is not null order by releaseDate desc ");
+    LimitQuery<Object> query = (LimitQuery<Object>) queryBuilder.build();
+    assertEquals("select count(*) from Ware where price is not null", query.getCountQuery().getStatement());
+  }
+
+  public void testToCountString5() throws Exception {
+    OqlBuilder<Object> queryBuilder = OqlBuilder.hql("from Ware where price is not null");
+    LimitQuery<Object> query = (LimitQuery<Object>) queryBuilder.build();
+    assertEquals("select count(*) from Ware where price is not null", query.getCountQuery().getStatement());
+  }
+
+  public void testHaving() throws Exception {
+    OqlBuilder<Object> queryBuilder = OqlBuilder.from("SomeClass a ").groupBy("a.name").having("sum(a.id)>0");
+    Assert.assertEquals(queryBuilder.build().getStatement(),
+        "from SomeClass a  group by a.name having sum(a.id)>0");
+  }
+
+}
diff --git a/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/limit/MockQueryPage.java b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/limit/MockQueryPage.java
new file mode 100755
index 0000000..88ef7ff
--- /dev/null
+++ b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/limit/MockQueryPage.java
@@ -0,0 +1,54 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.limit;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.ekingstar.commons.page.Page;
+import com.ekingstar.commons.page.SinglePage;
+import com.ekingstar.hibernate.query.LimitQuery;
+import com.ekingstar.hibernate.query.limit.AbstractQueryPage;
+
+public class MockQueryPage extends AbstractQueryPage<String> {
+
+  public MockQueryPage() {
+
+  }
+
+  public MockQueryPage(LimitQuery<String> query) {
+    super(query);
+    next();
+  }
+
+  public Page<String> moveTo(int pageNo) {
+    SinglePage<String> page = new SinglePage<String>();
+    page.setPageNo(pageNo);
+    page.setPageSize(super.getPageSize());
+    List<String> datas = new ArrayList<String>(getPageSize());
+    for (int i = 0; i < getPageSize(); i++) {
+      datas.add(String.valueOf(i) + " of " + pageNo);
+    }
+    page.setItems(datas);
+    page.setTotal(100);
+    setPageData(page);
+    return this;
+  }
+
+}
diff --git a/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/limit/QueryPageTest.java b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/limit/QueryPageTest.java
new file mode 100755
index 0000000..ea3672a
--- /dev/null
+++ b/tools/hqlbuilder/src/test/java/com/ekingstar/hibernate/limit/QueryPageTest.java
@@ -0,0 +1,43 @@
+/*
+ * Beangle, Agile Java/Scala Development Scaffold and Toolkit
+ *
+ * Copyright (c) 2005-2013, Beangle Software.
+ *
+ * Beangle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Beangle is distributed in the hope that it will be useful.
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Beangle.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.ekingstar.hibernate.limit;
+
+import static org.testng.Assert.assertNotNull;
+
+import java.util.Iterator;
+
+import org.testng.annotations.Test;
+
+import com.ekingstar.commons.page.PageLimit;
+import com.ekingstar.hibernate.query.LimitQuery;
+import com.ekingstar.hibernate.query.builder.OqlBuilder;
+
+@Test
+public class QueryPageTest {
+
+  public void testMove() throws Exception {
+    OqlBuilder<String> query = OqlBuilder.from(String.class, "dd");
+    query.limit(new PageLimit(1, 2));
+    MockQueryPage page = new MockQueryPage((LimitQuery<String>) query.build());
+    for (Iterator<String> iterator = page.iterator(); iterator.hasNext();) {
+      String data = iterator.next();
+      assertNotNull(data);
+    }
+  }
+}