Spring-Data-JPA criteria query

Although Spring Data JPA greatly simplifies the development of the persistence layer, in actual development, advanced dynamic queries are required in many places.

Criteria API

Criteria queries are based on the concept of a metamodel defined for the managed entities of a specific persistence unit, which can be entity classes, embedded classes, or mapped parent classes.

CriteriaQuery interface: Represents a specific top-level query object, which contains various parts of the query, such as: select, from, where, group by, order by, etc. Note: CriteriaQuery object only works on Criteria queries of entity type or embedded type.

Root interface: The root object representing the Criteria query. The query root of the Criteria query defines the entity type. It can get the desired result for future navigation. It is similar to the FROM clause in the SQL query.

1: The Root instance is typed and defines the types that can appear in the FROM clause of the query.

2: The query root instance can be obtained by passing an entity type to the AbstractQuery.from method.

3: Criteria query, you can have multiple query roots.

4: AbstractQuery is the parent class of the CriteriaQuery interface, which provides methods for getting the root of the query. CriteriaBuilder interface: The constructor object Predicate used to build CritiaQuery: a simple or complex predicate type, which is equivalent to a conditional or conditional combination

If the compiler is able to perform a syntax correctness check on the query, the query is type-safe for Java objects. The 2.0 version of the JavaTM Persistence API (JPA) introduces the Criteria API, which for the first time introduces type-safe queries into Java applications and provides a mechanism for dynamically constructing queries at runtime.

JPA metamodel

In JPA, standard queries are based on the concept of a metamodel. Metamodels are defined for managed entities of a specific persistence unit. These entities can be entity classes, embedded classes, or mapped parent classes. Providing managed entities The class of meta information is the metamodel class.

The biggest advantage of using a metamodel class is that it can access the entity's persistent properties at compile time by instantiating it. This feature makes the criteria query more type-safe.

as follows,ItemMetamodel corresponding to the entity classItem_

@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(Item.class)
public abstract class Item_ {
   public static volatile SingularAttribute<Item, Integer> itemId;
   public static volatile SingularAttribute<Item, String> itemName;
   public static volatile SingularAttribute<Item, Integer> itemStock;
   public static volatile SingularAttribute<Item, Integer> itemPrice;
}Copy code

Such a meta model does not need to be created manually. Add a plugin to Maven. After compiling, the @Entity annotated class will automatically generate the corresponding metamodel.

<!--hibernate JPA auto-generate metamodel -->
<!-- Related dependencies -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-jpamodelgen</artifactId>
            <version>5.2.10.Final</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.1.0.Final</version>
        </dependency>Copy code
<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
       <configuration>
           <source>1.8</source>
             <target>1.8</target>
              <compilerArguments>
                 <processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
              </compilerArguments>
         </configuration>
 </plugin>Copy code

There is more than one method, see:Chapter 2. Usage

Use criteria to query simple demos

@Service
public class ItemServiceImpl implements ItemService {

    @Resource
    private EntityManager entityManager;

    @Override
    public List<Item> findByConditions(String name, Integer price, Integer stock) {
          / / Create CriteriaBuilder security query factory
        //CriteriaBuilder is a factory object, the beginning of a secure query. Used to build JPA security queries.
        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        / / Create a CriteriaQuery security query main statement
        //CriteriaQuery objects must work on Criteria queries on entity types or embedded types.
        CriteriaQuery<Item> query = criteriaBuilder.createQuery(Item.class);
        //Root defines the type that can appear in the From clause of the query
        Root<Item> itemRoot = query.from(Item.class);
          //Predicate filter conditions. Possible conditions for constructing where clauses
          / / Here use List to store a variety of query conditions, to achieve dynamic query
        List<Predicate> predicatesList = new ArrayList<>();
          //name fuzzy query, like statement
        if (name != null) {
            predicatesList.add(
                    criteriaBuilder.and(
                            criteriaBuilder.like(
                                    itemRoot.get(Item_.itemName), "%" + name + "%")));
        }
         // itemPrice is less than or equal to <= statement
        if (price != null) {
            predicatesList.add(
                    criteriaBuilder.and(
                            criteriaBuilder.le(
                                    itemRoot.get(Item_.itemPrice), price)));
        }
        //itemStock is greater than or equal to >= statement
        if (stock != null) {
            predicatesList.add(
                    criteriaBuilder.and(
                            criteriaBuilder.ge(
                                    itemRoot.get(Item_.itemStock), stock)));
        }
          //where() splicing query conditions
        query.where(predicatesList.toArray(new Predicate[predicatesList.size()]));
        TypedQuery<Item> typedQuery = entityManager.createQuery(query);
        List<Item> resultList = typedQuery.getResultList();
        return resultList;
    }
}Copy code

The corresponding statement in each method of criteriaBuilder

equle : filed = value

