All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.beangle.commons.dao.query.builder.OqlBuilder Maven / Gradle / Ivy

The newest version!
/*
 * Beangle, Agile Development Scaffold and Toolkits.
 *
 * Copyright © 2005, The Beangle Software.
 *
 * This program 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.
 *
 * This program 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 this program.  If not, see .
 */
package org.beangle.commons.dao.query.builder;

import static org.beangle.commons.lang.Strings.concat;
import static org.beangle.commons.lang.Strings.contains;
import static org.beangle.commons.lang.Strings.isEmpty;
import static org.beangle.commons.lang.Strings.isNotEmpty;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.beangle.commons.collection.Order;
import org.beangle.commons.collection.page.PageLimit;
import org.beangle.commons.dao.query.Lang;
import org.beangle.commons.entity.metadata.EntityType;
import org.beangle.commons.entity.metadata.Model;
import org.beangle.commons.entity.util.EntityUtils;
import org.beangle.commons.lang.Assert;
import org.beangle.commons.lang.Strings;

/**
 * 实体类查询 Object Query Language Builder
 *
 * @author chaostone
 * @version $Id: $
 */
public class OqlBuilder extends AbstractQueryBuilder {

  /** 查询实体类 */
  protected Class entityClass;

  /**
   * Constructor for OqlBuilder.
   */
  protected OqlBuilder() {
    super();
  }

  /**
   * hql.
   *
   * @param hql a {@link java.lang.String} object.
   * @param  a E object.
   * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object.
   */
  public static  OqlBuilder hql(final String hql) {
    OqlBuilder query = new OqlBuilder();
    query.statement = hql;
    return query;
  }

  /**
   * from.
   *
   * @param from a {@link java.lang.String} object.
   * @param  a E object.
   * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object.
   */
  public static  OqlBuilder from(final String from) {
    OqlBuilder query = new OqlBuilder();
    query.newFrom(from);
    return query;
  }

  /**
   * from.
   *
   * @param entityName a {@link java.lang.String} object.
   * @param alias a {@link java.lang.String} object.
   * @param  a E object.
   * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object.
   */
  @SuppressWarnings("unchecked")
  public static  OqlBuilder from(final String entityName, final String alias) {
    EntityType type = Model.getType(entityName);
    OqlBuilder query = new OqlBuilder();
    if (null != type) query.entityClass = (Class) type.getEntityClass();
    query.alias = alias;
    query.select = "select " + alias;
    query.from = concat("from ", entityName, " ", alias);
    return query;
  }

  /**
   * from.
   *
   * @param entityClass a {@link java.lang.Class} object.
   * @param  a E object.
   * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object.
   */
  public static  OqlBuilder from(final Class entityClass) {
    EntityType type = Model.getType(entityClass.getName());
    if (null == type) type = Model.getType(entityClass);
    return from(entityClass, EntityUtils.getCommandName(type.getEntityName()));
  }

  /**
   * from.
   *
   * @param entityClass a {@link java.lang.Class} object.
   * @param alias a {@link java.lang.String} object.
   * @param  a E object.
   * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object.
   */
  @SuppressWarnings("unchecked")
  public static  OqlBuilder from(final Class entityClass, final String alias) {
    EntityType type = Model.getType(entityClass.getName());
    if (null == type) type = Model.getType(entityClass);
    OqlBuilder query = new OqlBuilder();
    query.entityClass = (Class) type.getEntityClass();
    query.alias = alias;
    query.select = "select " + alias;
    query.from = concat("from ", type.getEntityName(), " ", alias);
    return query;
  }

  /**
   * alias.
   *
   * @param alias a {@link java.lang.String} object.
   * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object.
   */
  public OqlBuilder alias(final String alias) {
    this.alias = alias;
    return this;
  }

  /**
   * join.
   *
   * @param path a {@link java.lang.String} object.
   * @param alias a {@link java.lang.String} object.
   * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object.
   */
  public OqlBuilder join(final String path, final String alias) {
    from = concat(from, " join ", path, " ", alias);
    return this;
  }

  /**
   * join.
   *
   * @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 org.beangle.commons.dao.query.builder.OqlBuilder} object.
   */
  public OqlBuilder join(final String joinMode, final String path, final String alias) {
    from = concat(from, " ", joinMode, " join ", path, " ", alias);
    return this;
  }

  public OqlBuilder params(final Map params) {
    this.params.putAll(params);
    return this;
  }

  /**
   * param.
   *
   * @param name a {@link java.lang.String} object.
   * @param value a {@link java.lang.Object} object.
   * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object.
   */
  public OqlBuilder param(String name, Object value) {
    params.put(name, value);
    return this;
  }

  public OqlBuilder limit(final PageLimit limit) {
    this.limit = limit;
    return this;
  }

