Chapter 3: Using QueryDSL and SpringDataJPA to complete Update&Delete

In the previous chapter, we explained the integration of QueryDsl with SpringDataJPA to complete a simple single-table conditional query. Two modes are used for querying. One is the complete QueryDsl and the other is the integrated form. Now that the single-table query has been explained, let's Let's take a look at the various processing modes of Update&Delete after the integration of QueryDsl and SpringDataJPA.

Objectives of this chapter

Based on the SpringBoot framework platform, QueryDsl integrates SpringDataJPA single-table Update&Delete operations.

Build the project

We use the idea tool to create an empty SpringBoot project, and copy the configuration files in Chapter 2 of the previous chapter: Using QueryDSL and SpringDataJPA to implement a single-table common conditional query to the project in this chapter (copy content includes: application.yml, pom.xml Internal dependencies, Bean, BaseJPA, UserJPA) After the copy is completed, use the maven compile command to complete the automatic creation of the QueryDsl query entity. First, complete the update of the user information. Let's go directly to the topic below.

Update entity information

We use two ways to update entity information, one is to completely use the save method of Spring Data JPA, and the other is the update method of QueryDsl. Let's first take a look at how Spring Data JPA completes the update of entity information.

Updating entities with SpringDataJPA

SpringDataJPA has a built-in save method for saving and updating entity content. If there is a primary key value, the row information corresponding to the primary key is updated. Otherwise, a new information is added, which is similar to Hibernate's saveOrUpdate method. Let's first create a UserController controller, the code is as follows:

package com.yuqiyu.querydsl.sample.chapter3.controller;

import com.querydsl.jpa.impl.JPAQueryFactory;
import com.yuqiyu.querydsl.sample.chapter3.bean.QUserBean;
import com.yuqiyu.querydsl.sample.chapter3.bean.UserBean;
import com.yuqiyu.querydsl.sample.chapter3.jpa.UserJPA;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;

/**
 * ========================
 * Created with IntelliJ IDEA.
 * User:恒宇少年
 * Date:2017/7/4
 * Time:22:15
 * 码云:http://git.oschina.net/jnyqy
 * ========================
 */
@RestController
public class UserController
{
    @Autowired
    private UserJPA userJPA;

    //实体管理者
    @Autowired
    private EntityManager entityManager;

    //JPA查询工厂
    private JPAQueryFactory queryFactory;

    @PostConstruct
    public void initFactory()
    {
        queryFactory = new JPAQueryFactory(entityManager);
        System.out.println("init JPAQueryFactory successfully");
    }
}

The above controller is no different from the basic content of the controller in Chapter 2. When the bean constructor is initialized, the JPAQueryFactory query factory entity is instantiated through the EntityManager object, which is convenient for our subsequent query operations. The QueryDsl form needs to be built on the JPAQueryFactory object. built on the basis. The SpringDataJPA way to update the entity code is as follows:

    /**
     * 使用Jpa更新会员信息
     * @param userBean
     */
    @RequestMapping(value = "/updateWithJpa")
    public String updateWithJpa(UserBean userBean)
    {
        //保存会员信息相当于Hibernate内的SaveOrUpdate
        userJPA.save(userBean);
        return "SUCCESS";
    }

It is very simple and there is nothing difficult to understand. The parameters are passed through the interface Request method. Let's run the next project and try the update operation based on the data in the previous chapter. The output of the running project console is shown in Figure 1 below:
figure 1
Seeing the red marked part in Figure 1 above, we can access the path through the browser and try to update the entity information. Let's visit the following address: 127.0.0.1:8080/updateWithJpa ?id=6&name=change&age=23&address=SdJN&pwd=123456 , the output content of the interface is shown in Figure 2 below:
figure 2
Let's take a look at the log content output by the console, as shown in the following code:

