mirror of
https://github.com/OtusTeam/Spring.git
synced 2026-05-30 10:50:42 +00:00
hibernate-fetch-mode-demo
This commit is contained in:
@@ -3,4 +3,5 @@
|
||||
## Описание проектов
|
||||
|
||||
* *unit-testing-plain-spring* - пример тестирования в проектах на чистом Spring
|
||||
* *unit-testing-spring-boot* - то же самое, только на Spring Boot
|
||||
* *unit-testing-spring-boot* - то же самое, только на Spring Boot
|
||||
* *hibernate-fetch-mode-demo* - демонстрация настроек Hibernate, в частности для решения проблемы N+1
|
||||
@@ -0,0 +1,29 @@
|
||||
HELP.md
|
||||
/target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
@@ -0,0 +1,71 @@
|
||||
<?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>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.1.3.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>ru.otus.example</groupId>
|
||||
<artifactId>hibernate-fetch-mode-demo</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>HibernateFetchModeDemo</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.shell</groupId>
|
||||
<artifactId>spring-shell-starter</artifactId>
|
||||
<version>2.0.0.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
</project>
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package ru.otus.example.HibernateFetchModeDemo;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class HibernateFetchModeDemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(HibernateFetchModeDemoApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package ru.otus.example.HibernateFetchModeDemo.models;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Entity
|
||||
@Table(name = "knowledge")
|
||||
public class Knowledge {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private long id;
|
||||
|
||||
@Column
|
||||
private String name;
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package ru.otus.example.HibernateFetchModeDemo.models;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.hibernate.annotations.LazyCollection;
|
||||
import org.hibernate.annotations.LazyCollectionOption;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Entity
|
||||
@Table(name = "mentors")
|
||||
public class Mentor {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private long id;
|
||||
|
||||
@Column
|
||||
private String name;
|
||||
|
||||
@LazyCollection(LazyCollectionOption.FALSE)
|
||||
@ManyToMany(targetEntity = Knowledge.class, cascade = CascadeType.ALL)
|
||||
@JoinTable(name = "mentors_experience",
|
||||
joinColumns = @JoinColumn(name = "mentor_id", referencedColumnName = "id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "knowledge_id", referencedColumnName = "id"))
|
||||
private List<Knowledge> experience;
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package ru.otus.example.HibernateFetchModeDemo.models;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.hibernate.annotations.BatchSize;
|
||||
import org.hibernate.annotations.LazyCollection;
|
||||
import org.hibernate.annotations.LazyCollectionOption;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Entity
|
||||
@Table(name = "students")
|
||||
public class Student {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private long id;
|
||||
|
||||
@Column
|
||||
private String name;
|
||||
|
||||
//@BatchSize(size = 5)
|
||||
@LazyCollection(LazyCollectionOption.FALSE)
|
||||
@ManyToMany(targetEntity = Knowledge.class, cascade = CascadeType.ALL)
|
||||
@JoinTable(name = "students_experience",
|
||||
joinColumns = @JoinColumn(name = "student_id", referencedColumnName = "id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "knowledge_id", referencedColumnName = "id"))
|
||||
private List<Knowledge> experience;
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package ru.otus.example.HibernateFetchModeDemo.models;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.hibernate.annotations.Fetch;
|
||||
import org.hibernate.annotations.FetchMode;
|
||||
import org.hibernate.annotations.LazyCollection;
|
||||
import org.hibernate.annotations.LazyCollectionOption;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Entity
|
||||
@Table(name = "teachers")
|
||||
public class Teacher {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private long id;
|
||||
|
||||
@Column
|
||||
private String name;
|
||||
|
||||
@LazyCollection(LazyCollectionOption.FALSE)
|
||||
@Fetch(FetchMode.SUBSELECT)
|
||||
@ManyToMany(targetEntity = Knowledge.class, cascade = CascadeType.ALL)
|
||||
@JoinTable(name = "teachers_experience",
|
||||
joinColumns = @JoinColumn(name = "teacher_id", referencedColumnName = "id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "knowledge_id", referencedColumnName = "id"))
|
||||
private List<Knowledge> experience;
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package ru.otus.example.HibernateFetchModeDemo.repositories;
|
||||
|
||||
import ru.otus.example.HibernateFetchModeDemo.models.Mentor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface MentorRepository {
|
||||
List<Mentor> findAll();
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package ru.otus.example.HibernateFetchModeDemo.repositories;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
import ru.otus.example.HibernateFetchModeDemo.models.Mentor;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public class MentorRepositoryImpl implements MentorRepository {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager em;
|
||||
|
||||
@Override
|
||||
public List<Mentor> findAll() {
|
||||
return em.createQuery("select m from Mentor m join fetch m.experience", Mentor.class).getResultList();
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package ru.otus.example.HibernateFetchModeDemo.repositories;
|
||||
|
||||
import ru.otus.example.HibernateFetchModeDemo.models.Student;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface StudentRepository {
|
||||
List<Student> findAll();
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package ru.otus.example.HibernateFetchModeDemo.repositories;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
import ru.otus.example.HibernateFetchModeDemo.models.Student;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public class StudentRepositoryImpl implements StudentRepository {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager em;
|
||||
|
||||
@Override
|
||||
public List<Student> findAll() {
|
||||
return em.createQuery("select s from Student s", Student.class).getResultList();
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package ru.otus.example.HibernateFetchModeDemo.repositories;
|
||||
|
||||
import ru.otus.example.HibernateFetchModeDemo.models.Teacher;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface TeacherRepository {
|
||||
List<Teacher> findAll();
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package ru.otus.example.HibernateFetchModeDemo.repositories;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
import ru.otus.example.HibernateFetchModeDemo.models.Teacher;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public class TeacherRepositoryImpl implements TeacherRepository {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager em;
|
||||
|
||||
@Override
|
||||
public List<Teacher> findAll() {
|
||||
return em.createQuery("select t from Teacher t", Teacher.class).getResultList();
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package ru.otus.example.HibernateFetchModeDemo.shell;
|
||||
|
||||
import org.springframework.shell.standard.ShellComponent;
|
||||
import org.springframework.shell.standard.ShellMethod;
|
||||
import ru.otus.example.HibernateFetchModeDemo.models.Mentor;
|
||||
import ru.otus.example.HibernateFetchModeDemo.models.Student;
|
||||
import ru.otus.example.HibernateFetchModeDemo.models.Teacher;
|
||||
import ru.otus.example.HibernateFetchModeDemo.repositories.MentorRepository;
|
||||
import ru.otus.example.HibernateFetchModeDemo.repositories.StudentRepository;
|
||||
import ru.otus.example.HibernateFetchModeDemo.repositories.TeacherRepository;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@ShellComponent
|
||||
public class ShellCommands {
|
||||
|
||||
private static final String OFFSET = "\n\n----------------------------\n\n";
|
||||
|
||||
private final StudentRepository studentRepository;
|
||||
private final MentorRepository mentorRepository;
|
||||
private final TeacherRepository teacherRepository;
|
||||
|
||||
public ShellCommands(StudentRepository studentRepository, MentorRepository mentorRepository, TeacherRepository teacherRepository) {
|
||||
this.studentRepository = studentRepository;
|
||||
this.mentorRepository = mentorRepository;
|
||||
this.teacherRepository = teacherRepository;
|
||||
}
|
||||
|
||||
|
||||
@ShellMethod(value = "Show all students", key = "find-all-students")
|
||||
public String findAllStudents(){
|
||||
System.out.println();
|
||||
return OFFSET + studentRepository.findAll().stream().map(Student::toString).collect(Collectors.joining("\n"));
|
||||
}
|
||||
|
||||
@ShellMethod(value = "Show all mentors", key = "find-all-mentors")
|
||||
public String findAllMentors(){
|
||||
System.out.println();
|
||||
return OFFSET + mentorRepository.findAll().stream().map(Mentor::toString).collect(Collectors.joining("\n"));
|
||||
}
|
||||
|
||||
@ShellMethod(value = "Show all teachers", key = "find-all-teachers")
|
||||
public String findAllTeachers(){
|
||||
System.out.println();
|
||||
return OFFSET + teacherRepository.findAll().stream().map(Teacher::toString).collect(Collectors.joining("\n"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:h2:mem:testdb
|
||||
initialization-mode: always
|
||||
|
||||
jpa:
|
||||
generate-ddl: false
|
||||
hibernate:
|
||||
ddl-auto: none
|
||||
|
||||
show-sql: true
|
||||
properties:
|
||||
hibernate:
|
||||
#format_sql: true
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
INSERT INTO knowledge (name) VALUES ('Spring Core'), ('Spring Data'), ('Spring MVC'), ('Spring Batch'), ('Spring Integration'), ('Spring WebFlux');
|
||||
|
||||
INSERT INTO students (name) VALUES ('Student #01'), ('Student #02'), ('Student #03'), ('Student #04'), ('Student #05'), ('Student #06'), ('Student #07'), ('Student #08'), ('Student #09');
|
||||
INSERT INTO mentors (name) VALUES ('Mentor #01'), ('Mentor #02'), ('Mentor #03'), ('Mentor #04'), ('Mentor #05'), ('Mentor #06'), ('Mentor #07'), ('Mentor #08'), ('Mentor #09');
|
||||
INSERT INTO teachers (name) VALUES ('Teacher #01'), ('Teacher #02'), ('Teacher #03'), ('Teacher #04'), ('Teacher #05'), ('Teacher #06'), ('Teacher #07'), ('Teacher #08'), ('Teacher #09');
|
||||
|
||||
INSERT INTO students_experience (student_id, knowledge_id) VALUES (1, 1), (1, 2), (2, 2), (2, 3), (2, 4), (2, 5);
|
||||
INSERT INTO mentors_experience (mentor_id, knowledge_id) VALUES (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6);
|
||||
INSERT INTO teachers_experience (teacher_id, knowledge_id) VALUES(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6);
|
||||
@@ -0,0 +1,48 @@
|
||||
DROP TABLE IF EXISTS students_experience;
|
||||
DROP TABLE IF EXISTS mentors_experience;
|
||||
DROP TABLE IF EXISTS teachers_experience;
|
||||
DROP TABLE IF EXISTS students;
|
||||
DROP TABLE IF EXISTS mentors;
|
||||
DROP TABLE IF EXISTS teachers;
|
||||
DROP TABLE IF EXISTS knowledge;
|
||||
|
||||
CREATE TABLE knowledge (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(255),
|
||||
);
|
||||
|
||||
CREATE TABLE students (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(255),
|
||||
);
|
||||
|
||||
CREATE TABLE mentors (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(255),
|
||||
);
|
||||
|
||||
CREATE TABLE teachers (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(255),
|
||||
);
|
||||
|
||||
CREATE TABLE students_experience (
|
||||
student_id BIGINT,
|
||||
knowledge_id BIGINT,
|
||||
FOREIGN KEY(student_id) REFERENCES students(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY(knowledge_id) REFERENCES knowledge(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE mentors_experience (
|
||||
mentor_id BIGINT,
|
||||
knowledge_id BIGINT,
|
||||
FOREIGN KEY(mentor_id) REFERENCES mentors(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY(knowledge_id) REFERENCES knowledge(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE teachers_experience (
|
||||
teacher_id BIGINT,
|
||||
knowledge_id BIGINT,
|
||||
FOREIGN KEY(teacher_id) REFERENCES teachers(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY(knowledge_id) REFERENCES knowledge(id) ON DELETE CASCADE
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user