org.hdpagination.dataaccess.support.orm
Class JPAQueryCallbackWrapper

java.lang.Object
  extended by org.hdpagination.dataaccess.support.QueryBuilder
      extended by org.hdpagination.dataaccess.support.orm.JPAQueryCallbackWrapper
All Implemented Interfaces:
java.io.Serializable, QueryCallback, JPAQueryCallback

public class JPAQueryCallbackWrapper
extends QueryBuilder
implements JPAQueryCallback

This class is used as a convenient wrapper class for JPAQueryCallback. It simplifies the way to generate an instance of JPAQueryCallback based on the searching criteria fields. Typically, there are two types of query parameters binding in the JP QL (Java Persistence Query Language) Queries. One is positioned parameter (JDBC-style ? parameters) and another one is named parameter. This wrapper class is used for positioned parameter (JDBC-style) type. If you prefer named parameter type, JPAQueryCallbackNamedParamWrapper should be used.

The way to use JPAQueryCallbackWrapper usually follows the following steps:

(1) Call its static factory method getInstance to get an initial instance of JPAQueryCallbackWrapper.

(2) Call addRestriction methods from the instance.

(3) Call setOrderBy method if you want to sort the search result.

A sample code is as follows:

   JPAQueryCallbackWrapper callback = JPAQueryCallbackWrapper.newInstance("select p from ProductVO p", "p")
       .addRestriction( Restrictions.eq("p.prodNo", crit.getProdNo()) )
       .addRestriction( Restrictions.in("p.madeIn", crit.getMadeIn()) )
       .addRestriction( Restrictions.contains("p.description", crit.getDescription()) )
       .addRestriction( Restrictions.range("p.price", priceFrom, priceTo))
       .setOrderBy("p.madeIn");

