private StringBuilder createSelectBuilder() {
    String select =
        SqlUtils.createSqlSelect(dao.getTablename(), tablePrefix, dao.getAllColumns(), distinct);
    StringBuilder builder = new StringBuilder(select);

    appendJoinsAndWheres(builder, tablePrefix);

    if (orderBuilder != null && orderBuilder.length() > 0) {
      builder.append(" ORDER BY ").append(orderBuilder);
    }
    return builder;
  }
 /**
  * Expands the query to another entity type by using a JOIN. The given sourceJoin's property is
  * used to match the given destinationProperty of the given destinationEntity. Note that
  * destination entity of the given join is used as the source for the new join to add. In this
  * way, it is possible to compose complex "join of joins" across several entities if required.
  */
 public <J> Join<T, J> join(
     Join<?, T> sourceJoin,
     Property sourceProperty,
     Class<J> destinationEntityClass,
     Property destinationProperty) {
   AbstractDao<J, ?> destinationDao =
       (AbstractDao<J, ?>) dao.getSession().getDao(destinationEntityClass);
   return addJoin(sourceJoin.tablePrefix, sourceProperty, destinationDao, destinationProperty);
 }
  /**
   * Builds a reusable query object for counting rows (Query objects can be executed more
   * efficiently than creating a QueryBuilder for each execution.
   */
  public CountQuery<T> buildCount() {
    String tablename = dao.getTablename();
    String baseSql = SqlUtils.createSqlSelectCountStar(tablename, tablePrefix);
    StringBuilder builder = new StringBuilder(baseSql);
    appendJoinsAndWheres(builder, tablePrefix);

    String sql = builder.toString();
    checkLog(sql);

    return CountQuery.create(dao, sql, values.toArray());
  }
  /**
   * Builds a reusable query object for deletion (Query objects can be executed more efficiently
   * than creating a QueryBuilder for each execution.
   */
  public DeleteQuery<T> buildDelete() {
    if (!joins.isEmpty()) {
      throw new DaoException("JOINs are not supported for DELETE queries");
    }
    String tablename = dao.getTablename();
    String baseSql = SqlUtils.createSqlDelete(tablename, null);
    StringBuilder builder = new StringBuilder(baseSql);

    // tablePrefix gets replaced by table name below. Don't use tableName here because it causes
    // trouble when
    // table name ends with tablePrefix.
    appendJoinsAndWheres(builder, tablePrefix);

    String sql = builder.toString();
    // Remove table aliases, not supported for DELETE queries.
    // TODO(?): don't create table aliases in the first place.
    sql = sql.replace(tablePrefix + ".\"", '"' + tablename + "\".\"");
    checkLog(sql);

    return DeleteQuery.create(dao, sql, values.toArray());
  }
 /**
  * Expands the query to another entity type by using a JOIN. The given sourceProperty is used to
  * match the primary key property of the given destinationEntity.
  */
 public <J> Join<T, J> join(Property sourceProperty, Class<J> destinationEntityClass) {
   AbstractDao<J, ?> destinationDao =
       (AbstractDao<J, ?>) dao.getSession().getDao(destinationEntityClass);
   Property destinationProperty = destinationDao.getPkProperty();
   return addJoin(tablePrefix, sourceProperty, destinationDao, destinationProperty);
 }
 /**
  * Expands the query to another entity type by using a JOIN. The primary key property of the
  * primary entity for this QueryBuilder is used to match the given destinationProperty.
  */
 public <J> Join<T, J> join(Class<J> destinationEntityClass, Property destinationProperty) {
   return join(dao.getPkProperty(), destinationEntityClass, destinationProperty);
 }