Hibernate: 
    select
        userbean0_.t_id as t_id1_0_0_,
        userbean0_.t_address as t_addres2_0_0_,
        userbean0_.t_age as t_age3_0_0_,
        userbean0_.t_name as t_name4_0_0_,
        userbean0_.t_pwd as t_pwd5_0_0_ 
    from
        t_user userbean0_ 
    where
        userbean0_.t_id=?
Hibernate: 
    update
        t_user 
    set
        t_address=?,
        t_age=?,
        t_name=?,
        t_pwd=? 
    where
        t_id=?

It can be seen that SpringDataJPA first went to the database to query the current object. The comparison found that it was inconsistent with the database and there was a primary key value, and the following Update statement was executed. If the queried field corresponds to the updated content, the following will not be executed. Update statement, let's visit the address just now to view the console output as shown in the following code block:

Hibernate: 
    select
        userbean0_.t_id as t_id1_0_0_,
        userbean0_.t_address as t_addres2_0_0_,
        userbean0_.t_age as t_age3_0_0_,
        userbean0_.t_name as t_name4_0_0_,
        userbean0_.t_pwd as t_pwd5_0_0_ 
    from
        t_user userbean0_ 
    where
        userbean0_.t_id=?

It can be seen that only the query is executed and the update operation is not initiated.

Updating entities using QueryDsl

Let's use QueryDsl completely to update the entity, the code is as follows:

/**
     * 使用QueryDsl更新会员信息
     * @param userBean
     */
    @RequestMapping(value = "/updateWithQueryDsl")
    public String updateWithQueryDsl(UserBean userBean)
    {
        //querydsl查询实体
        QUserBean _Q_user = QUserBean.userBean;

        queryFactory
                .update(_Q_user)//更新对象
                //更新字段列表
                .set(_Q_user.name,userBean.getName())
                .set(_Q_user.address,userBean.getAddress())
                .set(_Q_user.age,userBean.getAge())
                .set(_Q_user.pwd,userBean.getPwd())
                //更新条件
                .where(_Q_user.id.eq(userBean.getId()))
                //执行更新
                .execute();
        return "SUCCESS";
    }

The first step is to obtain the QUserBean query object, and build the update method processing through the JPAQueryFactory object, and the parameter of update is the query entity that needs to be updated. Of course, only a single query entity can be updated in the update method.

Next, we set the content of the fields to be updated, and here is what we can control as we like. To update which fields need to be updated, just set the content of the corresponding field update.

After setting the update field, you need to set the update conditions. It is also possible not to set it. Of course, it must be the same as the native SQL here. All the data in the table will be updated without setting the conditions.

The last step is crucial, the update operation will not be performed without calling the execute method. After restarting the project, visit the address: 127.0.0.1:8080/updateWithQueryDsl?id=6&name=changeWithQueryDsl&age=24&address=Shandong Jinan&pwd=666666 , the output of the interface is shown in Figure 4 below:
Figure 4, we found that there was a system exception here, let's take a look The error message output by the console is as follows:

javax.persistence.TransactionRequiredException: Executing an update/delete query
    at org.hibernate.jpa.spi.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:54) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at com.querydsl.jpa.impl.JPAUpdateClause.execute(JPAUpdateClause.java:77) ~[querydsl-jpa-4.1.4.jar:na]
    at com.yuqiyu.querydsl.sample.chapter3.controller.UserController.updateWithQueryDsl(UserController.java:76) ~[classes/:na]
.......

It is found that if you want to execute the update/delete method, there must be a transaction, then we modify the update method and add the transaction annotation @Transactional, restart the project and then visit our previous address, the interface output content is shown in Figure 5 below:
Figure 5, the interface outputs the execution Successful prompt, let's take a look at the SQL statement output by the console:

Hibernate: 
    update
        t_user 
    set
        t_name=?,
        t_address=?,
        t_age=?,
        t_pwd=? 
    where
        t_id=?

The SQL statement output by the console is automatically generated by QueryDsl based on the update entities, update fields, and query conditions we configured. Is it more flexible?

