Using the Select query

The Select query is a very useful query as it returns a subset of one or more tables of a database. The query can be used to select which rows of a table should be returned and which fields of each row. When the query is executed a list of results is returned and can be processed and/or displayed by the application.

Getting ready

The steps used to create and use a JPQL Select query include:

  1. Obtaining an instance of an EntityManager
  2. Using the createQuery method to create an instance of a Query based on a Select JPQL string argument
  3. Using a method such as the getResultList to execute and return the results of the query

    The easiest place to find an instance of the EntityManager is in a facade class. This is where we will place our JPQL-based methods.

How to do it...

The findAll method is provided as part of the AbstractFacade base class. However, it uses the Criteria API to return a list of every entity in the underlying database. In this recipe, we will focus on how to use JPQL to accomplish the same task.

Add a findAll method to the PatientFacade. Use the @Override annotation to explicitly override the base class method.

@Stateless
public class PatientFacade extends AbstractFacade<Patient> {
@PersistenceContext(unitName = "PatientApplication-ejbPU")
private EntityManager entityManager;
...
@Override
public List<Patient> findAll() {
Query query = entityManager.createQuery("select p FROM Patient p");
List<Patient> list = query.getResultList();
return list;
}
...
}

Add a call to the method in the PatientServlet after the body tag is displayed.

...
out.println("<body>");
List<Patient> firstNameList = patientFacade.findAll();
for (Patient patient : firstNameList) {
out.println("<h5>" + patient.getLastName() + ", " + patient.getFirstName() + "</h5>");
}

Execute the servlet. The result is shown in the following screenshot:

How to do it...

How it works...

The first step created the Query instance using the createQuery method. This required the use of the EntityManager class and a JPQL string. Since this method is a member of the PatientFacade, we used the entityManager variable and the createQuery method to create a Query object.

A JPQL query statement string was used as the argument to the createQuery method. What we would like the query to do is to make a request such as: "Return a list of all patients from the PATIENT table". The Select JPQL statement is designed to return this type of result. The statement consists of two parts: a Select clause and a From clause. The Select clause indicates what we want to retrieve and the From clause determines the origin of this information.

SELECT and FROM are keywords and are not case-sensitive. In these examples, they will be written in upper case to clarify the queries. A JPQL statement meeting our needs looks like this: SELECT p FROM Patient p. We can add this string to complete the process of creating the query.

Notice the use of the entity name, Patient, as opposed to the name of the table, PATIENT. The variable, p, is called an identification variable. All identification variables are declared in a From clause. They can be referenced from a Select clause, or as we will see later, from a Where clause. Optionally, we can use the AS keyword to be more explicit.

SELECT p FROM Patient AS p

For those familiar with SQL, we would use an * to identify all of the fields of the table row. In JPQL, we simply use the identification variable.

Since we are dealing at the entity level, we need an identifier to specify what we want to select. For example, if we had been interested in only the first name of the entity we would use a dot and the field name. The dot is called a navigation operator.

SELECT p.firstName FROM Patient p

To complete the process of creating and executing a query we needed to actually execute the query. The createQuery method only creates the query, it does not execute it. There are several methods we can use to execute the query. Since we are using a Select query and we need multiple entities returned, we used the getResultList method which returns a java.util.List object.

There's more...

A more condensed way of writing the method is to use Java's invocation chaining. This process simply eliminates the middleman and avoids intermediate variables.

public List<Patient> findAll() {
return em.createQuery("SELECT e FROM Patient e").getResultList();
}

There is more to the Select query than we can present here. However, there are several issues we should address including:

  • Eliminating duplicate entities
  • Using the Order By clause

Eliminating duplicate entities

For some tables, certain Select queries may return multiple entities which are identical. For example, add the following method to the Medication class that will return all medications of type ACE (Angiotensin Converting Enzyme Inhibitors):

public List<String> findByType() {
Query query = entityManager.createQuery("SELECT m.name FROM Medication m WHERE m.type = 'ACE'");
List<String> list = query.getResultList();
return list;
}

Add the following code sequence to the PatientServlet after the body tag is displayed.

...
out.println("<body>");
List<String> medications = medicationFacade.findByType();
out.println("<h3>Medications of type ACE</h3>");
for (String m : medications) {
out.println("<h3>Medication: " + m + "</h3>");
}

Execute the PatientServlet. Altace is returned twice as illustrated in the following screenshot:

Eliminating duplicate entities

To avoid this duplication of medication names we can use the DISTINCT keyword. Only those entities with a distinct set of values will be returned. Replace the query in the findByType method with this query:

SELECT DISTINCT m.name FROM Medication m WHERE m.type = 'ACE'

Re-execute the PatientServlet. Duplicate names are now removed as shown here:

Eliminating duplicate entities

Using the Order By clause

The Order By clause is useful in controlling the order of entities returned by a Select statement. The clause follows the Where clause and can consist of a comma delimited list of entity fields. Modify the findAll method to use the query:

SELECT DISTINCT m.name FROM Medication m ORDER BY m.name

Re-execute the PatientServlet. The list returned is sorted in ascending order by the medication's name as shown here:

Using the Order By clause

If we need to sort the elements in descending order the DESC keyword is used.

SELECT DISTINCT m.name FROM Medication m ORDER BY m.name DESC

While the keyword ASC can be used explicitly to indicate an ascending sort, the Order By clause defaults to ascending. If multiple elements are included in the clause, the left-most elements have higher precedence.

See also

The Using the Where clause recipe that follows illustrates how to limit the number of rows of a table returned.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.196.146