Click here to load reader
Upload
truongque
View
212
Download
0
Embed Size (px)
Citation preview
JPQL Srikanth Technologies 1
Java Persistence Query Language JPQL is the query language used with JPA. It resembles SQL and works with Entities.
The following Entities – Employee and Job are used throughout this document for examples. They map to
Employees and Jobs tables of HR account in Oracle database.
Job.java
import java.io.Serializable; import java.util.Collection; import javax.persistence.*; @Entity @Table(name = "JOBS") public class Job implements Serializable { @Id @Column(name = "JOB_ID", nullable = false) private String jobId; @Column(name = "JOB_TITLE", nullable = false) private String jobTitle; @Column(name = "MIN_SALARY") private Long minSalary; @Column(name = "MAX_SALARY") private Integer maxSalary; @OneToMany(cascade = CascadeType.ALL, mappedBy = "job") private Collection<Employee> employees; public Job() { } public Job(String jobId) { this.jobId = jobId; } public Job(String jobId, String jobTitle) { this.jobId = jobId; this.jobTitle = jobTitle; } public String getJobId() { return jobId; } public void setJobId(String jobId) { this.jobId = jobId; } public String getJobTitle() { return jobTitle; } public void setJobTitle(String jobTitle) { this.jobTitle = jobTitle; } public Long getMinSalary() { return minSalary; } public void setMinSalary(Long minSalary) { this.minSalary = minSalary; } public Integer getMaxSalary() { return maxSalary;
JPQL Srikanth Technologies 2
} public void setMaxSalary(Integer maxSalary) { this.maxSalary = maxSalary; } public Collection<Employee> getEmployees() { return employees; } public void setEmployees(Collection<Employee> employees) { this.employees = employees; } @Override public String toString() { return jobId + ":" + jobTitle + ":" + minSalary.toString() + ":" + maxSalary.toString(); } }
Employee.java
import java.io.Serializable; import java.math.BigDecimal; import java.util.Date; import javax.persistence.*; @Entity @Table(name = "EMPLOYEES") @NamedQueries({}) public class Employee implements Serializable { @Id @Column(name = "EMPLOYEE_ID", nullable = false) private Integer employeeId; @Column(name = "FIRST_NAME") private String firstName; @Column(name = "LAST_NAME", nullable = false) private String lastName; @Column(name = "EMAIL", nullable = false) private String email; @Column(name = "PHONE_NUMBER") private String phoneNumber; @Column(name = "HIRE_DATE", nullable = false) @Temporal(TemporalType.DATE) private Date hireDate; @Column(name = "SALARY") private BigDecimal salary; @Column(name = "COMMISSION_PCT") private BigDecimal commissionPct; @JoinColumn(name = "JOB_ID", referencedColumnName = "JOB_ID") @ManyToOne private Job job; public Integer getEmployeeId() { return employeeId; } public void setEmployeeId(Integer employeeId) { this.employeeId = employeeId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName;
JPQL Srikanth Technologies 3
} public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } public Date getHireDate() { return hireDate; } public void setHireDate(Date hireDate) { this.hireDate = hireDate; } public BigDecimal getSalary() { return salary; } public void setSalary(BigDecimal salary) { this.salary = salary; } public BigDecimal getCommissionPct() { return commissionPct; } public void setCommissionPct(BigDecimal commissionPct) { this.commissionPct = commissionPct; } public Job getJob() { return job; } public void setJob(Job job) { this.job = job; } @Override public String toString() { return employeeId + ":" + firstName + ":" + lastName + ":" + email + ":" + phoneNumber + ":" + commissionPct + ":" + job.getJobTitle(); } }
QueryServlet.java This is a servlet that takes query from user and displays the result. It uses DI to get access to EntityManager.
JPQL Srikanth Technologies 4
import java.io.*; import java.util.List; import javax.persistence.*; import javax.servlet.*; import javax.servlet.http.*; public class QueryServlet extends HttpServlet { @PersistenceContext EntityManager em; protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { String query = request.getParameter("query"); if ( query == null ) query =""; out.println("<form action='query' method='post'>Enter query below : "); out.println("<br/><textarea name='query' rows='5' cols='50'>" + query + "</textarea>"); out.println("<br><input type='submit' value='Execute'/></form>"); if ( query.length() > 0 ) { Query qry = em.createQuery(query); List lst = qry.getResultList(); for (Object obj : lst) { if (obj instanceof Object[]) { for( Object o : (Object[]) obj) out.println(o ); out.println("<br/>"); } else out.println( obj.toString() + "<br>"); } } } finally { out.close(); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } }
JPQL Srikanth Technologies 5
Positional Parameter A positional parameter starts with a ? followed by the parameter’s position. A named parameter starts with :
and is followed by the name of the parameter.
SELECT j from Job where j.minSalary > :minsal SELECT j from Job where j.minSalary > ?1
Retrieving a single entity
Query q = em.createQuery("SELECT j from Job j where j.jobId = ?1"); q.setParameter(1,"IT_PROG"); Job j = (Job) q.getSingleResult();
If your query retrieves multiple instances, it will throw NonUniqueResultException. The persistence
provider will throw NoResultException when your query does not retrieve any result.
Retrieving multiple entities
Query q= em.createQuery("SELECT j from Job j where j.minSalary > ?1"); q.setParameter(1,5000); List jobs = q.getResultList();
NOTE: If getResultList() does not retrieve any results for a query, it returns an empty list. No exceptions are
thrown.
Pagination The following methods of Query object are used to retrieve one page at a time.
query.setMaxResults(50); query.setFirstResult(0); List items = query.getResultList();
Query Examples You can use JPQL to perform selects, updates, and deletes in your queries.
select e from Employee e select e.firstName, e.salary, e.job.jobTitle from Employee e
From Clause The FROM clause of JPQL is by far the most important clause. It defines the domain for the query—that is, the
names for the entities that will be used in the query.
If you don’t specify the name element, it defaults to the name of the entity class. The name of entity must be
unique within a persistence unit.
@Entity(name = "Employee") public class Emp
Then we must change the FROM clause of the query as follows:
FROM Employee c
JPQL Srikanth Technologies 6
JPQL Reserved Words
The following are the reserved words of JPQL.
Statements and
clauses
SELECT, UPDATE, DELETE, FROM, WHERE, GROUP, HAVING, ORDER, BY, ASC, DESC
Joins JOIN, OUTER, INNER, LEFT, FETCH
Conditions and
operators
DISTINCT, OBJECT, NULL, TRUE, FALSE, NOT, AND, OR, BETWEEN, LIKE, IN, AS,
UNKNOWN, EMPTY, MEMBER, OF, IS, NEW, EXISTS, ALL, ANY, SOME
Functions AVG, MAX, MIN, SUM, COUNT, MOD, UPPER, LOWER, TRIM, POSITION,
CHARACTER_LENGTH, CHAR_LENGTH, BIT_LENGTH, CURRENT_TIME, CURRENT_DATE,
CURRENT_TIMESTAMP
You can navigate further to other persistence fields or association fields using a single-value path expression.
For example, say we have a many-to-one relationship between Employee and Job; we can navigate to a
persistence field such as jobTitle using association field job as follows:
e.job.jobTitle
Operators supported by JPQL
Unary sign +, -
Arithmetic *, / +, -
Relational =, >, >=, <, <=, <>, [NOT] BETWEEN, [NOT] LIKE, [NOT] IN, IS [NOT] NULL, IS [NOT]
EMPTY, [NOT] MEMBER [OF]
Logical NOT AND OR
Select e from Employee e where e.salary > 5000 Select e from Employee e where e.salary between 5000 and 10000 Select e from Employee e where e.employeeId in (100,110)
String Functions CONCAT(string1, string2) Returns the value of concatenating two strings or literals
together.
SUBSTRING(string, position, length) Returns the substring starting at position that is length long.
TRIM([LEADING | TRAILING | BOTH]
[trim_character] FROM] string_to_trimmed)
Trims the specified character to a new length. The trimming can
either be LEADING, TRAILING, or from BOTH ends. If no trim_character is specified, then a blank space is assumed
LOWER(string) Returns the string after converting to lowercase.
UPPER(string) Returns the string after converting to uppercase.
LENGTH(string) Returns the length of a string.
LOCATE(searchString,
stringToBeSearched[initialPosition])
Returns the position of a given string within another string. The
search starts at position 1 if initialPosition is not specified
Examples:
WHERE LOWER(e.firstName) = 'Srikanth' WHERE CONCAT(e.firstName, e.lastName) = 'SrikanthPragada' WHERE SUBSTRING(e.firstName, 1, 3) = 'Sri' where LOCATE('a',e.firstName) > 3
Arithmetic Functions ABS(numeric) Returns the absolute value
SQRT(numeric) Returns the square root value
MOD(num, div) Returns the result of executing the modulus operation for num, div
SIZE(collection) Returns the number of items in a collection
SELECT j.jobTitle FROM Job j WHERE SIZE (j.employees ) > 2
JPQL Srikanth Technologies 7
Temporal Functions
CURRENT_DATE Returns current date
CURRENT_TIME Returns current time
CURRENT_TIMESTAMP Returns current timestamp
DISTINCT clauses in SELECT
select distinct e.hireDate from Employee e
Aggregate Functions AVG Returns the average value of all values of the field it is applied to
COUNT Returns the number of results returned by the query
MAX Returns the maximum value of the field it is applied to
MIN Returns the minimum value of the field it is applied to
SUM Returns the sum of all values on the field it is applied to
select e.job.jobTitle, sum(e.salary) from Employee e group by e.job.jobTitle
select e.job.jobId, count(e.employeeId) from Employee e group by e.job.jobId having count(e.job.jobId) > 10
Subqueries A subquery is a query inside another query. Operators IN and EXISTS are used with subqueries.
select emp from Employee emp where emp.salary = ( select max(e.salary) from Employee e )
select j from Job j where exists ( select e from Employee e where e.job.jobId = j.jobId)
Joining Two entities can be joined based on their association or based on persistent fields.
select e.firstName, j.jobTitle from Employee e join e.job j where j.minSalary > 5000
select j from Job j join fetch j.employees where j.minSalary > 5000
select j.jobTitle, e.firstName from Job j left outer join j.employees e
JPQL Srikanth Technologies 8
Bulk Updates
It is possible to execute UPDATE and DELETE commands to effect more than one entity.
Use createQuery() method to create UPDATE or DELETE command and use executeUpdate() method to invoke
the query.
You must invoke executeUpdate() method within a transaction.
Query q = em.createQuery("UPDATE Job j set j.minSalary = j.minSalary + 1000"); int count = q.executeUpdate();
Query q = em.createQuery("DELETE Employee e where e.salary < 5000"); int count = q.executeUpdate();
Native Query Native query is SQL command that is directly passed to database without JPQL processing it. Use
createNativeQuery() method of EntityManager to create Query object that represents native query.
The following servlet shows how to use native query.
import java.io.*; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.servlet.*; import javax.servlet.http.*; import jpa.Job; public class NativeQueryServlet extends HttpServlet { @PersistenceContext EntityManager em; protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { Query qry = em.createNativeQuery( "select job_id, job_title, min_salary , max_salary from jobs", Job.class); List lst = qry.getResultList(); for (Object obj : lst) { out.println( obj.toString() + "<br>"); } } finally { out.close(); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } public String getServletInfo() { return "Short description"; } }