Deleting entity information using SpringDataJPA

Let's take a look at what to do when Spring Data JPA deletes entity information? The code looks like this:

    /**
     * 使用Jpa删除会员信息
     * @param userBean
     */
    @RequestMapping(value = "/deleteWithJpa")
    public String deleteWithJpa(UserBean userBean)
    {
        //执行删除指定主键的值
        userJPA.delete(userBean.getId());
        return "SUCCESS";
    }

In the above code, we delete the specified entity based on the primary key. Next, we restart the project and access the address: http://127.0.0.1:8080/deleteWithJpa?id=6 , the SQL content output by the console is as follows:

Hibernate: 
    delete 
    from
        t_user 
    where
        t_id=?

The output SQL also completes the deletion logic according to the primary key we specified.

Use QueryDsl to delete member information

Before writing the delete method, we thought of the need to add transactions when using QueryDsl to update entities. Of course, it is also required when deleting. So we should pay attention when writing the delete method. The delete code is as follows:

 /**
     * 使用QueryDsl删除会员信息
     * @param userBean
     */
    @RequestMapping(value = "/deleteWithQueryDsl")
    @Transactional
    public String deleteWithQueryDsl(UserBean userBean)
    {
        //querydsl查询实体
        QUserBean _Q_user = QUserBean.userBean;

        queryFactory
                //删除对象
                .delete(_Q_user)
                //删除条件
                .where(_Q_user.id.eq(userBean.getId()))
                //执行删除
                .execute();
        return "SUCCESS";
    }

The delete writing of QueryDsl is almost the same as the update method, except that the update method is changed to the delete method. Of course, multiple where conditions can be added, which depends on the actual business logic of the individual.

After the delete statement is written, the execute method is called before QueryDsl processes the delete logic. After restarting the project, access the address: 127.0.0.1:8080/deleteWithQueryDsl?id=7 , check the console output SQL content as follows:

Hibernate: 
    delete 
    from
        t_user 
    where
        t_id=?

Let's modify the deletion condition below. We delete it according to the name and age greater than 20 years old. The modified method code is as follows:

    @RequestMapping(value = "/deleteWithQueryDsl")
    @Transactional
    public String deleteWithQueryDsl(UserBean userBean)
    {
        //querydsl查询实体
        QUserBean _Q_user = QUserBean.userBean;

        queryFactory
                //删除对象
                .delete(_Q_user)
                //删除条件
                .where(
                        _Q_user.name.eq(userBean.getName())
                        .and(_Q_user.age.gt(20))
                )
                //执行删除
                .execute();
        return "SUCCESS";
    }

After restarting the project, access the address: http://127.0.0.1:8080/deleteWithQueryDsl?name=admin&age=20 , the console output SQL is as follows:

Hibernate: 
    delete 
    from
        t_user 
    where
        t_name=? 
        and t_age>?

The output SQL is automatically generated according to the conditions set by us. The conditions in QueryDsl can be exactly the same as the native SQL, and the conditions can be written completely using the SQL idea.

Summarize

The above content is the whole content of this chapter. This chapter mainly explains how QueryDsl operates the single-table Delete&Update operation and SpringDataJPA operates the single-table Delete&Update.
The code of this chapter has been uploaded to the code cloud:
SpringBoot supporting source code address: https://gitee.com/hengboy/spring-boot-chapter
SpringCloud supporting source code address: https://gitee.com/hengboy/spring-cloud-chapter
SpringBoot related For the series of articles, please visit: Catalog: SpringBoot Learning Catalogue
QueryDSL related series of articles, please visit: QueryDSL General Query Framework Learning Catalog
Spring DataJPA-related series of articles, please visit: Catalog: Spring DataJPA Learning Catalog
Thank you for reading!
Welcome to join the QQ technical exchange group and make progress together.
QQ technical exchange group

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324736220&siteId=291194637