1
0

实践JPA查询

This commit is contained in:
2024-12-03 23:23:38 +08:00
commit 3298d11bd8
12 changed files with 402 additions and 0 deletions

38
.gitignore vendored Normal file
View File

@@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

8
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

7
.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

14
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="temurin-11" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

94
pom.xml Normal file
View File

@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>jpa-library</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-boot.version>2.6.15</spring-boot.version>
<spring-cloud.version>2021.0.9</spring-cloud.version>
<querydsl.version>5.1.0</querydsl.version>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.blinkfox</groupId>
<artifactId>fenix-spring-boot-starter</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,74 @@
package com.lanyuanxiaoyao.jpa;
import com.blinkfox.fenix.EnableFenix;
import com.lanyuanxiaoyao.jpa.entity.Company;
import com.lanyuanxiaoyao.jpa.entity.User;
import com.lanyuanxiaoyao.jpa.repository.CompanyRepository;
import com.lanyuanxiaoyao.jpa.repository.UserRepository;
import java.time.LocalDateTime;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@Slf4j
@EnableFenix
@EnableJpaAuditing
@SpringBootApplication
public class Application implements ApplicationRunner {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Resource
private UserRepository userRepository;
@Resource
private CompanyRepository companyRepository;
@Override
public void run(ApplicationArguments args) throws Exception {
Company company1 = createCompany("Company 1");
log.info("Company 1: {}", company1);
User user1 = createUser("User 1", LocalDateTime.now(), User.Type.STUDENT, company1);
log.info("User 1: {}", user1);
User user2 = createUser("User 2", LocalDateTime.now(), User.Type.TEACHER, company1);
log.info("User 2: {}", user2);
// companyRepository.delete(company1);
/*Iterable<User> user = userRepository.findAll(((root, query, builder) -> {
return builder.and(
builder.equal(root.get("name"), "User 1")
// builder.equal(root.get("type"), "STUDENT"),
// builder.isNotNull(root.get("company").get("name"))
);
}));*/
/*Iterable<User> user = userRepository.findAll(builder -> builder
.andEquals("type", "STUDENT")
.build());*/
// log.info("User: {}", user.iterator().next().getCompany());
companyRepository.findAll(((root, query, builder) -> {
return builder.isEmpty(root.get("users"));
}));
}
private Company createCompany(String name) {
Company company = new Company();
company.setName(name);
return companyRepository.saveAndFlush(company);
}
private User createUser(String name, LocalDateTime birthday, User.Type type, Company company) {
User user = new User();
user.setName(name);
user.setBirthday(birthday);
user.setType(type);
user.setCompany(company);
return userRepository.saveAndFlush(user);
}
}

View File

@@ -0,0 +1,52 @@
package com.lanyuanxiaoyao.jpa.entity;
import java.time.LocalDateTime;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@Getter
@Setter
@ToString
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "jpa_company")
@NamedEntityGraph(name = "company.list", attributeNodes = {
@NamedAttributeNode("users")
})
@SQLDelete(sql = "update jpa_company set deleted = true where id = ?")
@Where(clause = "deleted = false")
public class Company {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(cascade = CascadeType.DETACH, fetch = FetchType.LAZY, mappedBy = "company")
@ToString.Exclude
@Where(clause = "deleted = false")
private List<User> users;
@Column(nullable = false)
private Boolean deleted = false;
@CreatedDate
private LocalDateTime createdTime;
@LastModifiedDate
private LocalDateTime modifiedTime;
}

View File

@@ -0,0 +1,67 @@
package com.lanyuanxiaoyao.jpa.entity;
import java.time.LocalDateTime;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@Getter
@Setter
@ToString
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "jpa_user")
@NamedEntityGraph(name = "user.list", attributeNodes = {
@NamedAttributeNode("company")
})
@SQLDelete(sql = "update jpa_user set deleted = true where id = ?")
@Where(clause = "deleted = false")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
private LocalDateTime birthday;
@ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@ToString.Exclude
@Where(clause = "deleted = false")
private Company company;
@Column(nullable = false)
@Enumerated(EnumType.STRING)
private Type type;
@Column(nullable = false)
private Boolean deleted = false;
@CreatedDate
private LocalDateTime createdTime;
@LastModifiedDate
private LocalDateTime modifiedTime;
public enum Type {
STUDENT,
TEACHER,
}
}

View File

@@ -0,0 +1,12 @@
package com.lanyuanxiaoyao.jpa.repository;
import com.blinkfox.fenix.jpa.FenixJpaRepository;
import com.blinkfox.fenix.specification.FenixJpaSpecificationExecutor;
import com.lanyuanxiaoyao.jpa.entity.Company;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.repository.query.QueryByExampleExecutor;
import org.springframework.stereotype.Repository;
@Repository
public interface CompanyRepository extends FenixJpaRepository<Company, Long>, FenixJpaSpecificationExecutor<Company>, QueryByExampleExecutor<Company>, QuerydslPredicateExecutor<Company> {
}

View File

@@ -0,0 +1,18 @@
package com.lanyuanxiaoyao.jpa.repository;
import com.blinkfox.fenix.jpa.FenixJpaRepository;
import com.blinkfox.fenix.specification.FenixJpaSpecificationExecutor;
import com.lanyuanxiaoyao.jpa.entity.User;
import java.util.List;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.repository.query.QueryByExampleExecutor;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends FenixJpaRepository<User, Long>, FenixJpaSpecificationExecutor<User>, QueryByExampleExecutor<User>, QuerydslPredicateExecutor<User> {
@EntityGraph("user.list")
@Override
List<User> findAll(Specification<User> spec);
}

View File

@@ -0,0 +1,12 @@
spring:
datasource:
url: jdbc:h2:mem:test;DATABASE_TO_LOWER=TRUE;CASE_INSENSITIVE_IDENTIFIERS=TRUE
username: lanyuanxiaoyao
password: lanyuanxiaoyao
driver-class-name: org.h2.Driver
jpa:
generate-ddl: true
show-sql: true
fenix:
print-banner: false
print-sql: false