Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   *  Copyright 2009-2014 Pavel Ponec
   *
   *  Licensed under the Apache License, Version 2.0 (the "License");
   *  you may not use this file except in compliance with the License.
   *  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
  *  Unless required by applicable law or agreed to in writing, software
  *  distributed under the License is distributed on an "AS IS" BASIS,
  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
 
 package org.ujorm.orm;
 
 import java.util.List;
 import org.ujorm.Key;
ORM query.

Author(s):
Pavel Ponec
Composed:
1 - 1 Session
Composed:
1 - 1 CriterionDecoder
 
 public class Query<UJO extends OrmUjoimplements Iterable<UJO> {

    
The base table
 
     final private MetaTable table;
    
Modified columns, the default value is the null.

 
     private ArrayList<ColumnWrappercolumns;
    
Database session
 
     private Session session;
    
Data constraint
 
     private Criterion<UJO> criterion;
    
Select distinct
 
     private boolean distinct;
    
An internal decoder
 
     private CriterionDecoder decoder;
    
An internal info
 
     private String statementInfo;

    
A list of keys to sorting
 
     private List<Key<UJO,?>> orderBy;
    
Set the first row to retrieve. If not set, rows will be retrieved beginnning from row 0.
 
     private long offset = 0;
    
The max row count for the resultset. The value -1 means no change, value 0 means no limit (or a default value by the JDBC driver implementation.
 
     private int limit = -1;
    
Retrieves the number of result set rows that is the default fetch size of the Query objects
 
     private int fetchSize = -1;
    
Pessimistic lock request
 
     private boolean lockRequest;
    
SQL parameters for a Native view
 
     private SqlParameters sqlParameters;

    
Create new ORM query. A one from argument is mandatory.

Parameters:
table Table model is mandatory
criterion If criterion is null, then the ForAll criterion is used.
session Session
 
     public Query(final MetaTable tablefinal Criterion<UJO> criterionfinal Session session) {
         this. = table;
         this. = null;
         this. = criterion;
         this. = session;
 
         orderByMany(); // set an undefined ordering
     }

    
Create new ORM query without a session. An open session must be .setSession(org.ujorm.orm.Session) assigned before executing a database request.

Parameters:
table Table model
criterion If criterion is null, then a TRUE constant criterion is used.
See also:
setSession(org.ujorm.orm.Session)
 
     public Query(final MetaTable tablefinal Criterion<UJO> criterion) {
         this(tablecriterionnull);
    }

    
Get Handler
    private OrmHandler getHandler() {
        OrmHandler handler = null;
        if ( != null) {
            handler = .getDatabase().getOrmHandler();
        } else if ( != null) {
            handler = .getHandler();
        }
        if (handler == null) {
            throw new IllegalStateException("The base class must be assigned first!");
        }
        return handler;
    }

    
An open session must be assigned before executing a database request.
    public Query<UJO> setSession(Session session) {
        this. = session;
        return this;
    }

    
Returns a database row count along a current limit and offset attribues.

See also:
getCount()
    public long getLimitedCount() {
        long result = getCount();
        // Recalculate the count by a limit and offset:
        if (isOffset()) {
            result -= ;
            if (result<0) {
                result = 0L;
            }
        }
        if (>=0
        &&  <result
        ){
            result = ;
        }
        return result;
    }

    
Returns a count of the items

    public long getCount() {
        final long result = .getRowCount(this);
        return result;
    }
    public <ITEM> void setParameter(Key<UJO,ITEM> property, ITEM value) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    
Add a new Criterion.

Parameters:
criterion Parameter is mandatory and must not be NULL.
See also:
Session.createQuery(org.ujorm.criterion.Criterion) createQuery(Criterion)
setCriterion(org.ujorm.criterion.Criterion) setCriterion(..)
    public void addCriterion(Criterion<UJO> criterionthrows IllegalArgumentException {
        if (criterion==null) {
            throw new IllegalArgumentException("Argument must not be null");
        }
        this. = this.!=null
            ? this..and(criterion)
            : criterion
            ;
        clearDecoder();
    }

    
Set a new Criterion. There is recommended

Parameters:
criterion The value NULL is allowed because the value is replaced internally to expression Criterion.where(true). A MetaTable parameter must be specified in the constuctor for this case.
See also:
Session.createQuery(org.ujorm.criterion.Criterion) createQuery(Criteron)
addCriterion(org.ujorm.criterion.Criterion) addCriterion(..)
    public Query<UJO> setCriterion(Criterion<UJO> criterion) {
        this. = criterion != null
            ? criterion
            : ((Criterion<UJO>) (Criterion) Criterion.where(true))
            ;
        clearDecoder();
        return this;
    }

    
Criterion
    public Criterion<UJO> getCriterion() {
        return ;
    }

    
Method builds and retuns a criterion decoder. The new decoder is cached to a next order by change.
    @SuppressWarnings("unchecked")
    final public CriterionDecoder getDecoder() {
        if (==null) {
            final List<Keyrelations = new ArrayList<Key>(16);
            for (Key key : ) {
                if (key.isComposite()) {
                    relations.add(key);
                }
            }
            for (ColumnWrapper column : getColumns()) {
                if (column.isCompositeKey()) {
                    relations.add(column.getKey());
                }
            }
             = new CriterionDecoder(relations);
        }
        return ;
    }

    
If the attribute 'order by' is changed so the decoder must be clearder.
    private void clearDecoder() {
        setDecoder(null);
    }

    
If the attribute 'order by' is changed so the decoder must be clearder.
    @PackagePrivate void setDecoder(CriterionDecoder decoder) {
        this. = decoder;
        this. = null;
    }

    
Session
    public Session getSession() {
        return ;
    }

    
Table Type
    public MetaTable getTableModel() {
        return ;
    }

    
Get Column Collection
    public List<ColumnWrappergetColumns() {
        return !=null
                ? 
                : getDefaultColumns();
    }

    
Returns all direct columns of the base table.
    protected List<ColumnWrappergetDefaultColumns() {
        return (List<ColumnWrapper>) (List..getList();
    }

    
Create a new column List.
    @SuppressWarnings("empty-statement")
    public ColumnWrapper[] getColumnArray() {
        final Collection<ColumnWrapperresColumns = getColumns();
        final ColumnWrapper[] result = resColumns.toArray(new ColumnWrapper[resColumns.size()]);
        return result;
    }

    
Create a new iterator by the query. The result iterator can be used in the Java statement for(...) directly.
NOTE: The items can be iterated inside a database transaction only, in other case call the next expression:
iterator().toList()

    @Override
    public UjoIterator<UJO> iterator() {
        final UjoIterator<UJO> result = UjoIterator.getInstance(this);
        return result;
    }

    
Create a new iterator by the query.

Deprecated:
Use iterator() instead of.
See also:
iterator()
    @Deprecated
    final public UjoIterator<UJO> iterate() {
        return iterator();
    }

    
There is recommended to use the method iterator() rather. The method calls internally the next statement:
iterator().toList()

    public List<UJO> list() {
        return iterator().toList();
    }

    
Create list and Load all lazy values for the current parameter recursively until optional depth.
Performance note: all lazy values are loaded using the one more SQL statement per one relation Key. The method can consume a lot of memory in dependence on the database row count and content of the Criteron.

Parameters:
depth The object resursion depth where value 0 means: do not any lazy loading. level. The current release supports only values: 0 and 1.
See also:
iterator()
org.ujorm.orm.utility.OrmTools.loadLazyValues(java.lang.Iterable,int)
org.ujorm.orm.utility.OrmTools.loadLazyValuesAsBatch(org.ujorm.orm.Query)
    public List<UJO> list(int depth) {
        switch (depth) {
            case 0: return list();
            case 1: return OrmTools.loadLazyValuesAsBatch((Querythis);
            defaultthrow new IllegalArgumentException("The method supports only two values 0 and 1 in the current release");
        }
    }

    
Returns a unique result or null if no result item (database row) was found.

Throws:
java.util.NoSuchElementException Result is not unique.
See also:
iterator()
exists()
    public UJO uniqueResult() throws NoSuchElementException {
        final UjoIterator<UJO> iterator = iterator();
        if (!iterator.hasNext()) {
            return null;
        }
        final UJO result = iterator.next();
        if (iterator.hasNext()) {
            iterator.close();
            throw new NoSuchElementException("Result is not unique for: " + );
        }
        return result;
    }

    
The method performs a new database request and returns result of the function UjoIterator.hasNext(). The result TRUE means the query covers one item (database row) at least.

    public boolean exists() {
        int $limit = ;
         = 1;
        final UjoIterator<UJO> iterator = iterator();
        final boolean result = iterator.hasNext();
        iterator.close();
         = $limit;
        return result;
    }

    
Get the order item list. The method returns a not null result always.
    final public List<Key<UJO,?>> getOrderBy() {
        return ;
    }

    
Get the order item array. The method returns a not null result always.
    @SuppressWarnings("unchecked")
    final public Key<UJO,?>[] getOrderAsArray() {
        return .toArray(new Key[.size()]);
    }

    
Set an order of the rows by a SQL ORDER BY phrase.

Deprecated:
Use the orderByMany(org.ujorm.Key[]) method instead of
See also:
orderByMany(org.ujorm.Key[])
    @Deprecated
    public Query<UJO> setOrder(Key... order) {
        return orderByMany(order);
    }

   
Set an order of the rows by a SQL ORDER BY phrase.
    public Query<UJO> orderBy(Key<UJO,?> orderItem) {
        return orderByMany(new Key[]{orderItem});
    }

   
Set an order of the rows by a SQL ORDER BY phrase.
    public Query<UJO> orderBy
        ( Key<UJO,?> orderItem1
        , Key<UJO,?> orderItem2
        ) {
        return orderByMany(new Key[]{orderItem1orderItem2});
    }

   
Set an order of the rows by a SQL ORDER BY phrase.
    public Query<UJO> orderBy
        ( Key<UJO,?> orderItem1
        , Key<UJO,?> orderItem2
        , Key<UJO,?> orderItem3
        ) {
        return orderByMany(new Key[]{orderItem1orderItem2orderItem3});
    }

   
Set an order of the rows by a SQL ORDER BY phrase.
WARNING: the parameters are not type checked.
    @SuppressWarnings("unchecked")
    public final Query<UJO> orderByMany(Key... orderItems) {
        clearDecoder();
        this. = new ArrayList(Math.max(orderItems.length, 4));
        for (final Key p : orderItems) {
            this..add(p);
        }
        return this;
    }

   
Set the one column to reading from database table. Other columns will return a default value, no exception will be throwed.
WARNING 1: assigning an column from a view is forbidden.
WARNING 2: the parameters are not type checked in compile time, use setColumn(..) and addColumn() for this feature.
WARNING 3: assigning an column from a view is forbidden.

Parameters:
column A Property to select. A composite Property is allowed however only the first item will be used.
See also:
setColumn(org.ujorm.Key) setColumn(Property)
    public Query<UJO> addColumn(Key<UJO,?> columnthrows IllegalArgumentException {
        clearDecoder();
        final MetaColumn mc = getHandler().findColumnModel(getLastProperty(column));
        if (mc==null) {
            throw new IllegalArgumentException("Column " + column.toStringFull() + " was not foud in the meta-model");
        }
        final ColumnWrapper wColumn = column.isComposite() 
                ? new ColumnWrapperImpl(mccolumn)
                : mc;
        if (==null) {
             = new ArrayList<ColumnWrapper>(getDefaultColumns());
        }
        addMissingColumn(wColumntruetrue);
        return this;
    }

   
Set the one column to reading from database table. Other columns will return a default value, no exception will be throwed.
WARNING: assigning an column from a view is forbidden.

Parameters:
column A Property to select. A composite Property is allowed however only the first item will be used.
See also:
addColumn(org.ujorm.Key) addColumn(Property)
    @SuppressWarnings("unchecked")
    public Query<UJO> setColumn(Key<UJO, ?> columnthrows IllegalArgumentException {
        return setColumns(falsecolumn);
    }

   
Set an list of required columns to reading from database table. Other columns (out of the list) will return a default value, no exception will be throwed.

Parameters:
addPrimaryKey If the column list does not contains a primary key then the one can be included.
columns A Key list including a compositer one to database select. The method does not check collumn duplicities.
See also:
setColumn(org.ujorm.Key) setColumn(Property)
addColumn(org.ujorm.Key) addColumn(Property)
    @SuppressWarnings("unchecked")
    public final Query<UJO> setColumns(boolean addPrimaryKeyKey... columns)  throws IllegalArgumentException {
        return setColumns(addPrimaryKeytruecolumns);
    }

   
Set an list of required columns to reading from database table. Other columns (out of the list) will return a default value, no exception will be throwed.
WARNING 1: the parameters are not type checked in compile time, use setColumn(..) and addColumn() for this feature.
WARNING 2: assigning an column from a view is forbidden.

Parameters:
addPrimaryKey If the column list doesn't contain a primary key of the base Entity then the one will be included.
addChilds Add all childs of the all foreign keys.
columns A Key list including a compositer one to database select. The method does not check collumn duplicities.
See also:
setColumn(org.ujorm.Key) setColumn(Property)
addColumn(org.ujorm.Key) addColumn(Property)
    public final Query<UJO> setColumns(boolean addPrimaryKeyboolean addChildsKey... columnsthrows IllegalArgumentException {
        clearDecoder();
        if (columns.length > 1) {
            // There is strongly preferred to sort the keys from direct to the relations (along a count of the relations in the key) due
            // an entity relation column cleans related foreign key.
            // For exmample use the set Item[order.id, order.date] instead of Item[order, order.date]
            Arrays.sort(columns);
        }
        this. = new ArrayList<ColumnWrapper>(columns.length + 3);
        final OrmHandler handler = getHandler();
        for (Key column : columns) {
            final MetaColumn mc = (MetaColumnhandler.findColumnModel(getLastProperty(column), true);
            final ColumnWrapper cw = column.isComposite() 
                    ? new ColumnWrapperImpl(mccolumn)
                    : mc;
            addMissingColumn(cwaddChildsfalse);
        }
        if (addPrimaryKey) {
            addMissingColumn(.getFirstPK(), falsetrue);
        }
        return this;
    }

    
Add a missing column. The method is for an internal use.

Parameters:
column Add the column for case it is missing in the column list
addChilds Add all childs of the foreign key.
checkDuplicities Check a duplicity column
    protected void addMissingColumn(final ColumnWrapper columnfinal boolean addChildsfinal boolean checkDuplicities) {
        final int hashCode = column.hashCode();
        if (checkDuplicities) {
            for (final ColumnWrapper c : ) {
                if (c.hashCode()==hashCode && column.equals(c)) {
                    return// The same column is assigned
                }
            }
        }
        if (addChilds) {
            final MetaColumn model = column.getModel();
            if (model.isForeignKey()) {
                for (ColumnWrapper columnWrapper : model.getForeignTable().getColumns()) {
                    final Key myKey = column.getKey().add(columnWrapper.getKey());
                    final ColumnWrapper cw = new ColumnWrapperImpl(columnWrapper.getModel(), myKey);
                    addMissingColumn(cwfalsetrue);
                }
            } else {
               .add(column);
            }
        } else {
            .add(column);
        }
    }

    
Only direct keys are supported
    private Key getLastProperty(Key p) {
        return p.isComposite()
            ? ((CompositeKey)p).getLastKey()
            : p ;
    }

   
Set an order of the rows by a SQL ORDER BY phrase. WARNING: the list items are not type checked. If you need an item chacking, use the method addOrderBy(org.ujorm.Key) rather.

    @SuppressWarnings("unchecked")
    public Query<UJO> orderBy(Collection<KeyorderItems) {
        clearDecoder();
        if (orderItems==null) {
            return orderByMany(); // empty sorting
        } else {
            this..clear();
            this..addAll( (Collection)orderItems );
        }
        return this;
    }

    
Add an item to the end of order list.
    public Query<UJO> addOrderBy(Key<UJO,?> property) {
        clearDecoder();
        .add(property);
        return this;
    }

    
Returns an order column. A method for an internal use only.
    public MetaColumn readOrderColumn(int ithrows IllegalStateException {
        final Key property = .get(i);
        final MetaRelation2Many result = .getHandler().findColumnModel(property);
        if (result instanceof MetaColumn) {
            return (MetaColumnresult;
        } else {
            String msg = "Property '" + .getType().getSimpleName() + "." + property + "' is not a persistent table column";
            throw new IllegalStateException(msg);
        }
    }

    
Has this Query an offset?
    public boolean isOffset() {
        return  > 0;
    }

    
Get the first row to retrieve (offset). Default value is 0.
    final public long getOffset() {
        return ;
    }

    
Get the first row to retrieve (offset). Default value is 0.

    public Query<UJO> setOffset(int offset) {
        this. = offset;
        return this;
    }

    
The max row count for the resultset. The value -1 means no change, value 0 means no limit (or a default value by the JDBC driver implementation.

See also:
getLimit()
    final public boolean isLimit() {
        return >0;
    }

    
The max row count for the resultset. The value -1 means no change, value 0 means no limit (or a default value by the JDBC driver implementation.

See also:
isLimit()
    final public int getLimit() {
        return ;
    }

    
The max row count for the resultset. The value -1 means no change, value 0 means no limit (or a default value by the JDBC driver implementation.

    public Query<UJO> setLimit(int limit) {
        this. = limit;
        return this;
    }

    
Set a limit and offset.

Parameters:
limit The max row count for the resultset. The value -1 means no change, value 0 means no limit (or a default value by the JDBC driver implementation.
offset Get the first row to retrieve (offset). Default value is 0.
See also:
setLimit(int)
setOffset(int)
    public Query<UJO> setLimit(int limitlong offset) {
        this. = limit;
        this. = offset;
        return this;
    }

    
Use the method setLimit(int) rather.

See also:
setLimit(int)
    @Deprecated
    final public Query<UJO> setMaxRows(int limit) {
        return setLimit(limit);
    }

    
Gives the JDBC driver a hint as to the number of rows that should be fetched from the database when more rows are needed.

    public int getFetchSize() {
        return ;
    }

    
Retrieves the number of result set rows that is the default fetch size for ResultSet objects generated from this Statement object.

    public Query<UJO> setFetchSize(int fetchSize) {
        this. = fetchSize;
        return this;
    }

    
Create a PreparedStatement including assigned parameter values
    public PreparedStatement getStatement() {
        return .getStatement(this).getPreparedStatement();
    }

    
Get the SQL statement or null, of statement is not known yet.
    public String getStatementInfo() {
        return ;
    }

    
Set the SQL statement
    /*default*/ void setStatementInfo(String statementInfo) {
        this. = statementInfo;
    }

    
Pessimistic lock request
    public boolean isLockRequest() {
        return ;
    }

    
Pessimistic lock request. A default value is false.

    public Query<UJO> setLockRequest(boolean lockRequest) {
        this. = lockRequest;
        return this;
    }

    
Set pessimistic lock request. A default value is false.

    public Query<UJO> setLockRequest() {
        return setLockRequest(true);
    }
    @Override
    public String toString() {
        if (!=null) {
            return ;
        }
        StringBuilder result = new StringBuilder(64);
        if (!=null) {
            result.append('(').append(.getType().getSimpleName()).append(") ");
        }
        if (!=null) {
            result.append(" criterion: ");
            result.append();
        }
        if (!=null && .size() > 0) {
            result.append(" | ordered by: ");
            for (Key<UJO, ?> ujoProperty : ) {
                result.append(ujoProperty)
                      .append(" ")
                      .append(ujoProperty.isAscending() ? "ASC" : "DESC")
                      .append(", ")
                      ;
            }
        }
        return result.length()>0
            ? result.toString()
            : super.toString()
            ;
    }

    
Select DISTINCT for a unique row result
    public boolean isDistinct() {
        return ;
    }

    
Select DISTINCT for a unique row result
    public Query<UJO> setDistinct(boolean distinct) {
        this. = distinct;
        return this;
    }

    
Select DISTINCT for a unique row result
    public Query<UJO> setDistinct() {
        return setDistinct(true);
    }

    
Get a SQL parameters of the Native view
    public SqlParameters getSqlParameters() {
        return ;
    }

    
Set a SQL parameters of the Native View

Throws:
java.lang.IllegalArgumentException The SQL parameters can be used for the VIEW only
See also:
org.ujorm.orm.annot.View
    public Query<UJO> setSqlParameters(SqlParameters sqlParametersthrows IllegalArgumentException {
        this. = sqlParameters;
        return this;
    }

    
Set a SQL parameters of the Native View

Throws:
java.lang.IllegalArgumentException The SQL parameters can be used for the VIEW only
See also:
org.ujorm.orm.annot.View
    public Query<UJO> setSqlParameters(Object ... parametersthrows IllegalArgumentException {
        return setSqlParameters(new SqlParameters(parameters));
    }
    // --------------- INNER CLASS ---------------

    
Compare two keys according to count of the KeyCount on sequence
    @PackagePrivate static final Comparator<KeyINNER_KEY_COMPARATOR = new Comparator<Key>() {
            public int compare(final Key k1final Key k2) {
                if (!k1.isComposite()) {
                    return k2.isComposite() ? -1 : 0;
                }
                else if (k2.isComposite()) {
                    final int c1 = ((CompositeKey)k1).getCompositeCount();
                    final int c2 = ((CompositeKey)k2).getCompositeCount();
                    return c1 == c2 ? 0
                         : c1 < c2 ? -1 : 1;
                } else {
                    return 1;
                }
            }
        };
New to GrepCode? Check out our FAQ X