开发用的工具
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("std.id=?",new Long(2));
+ * 或者 Condition("std.id=:std_id",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);
+ }
+ }
+}