lvxianchao / notes

狗屁不通瞎写的博客
https://coderlxc.com
1 stars 0 forks source link

SpringBoot + Gradle + Spring Data JPA + QueryDSL #46

Open lvxianchao opened 1 year ago

lvxianchao commented 1 year ago

记录一下在 SpringBoot 2 中使用 Gradle 整合 QueryDSL 以配合 JPA 查询。

Java 17 SpringBoot 2.7.7 Gradle 7.6 QueryDSL Version 5.0.0

最终目的是提供两个 Restful API:

重点

使用 QueryDSl 的重点就是在定义好了 Entity 以后,通过 Gradle Build 出 QEntity 类。如在以下演示文件中定义的是 User Entity,在 build 以后,在项目中可以看到自动生成的 Q 类:

image

安装依赖

build.gradle 中,添加以下:

// 在最外层场景 QueryDSL 版本
var queryDslVersion = '5.0.0'

// 以下需要添加到 dependencies 里
implementation ("com.querydsl:querydsl-jpa:${queryDslVersion}")
annotationProcessor("com.querydsl:querydsl-apt:${queryDslVersion}:jpa")
annotationProcessor("jakarta.persistence:jakarta.persistence-api")

项目文件

application.yml

spring:
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
  datasource:
    driverClassName: org.mariadb.jdbc.Driver
    password: root
    username: root
    url: jdbc:mariadb://10.15.1.175:43306/demo

build.gradle

plugins {
    id 'java'
    id 'org.springframework.boot' version '2.7.7'
    id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
var queryDslVersion = '5.0.0'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    implementation ("com.querydsl:querydsl-jpa:${queryDslVersion}")
    annotationProcessor("com.querydsl:querydsl-apt:${queryDslVersion}:jpa")
    annotationProcessor("jakarta.persistence:jakarta.persistence-api")
}

tasks.named('test') {
    useJUnitPlatform()
}

User

package com.example.demo.entity;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.Hibernate;

import javax.annotation.PostConstruct;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Objects;

/**
 * Author: lvxianchao
 * Date: 2023-01-09 11:16
 * Description:
 */
@Getter
@Setter
@ToString
@RequiredArgsConstructor
@Entity
@Table(name = "user")
public class User implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "email")
    private String email;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false;
        User user = (User) o;
        return id != null && Objects.equals(id, user.id);
    }

    @Override
    public int hashCode() {
        return getClass().hashCode();
    }
    @PostConstruct
    public void init(){

    }
}

UserController

package com.example.demo.controller;

import com.example.demo.dto.UserIndexDTO;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

/**
 * Author: lvxianchao
 * Date: 2023-01-09 11:16
 * Description:
 */
@RestController
public class UserController {

    @Resource
    UserService service;

    @GetMapping("/")
    public List<User> index(UserIndexDTO dto) {
        System.out.println("dto = " + dto);
        return service.index(dto);
    }

    @GetMapping("/{id}")
    public User show(@PathVariable Long id) {
        return service.show(id);
    }
}

UserIndexDTO

package com.example.demo.dto;

import lombok.Data;

/**
 * Author: lvxianchao
 * Date: 2023-01-09 13:08
 * Description:
 */
@Data
public class UserIndexDTO {
    private Long id;
    private String name;
    private String email;
}

UserService

package com.example.demo.service;

import com.example.demo.dto.UserIndexDTO;
import com.example.demo.entity.QUser;
import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;

/**
 * Author: lvxianchao
 * Date: 2023-01-09 11:17
 * Description:
 */
@Service
public class UserService {

    @Resource
    UserRepository repository;

    @PersistenceContext
    private EntityManager entityManager;

    public List<User> index(UserIndexDTO dto) {
        QUser user = QUser.user;
        JPAQueryFactory query = new JPAQueryFactory(entityManager);
        JPAQuery<User> selectFrom = query.selectFrom(user);

        if (dto.getId() != null) {
            System.out.println("dto.getId() = " + dto.getId());
            selectFrom.where(user.id.eq(dto.getId()));
        }

        if (dto.getName() != null) {
            System.out.println("dto.getName() = " + dto.getName());
            selectFrom.where(user.name.eq(dto.getName()));
        }

        if (dto.getEmail() != null) {
            System.out.println("dto.getEmail() = " + dto.getEmail());
            selectFrom.where(user.email.eq(dto.getEmail()));
        }

        return selectFrom.fetch();
    }

    public User show(Long id) {
        QUser user = QUser.user;
        JPAQueryFactory query = new JPAQueryFactory(entityManager);
        User first = query.selectFrom(user).where(user.id.eq(id)).fetchFirst();
        return first;
    }
}

UserRepository

package com.example.demo.repository;

import com.example.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * Author: lvxianchao
 * Date: 2023-01-09 11:16
 * Description:
 */
public interface UserRepository extends JpaRepository<User, Long> {
}
lvxianchao commented 1 year ago

SpringBoot 3

在 SpringBoot 3 中,需要把 dependencies 中引入的依赖改为如下:


// SpringBoot 2

implementation ("com.querydsl:querydsl-jpa:${queryDslVersion}")
annotationProcessor("com.querydsl:querydsl-apt:${queryDslVersion}:jpa")
annotationProcessor("jakarta.persistence:jakarta.persistence-api")

//  SpringBoot 3
implementation ("com.querydsl:querydsl-jpa:${queryDslVersion}:jakarta")
annotationProcessor("com.querydsl:querydsl-apt:${queryDslVersion}:jakarta")
annotationProcessor("jakarta.persistence:jakarta.persistence-api")

在 SpringBoot 2 中,处于 javax 命令空间下的包需要更名为 jakarta