gt / greaterThan : filed > value

lt / lessThan : filed < value

ge / greaterThanOrEqualTo : filed >= value

le / lessThanOrEqualTo: filed <= value

notEqule : filed != value

like : filed like value

notLike : filed not like value

If every dynamic query is written like this, it would be too much trouble.

In fact, when using Spring Data JPA, as long as our Repo layer interface inherits the JpaSpecificationExecutor interface, we can use the Specification for dynamic query. Let's take a look at the JpaSpecificationExecutor interface:

public interface JpaSpecificationExecutor<T> {
    T findOne(Specification<T> var1);

    List<T> findAll(Specification<T> var1);

    Page<T> findAll(Specification<T> var1, Pageable var2);

    List<T> findAll(Specification<T> var1, Sort var2);

    long count(Specification<T> var1);
}Copy code

There is a very important interface here.Specification

public interface Specification<T> {
    Predicate toPredicate(Root<T> var1, CriteriaQuery<?> var2, CriteriaBuilder var3);
}Copy code

This interface has only one method, which returns the data structure of the dynamic query and is used to construct SQL for various dynamic queries.

Specification interface example

public Page<Item> findByConditions(String name, Integer price, Integer stock, Pageable page) {
     Page<Item> page = itemRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicatesList = new ArrayList<>();
            //name fuzzy query, like statement
            if (name != null) {
                predicatesList.add(
                        criteriaBuilder.and(
                                criteriaBuilder.like(
                                        root.get(Item_.itemName), "%" + name + "%")));
            }
            // itemPrice is less than or equal to <= statement
            if (price != null) {
                predicatesList.add(
                        criteriaBuilder.and(
                                criteriaBuilder.le(
                                        root.get(Item_.itemPrice), price)));
            }
            //itemStock is greater than or equal to >= statement
            if (stock != null) {
                predicatesList.add(
                        criteriaBuilder.and(
                                criteriaBuilder.ge(
                                        root.get(Item_.itemStock), stock)));
            }
            return criteriaBuilder.and(
                    predicatesList.toArray(new Predicate[predicatesList.size()]));
        }, page);
    return page;
}Copy code

Here becausefindAll(Specification<T> var1, Pageable var2)Method parameterSpecification<T> Is an anonymous inner class

Then you can directly simplify the code directly with lambda expressions.

Writing this way is much simpler than using the CriteriaBuilder to safely query the factory.

transfer:

Page<Item> itemPageList = findByConditions("car", 300, null, new PageRequest(1, 10));Copy code

Using JPASpecification<T>The interface and metamodel implement dynamic query.

In fact, every place that needs dynamic query needs to write a similarfindByConditionsMethod, it feels very troublesome. Of course, the more simplified the better.

The next one will talk about a JPASpecificationMore convenient to use.
Original link:Spring-Data-JPA criteria Search |

Intelligent Recommendation

jpa multi-criteria query

First inherit JpaSpecificationExecutor <T> interfaces Need to use JpaSpecificationExecutor <T> in the Page <T> findAll (@Nullable Specification <T> spec, Pageable pageable); //...

JPA Criteria Query

There is such a simple demand for a certain day, and a page has N query mode. This N parameters may have no, Other A query mode is "AND", and remaining "OR". 1.png There is such a ...

Spring Boot using JPA multi-criteria query mysql

In the previous section we have learned to read in Spring Boot function using the mysql database. Spring Boot use mysql database This chapter to learn about how to use JPA multi-criteria query mysql. ...

Spring data Jpa query

1. After inheriting from JpaRepository<T, ID>, you can use the query method of the parent interface directly in the service. Methods such as findOne, findById, findAll, etc. to query one, multip...

spring-data-jpa query

Let's basic use spring-data-jpa through a complete project, then we introduce his advanced usage. build a database table:. user, the primary key increment    b corresponds to the entity:. User c. Resu...

More Recommendation

Spring Data JPA @Query

Use @Query annotations in the DAO layer Define physical classes Person Use @Query annotations in the DAO layer (SQL native statement query) @Query default is to query by object, nativeQuery = true: Pr...

Spring data jpa query with @Query

Before introducing the @Query annotation, let's see how to use @NamedQuery for named queries. 1. Now the entity class defines a method that has a specific query statement. 2. Then we can use this meth...

Spring Data JPA from entry to proficiency ~ a brief introduction to the concept of Criteria

(1)Root<T> root It represents the root object that can query and operate. If the entity object is metaphorized to the table name, then the field in this table is just the physical field of JPQL....

JpaRepository and criteria API of Spring JPA

Preface Both JpaRepository and criteria API are tools provided by spring jpa for database operations. The difference from mybaits is that they do not need to write native SQL statements, and database ...

Copyright  DMCA © 2018-2026 - All Rights Reserved - www.programmersought.com  User Notice

Top