  /**
   * limit.
   *
   * @param pageIndex a int.
   * @param pageSize a int.
   * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object.
   */
  public OqlBuilder limit(final int pageIndex, final int pageSize) {
    this.limit = new PageLimit(pageIndex, pageSize);
    return this;
  }

  /**
   * cacheable.
   *
   * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object.
   */
  public OqlBuilder cacheable() {
    this.cacheable = true;
    return this;
  }

  /**
   * cacheable.
   *
   * @param cacheable a boolean.
   * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object.
   */
  public OqlBuilder cacheable(final boolean cacheable) {
    this.cacheable = cacheable;
    return this;
  }

  /**
   * where.
   *
   * @param conditions a {@link org.beangle.commons.dao.query.builder.Condition} object.
   * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object.
   */
  public OqlBuilder where(final Condition... conditions) {
    if (isNotEmpty(statement)) throw new RuntimeException("cannot add condition to a exists statement");
    return where(Arrays.asList(conditions));
  }

  /**
   * @param content
   * @return
   */
  public OqlBuilder where(String content) {
    Condition con = new Condition(content);
    return where(con);
  }

  public OqlBuilder where(String content, Object param1) {
    Condition con = new Condition(content);
    con.param(param1);
    return where(con);
  }

  public OqlBuilder where(String content, Object param1, Object param2) {
    Condition con = new Condition(content);
    con.param(param1);
    con.param(param2);
    return where(con);
  }

  /**
   * 为了接受数组作为参数,防止java将数组展开为可变参数特定以下几个重致where函数,
   *
   * @param content
   * @param param1
   * @param param2
   * @param param3
   * @param varparams
   * @see https://github.com/beangle/library/issues/231
   * @return
   */
  public OqlBuilder where(final String content, Object param1, Object param2, Object param3,
      Object... varparams) {
    Condition con = new Condition(content);
    con.param(param1);
    con.param(param2);
    con.param(param3);

    if (varparams != null && varparams.length > 0) {
      for (Object a : varparams) {
        con.param(a);
      }
    }
    return where(con);
  }

  /**
   * 添加一组条件
* query中不能添加条件集合作为一个条件,因此这里命名没有采用有区别性的addAll * * @param cons a {@link java.util.Collection} object. * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object. */ public OqlBuilder where(final Collection cons) { conditions.addAll(cons); return params(Conditions.getParamMap(cons)); } public OqlBuilder tailOrder(final String orderBy) { List os=Order.parse(orderBy); if(os.isEmpty()){ this.tailOrder=null; }else{ this.tailOrder=os.get(0); } return this; } /** * 声明排序字符串 * * @param orderBy 排序字符串 * @return 查询构建器 */ public OqlBuilder orderBy(final String orderBy) { return orderBy(Order.parse(orderBy)); } /** * 指定排序字符串的位置 * * @param index 从0开始 * @param orderBy 排序字符串 * @return 查询构建器 */ public OqlBuilder orderBy(final int index, final String orderBy) { if (null != orders) { if (isNotEmpty(statement)) { throw new RuntimeException("cannot add order by to a exists statement."); } this.orders.addAll(index, Order.parse(orderBy)); } return this; } /** * orderBy. * * @param order a {@link org.beangle.commons.collection.Order} object. * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object. */ public OqlBuilder orderBy(final Order order) { if (null != order) { return orderBy(Collections.singletonList(order)); } return this; } /** * cleanOrders. * * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object. */ public OqlBuilder clearOrders() { this.orders.clear(); return this; } /** * orderBy. * * @param orders a {@link java.util.List} object. * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object. */ public OqlBuilder orderBy(final List orders) { if (null != orders) { if (isNotEmpty(statement)) { throw new RuntimeException("cannot add order by to a exists statement."); } this.orders.addAll(orders); } return this; } /** *

* select. *

* * @param what a {@link java.lang.String} object. * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object. */ public OqlBuilder 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; } /** * newFrom. * * @param from a {@link java.lang.String} object. * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object. */ public OqlBuilder 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; } /** * groupBy. * * @param what a {@link java.lang.String} object. * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object. */ public OqlBuilder groupBy(final String what) { if (Strings.isNotEmpty(what)) { groups.add(what); } return this; } /** *

* Having subclause. *

* * @param what having subclause * @return this */ public OqlBuilder 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 (isEmpty(genQueryStr)) { return ""; } final String lowerCaseQueryStr = genQueryStr.toLowerCase(); if (contains(lowerCaseQueryStr, " group ")) { return ""; } if (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 (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; } } /** * forEntity. * * @param entityClass a {@link java.lang.Class} object. * @return a {@link org.beangle.commons.dao.query.builder.OqlBuilder} object. */ public OqlBuilder forEntity(final Class entityClass) { this.entityClass = entityClass; return this; } @Override protected Lang getLang() { return Lang.HQL; } /** * Getter for the field entityClass. * * @return a {@link java.lang.Class} object. */ public Class getEntityClass() { return entityClass; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy