Enterprise ApplicationDevelopment with Ext JSand Spring
上QQ阅读APP看书,第一时间看更新

Introducing the Java Persistence Query Language

Everyone reading this book should be familiar with SQL queries and how they work. Constructing a simple query against the ttt_company table to retrieve all records would look something like:

select * from ttt_company

Restricting the result set to companies starting with G would look like the following code line:

select * from ttt_company where company_name like "G%"

In JPA, we are dealing with entities and relationships between entities. The Java Persistence Query Language (JPQL) is used to formulate queries in a similar way to SQL. The previously mentioned statement will be written in JPQL as follows:

SELECT c FROM Company c

And the statement that follows is written as such:

SELECT c FROM Company c WHERE c.companyName LIKE 'G%'

The following are the major differences between SQL and JPQL:

  • JPQL class and field names are case sensitive. When we are dealing with classes, the class name must start with an uppercase letter. All the fields must have the exact case as defined in the class. The following statement will not compile as the company entity starts with a lowercase c:
    SELECT c FROM company c WHERE c.companyName LIKE 'G%'
  • JPQL keywords are case insensitive. The preceding statement could just as well have been written as follows:
    select c from Company c where c.companyName like 'G%'
  • JPQL uses aliases to define instances and relationships between the instances. In the previous examples, the lowercase c is used as the alias in the SELECT and WHERE clauses.
  • JPQL queries may be static (defined in an annotation) or dynamic (built and executed at runtime). Static queries are compiled once and looked up whenever required. This makes static queries faster to use and more performant.
  • JPQL queries are translated into SQL; they are then executed against the underlying database. This translation allows for database-specific query optimization in the persistence engine.
  • JPQL has a rich set of functions to define conditional expressions. These expressions are translated into the correct SQL for the underlying database. This means that developers no longer need to write database-specific SQL statements. Switching between databases will not require any coding as the JPQL statements abstract the underlying SQL required to execute the statement.

Note

We strongly recommend you spend time learning about JPQL. There are many excellent books available that are dedicated to JPA and JPQL; they explain advanced usage. There are also many online tutorials and JPQL examples on the Internet. It is beyond the scope of this book to go beyond the basics, and we leave it to you to delve into this rich language further.

Defining named queries

The reverse engineering process generated a set of @NamedQuery annotations in each class, one for each persistent field. The Company class, for example, had the following named queries defined:

@NamedQueries({
  @NamedQuery(name = "Company.findAll", query = "SELECT c FROM Company c"),
  @NamedQuery(name = "Company.findByIdCompany", query = "SELECT c FROM Company c WHERE c.idCompany = :idCompany"),
  @NamedQuery(name = "Company.findByCompanyName", query = "SELECT c FROM Company c WHERE c.companyName = :companyName")}) 

Each @NamedQuery name must be unique within the persistence engine; hence, it is prefixed with the name of the class. The first query name, Company.findAll, represents the full list of the Company objects. The second query uses a named parameter, idCompany, as a placeholder for a value provided at runtime. Named parameters are always prefixed with the colon symbol. You should spend some time browsing the queries generated in the Java classes to become familiar with the basic JPQL syntax. We will learn more about named queries and how they are used in the following chapters.