JPQL
JPQL addresses Entities, not tables directly
JPQL resembles SQL, but the query is written in terms of the persistence model. An Entity name is used instead of a table name, and its persistent fields or properties are used instead of columns.
List<User> users = entityManager.createQuery(
"select u from User u where u.active = :active",
User.class)
.setParameter("active", true)
.getResultList();
Here User is an Entity, u.active is its attribute,
and the result is immediately typed as List<User>.
The provider translates JPQL into a query for the specific database.
Parameters are passed separately from query text
As with PreparedStatement, values should not be concatenated into the query string.
The named parameter :active makes the query clearer and separates its structure from its data.
Relationships can be used directly in expressions
List<Order> orders = entityManager.createQuery(
"select o from Order o where o.user.id = :userId",
Order.class)
.setParameter("userId", 42L)
.getResultList();
JPQL can navigate mapped Entity relationships. But convenient object-oriented syntax does not remove the cost of the resulting SQL, so complex queries still need to be evaluated from the database point of view.