Behind the scene, the way JPAQueryCallbackWrapper generates the full query statement can be described as:

  • It uses the value of 'selectFrom' (the first argument from static factory methods newInstance) to construct an initial query statement.
  • It goes through all the restrictions (added by calling the methods addRestriction). For each restriction:
  •       (1) It appends the keyword 'WHERE' or 'AND' to the query statement first. If it is the first restriction, 'WHERE' is added; otherwise 'AND' is added.

          (2) Then it appends the restriction's clause statement (e.g. p.description LIKE ?1) to the query statement. As specified by JPA Specification, input parameters are designated by the question mark (?) prefix followed by an integer. So an integer (starting from 1) will be calculated automatically (based on the position of the current restriction in the list) and inserted after the question mark (?).

  • If orderBy is set, then append the generated ORDER BY clause to the query statement.
  • Since:
    1.3.1
    Author:
    Liangfeng Ren
    See Also:
    Serialized Form

    Field Summary
     
    Fields inherited from class org.hdpagination.dataaccess.support.QueryBuilder
    asending, countStatement, orderBy, selectFrom
     
    Constructor Summary
    JPAQueryCallbackWrapper(java.lang.String selectFrom, java.lang.String countArgument)
               Please note that the factory method newInstance(java.lang.String, java.lang.String) is encouraged to use to create an object of JPAQueryCallbackWrapper rather than instantiating it directly.
     
    Method Summary
     JPAQueryCallbackWrapper addRestriction(Restriction restriction)
              Add restriction applied to the query SELECT statement.
     JPAQueryCallbackWrapper addRestriction(java.lang.String clause)
              Add restriction applied to the query SELECT statement.
     JPAQueryCallbackWrapper addRestriction(java.lang.String clause, java.util.List params)
              Add restriction applied to the query SELECT statement.
     JPAQueryCallbackWrapper addRestriction(java.lang.String clause, java.lang.Object param)
              Add restriction applied to the query SELECT statement.
     JPAQueryCallbackWrapper addRestriction(java.lang.String clause, java.lang.Object[] params)
              Add restriction applied to the query SELECT statement.
     java.lang.String getCountRecordsQueryStatement()
              Query statement to count total records.
     java.lang.String getQueryStatement()
              Query statement(e.g.
    static JPAQueryCallbackWrapper newInstance(java.lang.String selectFrom, java.lang.String countArgument)
              As a convenient (or shortcut) factory method to get an JPAQueryCallbackWrapper object.
     java.util.List processQueriedResult(java.util.List queriedResult)
              process the result from calling javax.persistence.Query.list() method in JPAQueryTemplate.query(QueryCallback callback, int pageSize, int pageNo), and the value(java.util.List) returned by current method will be used as the return value of JPAQueryTemplate.query(QueryCallback callback, int pageSize, int pageNo).
     JPAQueryCallbackWrapper setOrderBy(java.lang.String orderBy)
              Set order by
     JPAQueryCallbackWrapper setOrderBy(java.lang.String orderBy, boolean ascending)
              Set order by
     void setQueryResultProcessor(QueryResultProcessor queryResultProcessor)
              Set an instance of QueryResultProcessor to process the query result (java.util.List) before EntityManager is closed.
     void setValues(javax.persistence.Query query)
              Operate on Query instance to bind parameters
     
    Methods inherited from class org.hdpagination.dataaccess.support.QueryBuilder
    getQueryOrder, setCountRecordsQueryStatement, setQueryOrder
     
    Methods inherited from class java.lang.Object
    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
     
    Methods inherited from interface org.hdpagination.core.QueryCallback
    getQueryOrder, setQueryOrder
     

    Constructor Detail

    JPAQueryCallbackWrapper

    public JPAQueryCallbackWrapper(java.lang.String selectFrom,
                                   java.lang.String countArgument)

    Please note that the factory method newInstance(java.lang.String, java.lang.String) is encouraged to use to create an object of JPAQueryCallbackWrapper rather than instantiating it directly.

    Parameters:
    selectFrom - the "SELECT ... FROM .." statement for the JP QL (Java Persistence Query Language) query. It should not contain the "WHERE" clause, otherwise when restrictions are added later, the full generated query statement will not be correct (it contains more than one "WHERE" key words). The methods addRestriction are used to specify the "WHERE" clause. It also should not contain the "ORDER BY" clause, the method setOrderBy is for this purpose.
    countArgument - to query the total number of records, the "SELECT COUNT([countArgument]) FROM ..." statement (generated based on the query statement) needs to be executed. As specified by JPA Specification, the COUNT function takes either an identification variable or a path expression as its argument. This argument will be used as the COUNT function's argument. This argument can not be null or empty, unless the property countRecordsQueryStatement is set explicitly by calling the method JPAQueryCallbackWrapper.setCountRecordsQueryStatement(java.lang.String) (in this case, it will be ignored).
    Method Detail

    setOrderBy

    public JPAQueryCallbackWrapper setOrderBy(java.lang.String orderBy)
    Set order by

    Parameters:
    orderBy - the column after the key word ORDER BY in 'ORDER BY' clause
    Returns:
    this, to enable chaining

    setOrderBy

    public JPAQueryCallbackWrapper setOrderBy(java.lang.String orderBy,
                                              boolean ascending)
    Set order by

    Parameters:
    orderBy - the column after the key word ORDER BY in 'ORDER BY' clause
    ascending - if sorted in ascending order
    Returns:
    this, to enable chaining

    setQueryResultProcessor

    public void setQueryResultProcessor(QueryResultProcessor queryResultProcessor)
    Set an instance of QueryResultProcessor to process the query result (java.util.List) before EntityManager is closed. Its main purpose is to allow you to trigger lazy loading before EntityManager is closed. See sample code is provided in QueryResultProcessor.

    Parameters:
    queryResultProcessor -
    Since:
    1.3.2

    addRestriction

    public JPAQueryCallbackWrapper addRestriction(Restriction restriction)
    Add restriction applied to the query SELECT statement.

    If the argument 'restriction' is not null, the restriction will be appended to the WHERE clause of the SELECT statement to filter the search result. Otherwise, the restriction will not be appended.

    Typically, this method is used together with one of static factory methods from Restrictions. Restrictions provides some static factory methods to generate object of Restriction conditionally based on the parameter value.

    A general rule for some of its simple factory methods (eq, gt, ge, lt, le, contains) is:

  • If the parameter is null or blank (if the type of parameter is java.lang.String), the method returns null. As a result,the restriction will not be added.
  • In a typical search scenario, only if the search criteria field is provided (e.g. its value is not null and empty), the restriction should be applied. This method particularly suits this scenario. You can avoid coding the annoying IF .. ELSE checking by doing this.

    Parameters:
    restriction - If the argument is null, the restriction is not applied to the query.
    Returns:
    this, to enable chaining

    addRestriction

    public JPAQueryCallbackWrapper addRestriction(java.lang.String clause)
    Add restriction applied to the query SELECT statement. The restriction will be appended to the WHERE clause of the SELECT statement to filter the search result.

    Parameters:
    clause - The WHERE clause fragment (after prefixing "WHERE" or "AND" keywords) will be appended to the SELECT statement. Please note that the key words "WHERE" or "AND" should be excluded from this clause fragment. When generating the full query statement, the framework knows when to prefix "WHERE" or "AND". The clause fragment should not contain '?' IN parameter placeholder. This argument can not be null or blank.
    Returns:
    this, to enable chaining

    addRestriction

    public JPAQueryCallbackWrapper addRestriction(java.lang.String clause,
                                                  java.lang.Object param)
    Add restriction applied to the query SELECT statement. The restriction will be appended to the WHERE clause of the SELECT statement to filter the search result.

    Parameters:
    clause - The WHERE clause fragment (after prefixing "WHERE" or "AND" keywords) will be appended to the SELECT statement. Please note that the key words "WHERE" or "AND" should be excluded from this clause fragment. When generating the full query statement, the framework knows when to prefix "WHERE" or "AND". The clause fragment should contain ONE and ONLY ONE '?' IN parameter placeholder. Although, as specified by JPA Specification, input parameters are designated by the question mark (?) prefix followed by an integer, you should NEVER include that integer number. Because the query statement is dynamic, JPAQueryCallbackWrapper will calculate the integer (based on the position of restriction in the list) and insert it after the question mark (?) when generating the full query statement. So "p.madeIn LIKE ?1" is illegal and "p.madeIn LIKE ?" is legal. This argument can not be null or blank.
    param - parameter binding to the '?' IN parameter placeholder in the clause argument. It should be a valid type to call the method javax.persistence.Query.setParameter(int position, Object value) as the second argument. This argument can not be null.
    Returns:
    this, to enable chaining

    addRestriction

    public JPAQueryCallbackWrapper addRestriction(java.lang.String clause,
                                                  java.lang.Object[] params)
    Add restriction applied to the query SELECT statement. The restriction will be appended to the WHERE clause of the SELECT statement to filter the search result.

    Parameters:
    clause - The WHERE clause fragment (after prefixing "WHERE" or "AND" keywords) will be appended to the SELECT statement. Please note that the key words "WHERE" or "AND" should be excluded from this clause fragment. When generating the full query statement, the framework knows when to prefix "WHERE" or "AND". The clause fragment can contain multiple '?' IN parameter placeholders, and the number of placeholders must match the number of elements in the params argument. Although, as specified by JPA Specification, input parameters are designated by the question mark (?) prefix followed by an integer, you should NEVER include that integer number. Because the query statement is dynamic, JPAQueryCallbackWrapper will calculate the integer (based on the position of restriction in the list) and insert it after the question mark (?) when generating the full query statement. So "p.madeIn IN (?1, ?2)" is illegal and "p.madeIn IN (?, ?)" is legal. This argument can not be null or blank.
    params - the parameter values binding to the '?' IN parameter placeholders in the clause argument. Its elements should be a valid type to call the method javax.persistence.Query.setParameter(int position, Object value) as the second argument. This argument can not be null and should contain at least one element.
    Returns:
    this, to enable chaining

    addRestriction

    public JPAQueryCallbackWrapper addRestriction(java.lang.String clause,
                                                  java.util.List params)
    Add restriction applied to the query SELECT statement. The restriction will be appended to the WHERE clause of the SELECT statement to filter the search result.

    Parameters:
    clause - The WHERE clause fragment (after prefixing "WHERE" or "AND" sql keywords) will be appended to the SELECT statement. Please note that the key words "WHERE" or "AND" should be excluded from this clause fragment. When generating the full query statement, the framework knows when to prefix "WHERE" or "AND". The clause fragment can contain multiple '?' IN parameter placeholders, and the number of placeholders must match the number of elements in the params argument. This argument can not be null or blank. Although, as specified by JPA Specification, input parameters are designated by the question mark (?) prefix followed by an integer, you should NEVER include that integer number. Because the query statement is dynamic, JPAQueryCallbackWrapper will calculate the integer (based on the position of restriction in the list) and insert it after the question mark (?) when generating the full query statement. So "p.madeIn IN (?1, ?2)" is illegal and "p.madeIn IN (?, ?)" is legal. This argument can not be null or blank.
    params - the parameter values binding to the '?' IN parameter placeholders in the clause argument. Its elements should be a valid type to call the method javax.persistence.Query.setParameter(int position, Object value) as the second argument. This argument can not be null and should contain at least one element.
    Returns:
    this, to enable chaining

    getQueryStatement

    public java.lang.String getQueryStatement()
    Description copied from interface: QueryCallback
    Query statement(e.g. sql for JDBC and queryString for Hibernate)

    Specified by:
    getQueryStatement in interface QueryCallback
    Returns:

    getCountRecordsQueryStatement

    public java.lang.String getCountRecordsQueryStatement()
    Description copied from class: QueryBuilder
    Query statement to count total records. If this property is not provided, the corresponding QueryTemplate will do some auto translation to generate the "count query statement" based on "queryStatement" property and related persistence technology or database provides (e.g. the way of translation is different between Hibernate and JDBC, Oracle and DB2).

    Specified by:
    getCountRecordsQueryStatement in interface QueryCallback
    Overrides:
    getCountRecordsQueryStatement in class QueryBuilder
    Returns:

    setValues

    public void setValues(javax.persistence.Query query)
    Description copied from interface: JPAQueryCallback
    Operate on Query instance to bind parameters

    Specified by:
    setValues in interface JPAQueryCallback

    processQueriedResult

    public java.util.List processQueriedResult(java.util.List queriedResult)
    Description copied from interface: JPAQueryCallback
    process the result from calling javax.persistence.Query.list() method in JPAQueryTemplate.query(QueryCallback callback, int pageSize, int pageNo), and the value(java.util.List) returned by current method will be used as the return value of JPAQueryTemplate.query(QueryCallback callback, int pageSize, int pageNo).

    Specified by:
    processQueriedResult in interface JPAQueryCallback
    Returns:

    newInstance

    public static JPAQueryCallbackWrapper newInstance(java.lang.String selectFrom,
                                                      java.lang.String countArgument)
    As a convenient (or shortcut) factory method to get an JPAQueryCallbackWrapper object. This factory method is encouraged to create an object of JPAQueryCallbackWrapper rather than instantiating it directly.

    Please note, since version 1.3.2, this method adds a second argument countArgument to fix a design defect not complying with the JPA specification. So if you upgrade from previous version (1.3.1), you will find a compilation error.

    Parameters:
    selectFrom - the "SELECT ... FROM .." statement for the JP QL (Java Persistence Query Language) query. It should not contain the "WHERE" clause, otherwise when restrictions are added later, the full generated query statement will not be correct (it contains more than one "WHERE" key words). The methods addRestriction are used to specify the "WHERE" clause. It also should not contain the "ORDER BY" clause, the method setOrderBy is for this purpose. This argument can not be null or empty.
    countArgument - to query the total number of records, the "SELECT COUNT([countArgument]) FROM ..." statement (generated based on the query statement) needs to be executed. As specified by JPA Specification, the COUNT function takes either an identification variable or a path expression as its argument. This argument will be used as the COUNT function's argument. This argument can not be null or empty, unless the property countRecordsQueryStatement is set explicitly by calling the method JPAQueryCallbackWrapper.setCountRecordsQueryStatement(java.lang.String) (in this case, it will be ignored).
    Returns:


    Copyright © 2008 HDPagination All Rights Reserved.