2023-03 spring-10-orm added

This commit is contained in:
stvort
2023-04-27 19:53:24 +04:00
parent d9711739b2
commit b634c817dd
127 changed files with 3593 additions and 0 deletions
@@ -0,0 +1,4 @@
.idea/
*.iml
target/
@@ -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,2 @@
# mybatis-demo
Пример работы с БД через MyBatis
@@ -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.7.8</version>
-->
<version>3.0.6</version>
<relativePath/>
</parent>
<groupId>ru.otus.example</groupId>
<artifactId>mybatis-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mybatis-demo</name>
<description>MyBatis demo</description>
<properties>
<!--
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<mybatis.version>2.2.2</mybatis.version>
-->
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<mybatis.version>3.0.1</mybatis.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.version}</version>
</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>
</project>
@@ -0,0 +1,14 @@
package ru.otus.example.mybatisdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class MyBatisDemoApplication {
public static void main(String[] args) {
SpringApplication.run(MyBatisDemoApplication.class, args);
}
}
@@ -0,0 +1,13 @@
package ru.otus.example.mybatisdemo.models;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Avatar {
private long id;
private String photoUrl;
}
@@ -0,0 +1,13 @@
package ru.otus.example.mybatisdemo.models;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Course {
private long id;
private String name;
}
@@ -0,0 +1,13 @@
package ru.otus.example.mybatisdemo.models;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class EMail {
private long id;
private String email;
}
@@ -0,0 +1,18 @@
package ru.otus.example.mybatisdemo.models;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OtusStudent {
private long id;
private String name;
private Avatar avatar;
private List<EMail> emails;
private List<Course> courses;
}
@@ -0,0 +1,18 @@
package ru.otus.example.mybatisdemo.repositories;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import ru.otus.example.mybatisdemo.models.Avatar;
@Mapper
public interface AvatarRepository {
@Select("select * from avatars where id = #{id}")
@Results(value = {
@Result(property = "id", column = "id"),
@Result(property = "photoUrl", column = "photo_url")
})
Avatar getAvatarById(long id);
}
@@ -0,0 +1,17 @@
package ru.otus.example.mybatisdemo.repositories;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import ru.otus.example.mybatisdemo.models.Course;
import java.util.List;
@Mapper
public interface CourseRepository {
@Select("select * " +
"from student_courses sc left join courses c on sc.course_id = c.id " +
"where sc.student_id = #{studentId}")
List<Course> getCoursesByStudentId(long studentId);
}
@@ -0,0 +1,14 @@
package ru.otus.example.mybatisdemo.repositories;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import ru.otus.example.mybatisdemo.models.EMail;
import java.util.List;
@Mapper
public interface EmailRepository {
@Select("select * from emails where student_id = #{studentId}")
List<EMail> getEmailsByStudentId(long studentId);
}
@@ -0,0 +1,42 @@
package ru.otus.example.mybatisdemo.repositories;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import ru.otus.example.mybatisdemo.models.Avatar;
import ru.otus.example.mybatisdemo.models.OtusStudent;
import java.util.List;
@Mapper
public interface OtusStudentRepository {
@Select("select * from otus_students")
@Results(id = "studentAllMap", value = {
@Result(property = "id", column = "id"),
@Result(property = "name", column = "name"),
@Result(property = "avatar", column = "avatar_id", javaType = Avatar.class,
one = @One(select = "ru.otus.example.mybatisdemo.repositories.AvatarRepository.getAvatarById", fetchType = FetchType.EAGER)),
@Result(property = "emails", column = "id", javaType = List.class,
many = @Many(select = "ru.otus.example.mybatisdemo.repositories.EmailRepository.getEmailsByStudentId", fetchType = FetchType.EAGER)),
@Result(property = "courses", column = "id", javaType = List.class,
many = @Many(select = "ru.otus.example.mybatisdemo.repositories.CourseRepository.getCoursesByStudentId", fetchType = FetchType.EAGER))
})
List<OtusStudent> findAllWithAllInfo();
@Select("select * from otus_students where id = #{id}")
@ResultMap("studentAllMap")
OtusStudent findById(long id);
@Select("select count(*) as students_count from otus_students")
long getStudentsCount();
@Insert("insert into otus_students(name, avatar_id) values (#{name}, #{avatar.id})")
void insert(OtusStudent student);
@Update("update otus_students set name = #{name} where id = #{id}")
void updateName(OtusStudent student);
@Delete("delete from otus_students where id = #{id}")
void deleteById(long id);
}
@@ -0,0 +1,31 @@
create table avatars(
id bigserial,
photo_url varchar(8000),
primary key (id)
);
create table courses(
id bigserial,
name varchar(255),
primary key (id)
);
create table otus_students(
id bigserial,
name varchar(255),
avatar_id bigint references avatars (id),
primary key (id)
);
create table emails(
id bigserial,
student_id bigint references otus_students(id) on delete cascade,
email varchar(255),
primary key (id)
);
create table student_courses(
student_id bigint references otus_students(id) on delete cascade,
course_id bigint references courses(id),
primary key (student_id, course_id)
);
@@ -0,0 +1,110 @@
package ru.otus.example.mybatisdemo.repositories;
import lombok.val;
import org.assertj.core.api.recursive.comparison.RecursiveComparisonConfiguration;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
import ru.otus.example.mybatisdemo.models.Avatar;
import ru.otus.example.mybatisdemo.models.OtusStudent;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@DisplayName("Репозиторий на основе MyBatis для работы со студентами ")
@SpringBootTest
@Transactional
public class OtusStudentRepositoryTest {
private static final String FIELD_ID = "id";
private static final String FIELD_PHOTO_URL = "photoUrl";
private static final String FIELD_NAME = "name";
private static final long FIRST_STUDENT_ID = 1L;
private static final long FIRST_AVATAR_ID = 1L;
private static final String FIRST_STUDENT_NAME = "student_01";
private static final String FIRST_AVATAR_URL = "photoUrl_01";
private static final String STUDENT_NEW_NAME = "Висусуалий";
private static final int EXPECTED_NUMBER_OF_STUDENTS = 10;
private static final long INSERTED_STUDENT_ID = 11L;
private static final int EXPECTED_EMAILS_COUNT = 2;
private static final int EXPECTED_COURSES_COUNT = 3;
@Autowired
private OtusStudentRepository studentRepositoryMyBatis;
@DisplayName("должен загружать список всех студентов с полной информацией о них")
@Test
void shouldReturnCorrectStudentsListWithAllInfo() {
val students = studentRepositoryMyBatis.findAllWithAllInfo();
assertThat(students).isNotNull().hasSize(EXPECTED_NUMBER_OF_STUDENTS)
.allMatch(s -> !s.getName().equals(""))
.allMatch(s -> s.getCourses() != null && s.getCourses().size() > 0)
.allMatch(s -> s.getAvatar() != null)
.allMatch(s -> s.getEmails() != null && s.getEmails().size() > 0);
}
@DisplayName("должен загружать число студентов в БД")
@Test
void shouldReturnCorrectStudentsCount() {
long studentsCount = studentRepositoryMyBatis.getStudentsCount();
assertThat(studentsCount).isEqualTo(EXPECTED_NUMBER_OF_STUDENTS);
}
@DisplayName(" должен загружать информацию о нужном студенте")
@Test
void shouldFindExpectedStudentById(){
val actualStudent = studentRepositoryMyBatis.findById(FIRST_STUDENT_ID);
assertThat(actualStudent).isNotNull();
assertThat(actualStudent.getName()).isEqualTo(FIRST_STUDENT_NAME);
assertThat(actualStudent.getAvatar()).isNotNull()
.hasFieldOrPropertyWithValue(FIELD_ID, FIRST_STUDENT_ID)
.hasFieldOrPropertyWithValue(FIELD_PHOTO_URL, FIRST_AVATAR_URL);
assertThat(actualStudent.getEmails()).isNotNull().hasSize(EXPECTED_EMAILS_COUNT);
assertThat(actualStudent.getCourses()).isNotNull().hasSize(EXPECTED_COURSES_COUNT);
}
@DisplayName(" должен сохранить, а потом загрузить информацию о нужном студенте")
@Test
void shouldSaveAndLoadCorrectStudent() {
val expectedStudent = new OtusStudent(0, STUDENT_NEW_NAME,
new Avatar(FIRST_AVATAR_ID, FIRST_AVATAR_URL), List.of(), List.of());
studentRepositoryMyBatis.insert(expectedStudent);
val actualStudent = studentRepositoryMyBatis.findById(INSERTED_STUDENT_ID);
assertThat(actualStudent)
.isNotNull()
.usingRecursiveComparison(
RecursiveComparisonConfiguration.builder()
.withIgnoredFields(FIELD_ID).build())
.isEqualTo(expectedStudent);
}
@DisplayName(" должен обновлять имя студента в БД")
@Test
void shouldUpdateStudentName() {
val student = studentRepositoryMyBatis.findById(FIRST_STUDENT_ID);
student.setName(STUDENT_NEW_NAME);
studentRepositoryMyBatis.updateName(student);
val actualStudent = studentRepositoryMyBatis.findById(FIRST_STUDENT_ID);
assertThat(actualStudent).isNotNull().hasFieldOrPropertyWithValue(FIELD_NAME, student.getName());
}
@DisplayName("должен удалять студента из БД по id")
@Test
void shouldDeleteStudentFromDbById() {
val studentsCountBefore = studentRepositoryMyBatis.getStudentsCount();
studentRepositoryMyBatis.deleteById(FIRST_STUDENT_ID);
val studentsCountAfter = studentRepositoryMyBatis.getStudentsCount();
assertThat(studentsCountBefore - studentsCountAfter).isEqualTo(1);
}
}
@@ -0,0 +1,8 @@
spring:
datasource:
url: jdbc:h2:mem:testdb
initialization-mode: always
logging:
level:
ru.otus.example.mybatisdemo.repositories: TRACE
@@ -0,0 +1,29 @@
insert into avatars(photo_url)
values ('photoUrl_01'), ('photoUrl_02'), ('photoUrl_03'), ('photoUrl_04'), ('photoUrl_05'),
('photoUrl_06'), ('photoUrl_07'), ('photoUrl_08'), ('photoUrl_09'), ('photoUrl_10');
insert into courses(name)
values ('course_name_01'), ('course_name_02'), ('course_name_03'), ('course_name_04'), ('course_name_05'),
('course_name_06'), ('course_name_07'), ('course_name_08'), ('course_name_09'), ('course_name_10'), ('not_used_11');
insert into otus_students(name, avatar_id)
values ('student_01', 1), ('student_02', 2), ('student_03', 3), ('student_04', 4), ('student_05', 5),
('student_06', 6), ('student_07', 7), ('student_08', 8), ('student_09', 9), ('student_10', 10);
insert into emails(email, student_id)
values ('email_01', 1), ('email_02', 1), ('email_03', 2), ('email_04', 2), ('email_05', 3), ('email_06', 4),
('email_07', 5), ('email_08', 6), ('email_09', 7), ('email_10', 8), ('email_11', 9), ('email_12', 10);
insert into student_courses(student_id, course_id)
values (1, 1), (1, 2), (1, 3),
(2, 2), (2, 4), (2, 5),
(3, 3), (3, 6), (3, 7),
(4, 4), (4, 8), (4, 9),
(5, 5), (5, 10), (5, 1),
(6, 6), (6, 2), (6, 3),
(7, 7), (7, 4), (7, 5),
(8, 8), (8, 6), (8, 7),
(9, 9), (9, 8), (9, 10),
(10, 10), (10, 1), (10, 2);
@@ -0,0 +1,18 @@
<?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>ru.otus</groupId>
<artifactId>demo-projects</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<modules>
<module>spring-jdbc-demo</module>
<module>spring-jpa-ineritance-demo</module>
<module>mybatis-demo</module>
</modules>
</project>
@@ -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,2 @@
# spring-jdbc-demo
Пример работы с БД через jdbc
@@ -0,0 +1,66 @@
<?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.7.8</version>
-->
<version>3.0.6</version>
<relativePath/>
</parent>
<groupId>ru.otus.example</groupId>
<artifactId>spring-jdbc-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-jdbc-demo</name>
<description>Spring jdbc demo</description>
<properties>
<!--
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
-->
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</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>
</project>
@@ -0,0 +1,13 @@
package ru.otus.example.springjdbcdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringJdbcDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringJdbcDemoApplication.class, args);
}
}
@@ -0,0 +1,13 @@
package ru.otus.example.springjdbcdemo.models;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Avatar {
private long id;
private String photoUrl;
}
@@ -0,0 +1,13 @@
package ru.otus.example.springjdbcdemo.models;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Course {
private long id;
private String name;
}
@@ -0,0 +1,13 @@
package ru.otus.example.springjdbcdemo.models;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class EMail {
private long id;
private String email;
}
@@ -0,0 +1,18 @@
package ru.otus.example.springjdbcdemo.models;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OtusStudent {
private long id;
private String name;
private Avatar avatar;
private List<EMail> emails;
private List<Course> courses;
}
@@ -0,0 +1,9 @@
package ru.otus.example.springjdbcdemo.repositories;
import ru.otus.example.springjdbcdemo.models.Course;
import java.util.List;
public interface CourseRepository {
List<Course> findAllUsed();
}
@@ -0,0 +1,35 @@
package ru.otus.example.springjdbcdemo.repositories;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import ru.otus.example.springjdbcdemo.models.Course;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
@Repository
@RequiredArgsConstructor
public class CourseRepositoryJdbc implements CourseRepository {
private final JdbcOperations op;
@Override
public List<Course> findAllUsed() {
return op.query("select c.id, c.name " +
"from courses c inner join student_courses sc on c.id = sc.course_id " +
"group by c.id, c.name " +
"order by c.name", new CourseRowMapper());
}
private static class CourseRowMapper implements RowMapper<Course> {
@Override
public Course mapRow(ResultSet rs, int i) throws SQLException {
return new Course(rs.getLong(1), rs.getString(2));
}
}
}
@@ -0,0 +1,9 @@
package ru.otus.example.springjdbcdemo.repositories;
import ru.otus.example.springjdbcdemo.models.OtusStudent;
import java.util.List;
public interface OtusStudentRepository {
List<OtusStudent> findAllWithAllInfo();
}
@@ -0,0 +1,52 @@
package ru.otus.example.springjdbcdemo.repositories;
import lombok.RequiredArgsConstructor;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.stereotype.Repository;
import ru.otus.example.springjdbcdemo.models.Course;
import ru.otus.example.springjdbcdemo.models.OtusStudent;
import ru.otus.example.springjdbcdemo.repositories.ext.OtusStudentResultSetExtractor;
import ru.otus.example.springjdbcdemo.repositories.ext.StudentCourseRelation;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@Repository
@RequiredArgsConstructor
public class OtusStudentRepositoryJdbc implements OtusStudentRepository {
private final CourseRepository courseRepository;
private final JdbcOperations op;
@Override
public List<OtusStudent> findAllWithAllInfo() {
List<Course> courses = courseRepository.findAllUsed();
List<StudentCourseRelation> relations = getAllRelations();
Map<Long, OtusStudent> students =
op.query("select os.id, os.name, a.id avatar_id, a.photo_url, e.id email_id, e.email " +
"from (otus_students os left join avatars a on " +
"os.avatar_id = a.id) left join emails e on os.id = e.student_id",
new OtusStudentResultSetExtractor());
mergeStudentsInfo(students, courses, relations);
return new ArrayList<>(Objects.requireNonNull(students).values());
}
private List<StudentCourseRelation> getAllRelations() {
return op.query("select student_id, course_id from student_courses sc order by student_id, course_id",
(rs, i) -> new StudentCourseRelation(rs.getLong(1), rs.getLong(2)));
}
private void mergeStudentsInfo(Map<Long, OtusStudent> students, List<Course> courses,
List<StudentCourseRelation> relations) {
Map<Long, Course> coursesMap = courses.stream().collect(Collectors.toMap(Course::getId, Function.identity()));
relations.forEach(r -> {
if (students.containsKey(r.getStudentId()) && coursesMap.containsKey(r.getCourseId())) {
students.get(r.getStudentId()).getCourses().add(coursesMap.get(r.getCourseId()));
}
});
}
}
@@ -0,0 +1,37 @@
package ru.otus.example.springjdbcdemo.repositories.ext;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;
import ru.otus.example.springjdbcdemo.models.Avatar;
import ru.otus.example.springjdbcdemo.models.EMail;
import ru.otus.example.springjdbcdemo.models.OtusStudent;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class OtusStudentResultSetExtractor implements
ResultSetExtractor<Map<Long, OtusStudent>> {
@Override
public Map<Long, OtusStudent> extractData(ResultSet rs) throws SQLException,
DataAccessException {
Map<Long, OtusStudent> students = new HashMap<>();
while (rs.next()) {
long id = rs.getLong("id");
OtusStudent student = students.get(id);
if (student == null) {
student = new OtusStudent(id, rs.getString("name"),
new Avatar(rs.getLong("avatar_id"), rs.getString("photo_url")),
new ArrayList<>(), new ArrayList<>());
students.put(student.getId(), student);
}
student.getEmails().add(new EMail(rs.getLong("email_id"),
rs.getString("email")));
}
return students;
}
}
@@ -0,0 +1,11 @@
package ru.otus.example.springjdbcdemo.repositories.ext;
import lombok.Data;
import lombok.RequiredArgsConstructor;
@Data
@RequiredArgsConstructor
public class StudentCourseRelation {
private final long studentId;
private final long courseId;
}
@@ -0,0 +1,31 @@
create table avatars(
id bigserial,
photo_url varchar(8000),
primary key (id)
);
create table courses(
id bigserial,
name varchar(255),
primary key (id)
);
create table otus_students(
id bigserial,
name varchar(255),
avatar_id bigint references avatars (id),
primary key (id)
);
create table emails(
id bigserial,
student_id bigint references otus_students(id) on delete cascade,
email varchar(255),
primary key (id)
);
create table student_courses(
student_id bigint references otus_students(id) on delete cascade,
course_id bigint references courses(id),
primary key (student_id, course_id)
);
@@ -0,0 +1,35 @@
package ru.otus.example.springjdbcdemo.repositories;
import lombok.val;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest;
import org.springframework.context.annotation.Import;
import static org.assertj.core.api.Assertions.assertThat;
@DisplayName("Репозиторий на основе Jdbc для работы со студентами ")
@JdbcTest
@Import({OtusStudentRepositoryJdbc.class, CourseRepositoryJdbc.class})
class OtusStudentRepositoryJdbcTest {
private static final int EXPECTED_NUMBER_OF_STUDENTS = 10;
@Autowired
private OtusStudentRepositoryJdbc repositoryJdbc;
@DisplayName("должен загружать список всех студентов с полной информацией о них")
@Test
void shouldReturnCorrectStudentsListWithAllInfo() {
val students = repositoryJdbc.findAllWithAllInfo();
assertThat(students).isNotNull().hasSize(EXPECTED_NUMBER_OF_STUDENTS)
.allMatch(s -> !s.getName().equals(""))
.allMatch(s -> s.getCourses() != null && s.getCourses().size() > 0)
.allMatch(s -> s.getAvatar() != null)
.allMatch(s -> s.getEmails() != null && s.getEmails().size() > 0);
students.forEach(System.out::println);
}
}
@@ -0,0 +1,4 @@
spring:
datasource:
url: jdbc:h2:mem:testdb
initialization-mode: always
@@ -0,0 +1,29 @@
insert into avatars(photo_url)
values ('photoUrl_01'), ('photoUrl_02'), ('photoUrl_03'), ('photoUrl_04'), ('photoUrl_05'),
('photoUrl_06'), ('photoUrl_07'), ('photoUrl_08'), ('photoUrl_09'), ('photoUrl_10');
insert into courses(name)
values ('course_name_01'), ('course_name_02'), ('course_name_03'), ('course_name_04'), ('course_name_05'),
('course_name_06'), ('course_name_07'), ('course_name_08'), ('course_name_09'), ('course_name_10'), ('not_used_11');
insert into otus_students(name, avatar_id)
values ('student_01', 1), ('student_02', 2), ('student_03', 3), ('student_04', 4), ('student_05', 5),
('student_06', 6), ('student_07', 7), ('student_08', 8), ('student_09', 9), ('student_10', 10);
insert into emails(email, student_id)
values ('email_01', 1), ('email_02', 1), ('email_03', 2), ('email_04', 2), ('email_05', 3), ('email_06', 4),
('email_07', 5), ('email_08', 6), ('email_09', 7), ('email_10', 8), ('email_11', 9), ('email_12', 10);
insert into student_courses(student_id, course_id)
values (1, 1), (1, 2), (1, 3),
(2, 2), (2, 4), (2, 5),
(3, 3), (3, 6), (3, 7),
(4, 4), (4, 8), (4, 9),
(5, 5), (5, 10), (5, 1),
(6, 6), (6, 2), (6, 3),
(7, 7), (7, 4), (7, 5),
(8, 8), (8, 6), (8, 7),
(9, 9), (9, 8), (9, 10),
(10, 10), (10, 1), (10, 2);
@@ -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,2 @@
# spring-jdbc-demo
Пример работы с БД через jdbc
@@ -0,0 +1,66 @@
<?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.7.8</version>
-->
<version>3.0.6</version>
<relativePath/>
</parent>
<groupId>ru.otus.example</groupId>
<artifactId>spring-jpa-ineritance-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-jpa-demo</name>
<description>Spring jpa demo</description>
<properties>
<!--
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
-->
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.0.202</version>
</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>
</project>
@@ -0,0 +1,43 @@
package ru.otus.example.ineritancedemo;
import org.h2.tools.Console;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import ru.otus.example.ineritancedemo.model.A;
import ru.otus.example.ineritancedemo.model.C;
import ru.otus.example.ineritancedemo.model.B;
import ru.otus.example.ineritancedemo.repository.ARepository;
import java.sql.SQLException;
import java.util.List;
@SpringBootApplication
public class InheritanceDemo {
public static void main(String[] args) throws SQLException {
ConfigurableApplicationContext ctx = SpringApplication.run(InheritanceDemo.class, args);
ARepository aRepository = ctx.getBean(ARepository.class);
System.out.println("\n\n-------------------------------------------\n\n");
System.out.println("Начинаем вставку сущностей A/B/C: ");
var a = new A(0, "aaaaaa1");
var b = new B(0, "aaaaaa2", "bbbbbbb");
var c = new C(0, "aaaaaa3", "ccccccc");
aRepository.save(a);
aRepository.save(b);
aRepository.save(c);
System.out.println("\n\n-------------------------------------------\n\n");
System.out.println("Загружаем все сущности A (в т.ч. наследников):");
List<A> resultList = aRepository.findAll();
System.out.println("\n\nРезультат:");
System.out.println(resultList);
Console.main();
}
}
@@ -0,0 +1,45 @@
package ru.otus.example.ineritancedemo.model;
import jakarta.persistence.DiscriminatorColumn;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Inheritance;
import jakarta.persistence.InheritanceType;
import jakarta.persistence.Table;
@Entity
@DiscriminatorColumn(name = "discriminator")
@DiscriminatorValue("RootA")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
//@Inheritance(strategy = InheritanceType.JOINED)
//@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Table(name = "A")
public class A {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
// Не получится использовать при InheritanceType.TABLE_PER_CLASS
//@GeneratedValue(strategy = GenerationType.IDENTITY)
protected long id;
protected String a;
public A() {
}
public A(long id, String a) {
this.id = id;
this.a = a;
}
@Override
public String toString() {
return "A{" +
"id=" + id +
", a='" + a + '\'' +
'}';
}
}
@@ -0,0 +1,30 @@
package ru.otus.example.ineritancedemo.model;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
@Entity
@Table(name = "B")
@DiscriminatorValue("LeafB")
public class B extends A {
private String b;
public B() {
super();
}
public B(long id, String a, String b) {
super(id, a);
this.b = b;
}
@Override
public String toString() {
return "B{" +
"id=" + id +
", a='" + a + '\'' +
", b='" + b + '\'' +
'}';
}
}
@@ -0,0 +1,33 @@
package ru.otus.example.ineritancedemo.model;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
@Entity
@Table(name = "C")
@DiscriminatorValue("LeafC")
public class C extends A{
private String c;
public C() {
super();
}
public C(long id, String a, String c) {
super(id, a);
this.c = c;
}
@Override
public String toString() {
return "C{" +
"id=" + id +
", a='" + a + '\'' +
", c='" + c + '\'' +
'}';
}
}
@@ -0,0 +1,10 @@
package ru.otus.example.ineritancedemo.repository;
import ru.otus.example.ineritancedemo.model.A;
import java.util.List;
public interface ARepository {
List<A> findAll();
void save(A a);
}
@@ -0,0 +1,32 @@
package ru.otus.example.ineritancedemo.repository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import ru.otus.example.ineritancedemo.model.A;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.TypedQuery;
import java.util.List;
@Repository
@RequiredArgsConstructor
public class ARepositoryJpa implements ARepository {
@PersistenceContext
private final EntityManager em;
@Transactional(readOnly = true) // Только для примера. Лучше вешать на методы сервисов
@Override
public List<A> findAll() {
TypedQuery<A> query = em.createQuery("select a from A a", A.class);
return query.getResultList();
}
@Transactional // Только для примера. Лучше вешать на методы сервисов
@Override
public void save(A a) {
em.persist(a);
}
}
@@ -0,0 +1,20 @@
spring:
datasource:
url: jdbc:h2:mem:testdb
initialization-mode: never
jpa:
generate-ddl: true
hibernate:
ddl-auto: create
properties:
hibernate:
format_sql: true
show-sql: true
logging:
level:
ROOT: ERROR
@@ -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,66 @@
<?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.7.9</version>
-->
<version>3.0.6</version>
<relativePath/>
</parent>
<groupId>ru.otus.example</groupId>
<artifactId>orm-exercise</artifactId>
<name>orm-exercise</name>
<version>0.0.1-SNAPSHOT</version>
<properties>
<!--
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
-->
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
</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>
</project>
@@ -0,0 +1,17 @@
package ru.otus.example.ormdemo;
import org.h2.tools.Console;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.sql.SQLException;
@SpringBootApplication
public class OrmDemoApplication {
public static void main(String[] args) throws SQLException {
SpringApplication.run(OrmDemoApplication.class, args);
Console.main(args);
}
}
@@ -0,0 +1,15 @@
package ru.otus.example.ormdemo.models;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import jakarta.persistence.*;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Avatar {
private long id;
private String photoUrl;
}
@@ -0,0 +1,15 @@
package ru.otus.example.ormdemo.models;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import jakarta.persistence.*;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Course {
private long id;
private String name;
}
@@ -0,0 +1,15 @@
package ru.otus.example.ormdemo.models;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import jakarta.persistence.*;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EMail {
private long id;
private String email;
}
@@ -0,0 +1,18 @@
package ru.otus.example.ormdemo.models;
import lombok.*;
import jakarta.persistence.*;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OtusStudent {
private long id;
private String name;
//private Avatar avatar;
//private List<EMail> emails;
//private List<Course> courses;
}
@@ -0,0 +1,20 @@
spring:
datasource:
url: jdbc:h2:mem:testdb
initialization-mode: never
jpa:
generate-ddl: true
hibernate:
ddl-auto: create
properties:
hibernate:
format_sql: true
show-sql: true
logging:
level:
ROOT: ERROR
@@ -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,66 @@
<?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.7.8</version>
-->
<version>3.0.6</version>
<relativePath/>
</parent>
<groupId>ru.otus.example</groupId>
<artifactId>orm-solution-01</artifactId>
<name>orm-solution-01</name>
<version>0.0.1-SNAPSHOT</version>
<properties>
<!--
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
-->
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
</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>
</project>
@@ -0,0 +1,17 @@
package ru.otus.example.ormdemo;
import org.h2.tools.Console;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.sql.SQLException;
@SpringBootApplication
public class OrmDemoApplication {
public static void main(String[] args) throws SQLException {
SpringApplication.run(OrmDemoApplication.class, args);
//Console.main(args);
}
}
@@ -0,0 +1,17 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Avatar {
@Id
private long id;
private String photoUrl;
}
@@ -0,0 +1,17 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Course {
@Id
private long id;
private String name;
}
@@ -0,0 +1,17 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class EMail {
@Id
private long id;
private String email;
}
@@ -0,0 +1,23 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity // Указывает, что данный класс является сущностью
public class OtusStudent {
@Id // Позволяет указать какое поле является идентификатором
private long id;
private String name;
//private Avatar avatar;
//private List<EMail> emails;
//private List<Course> courses;
}
@@ -0,0 +1,20 @@
spring:
datasource:
url: jdbc:h2:mem:testdb
initialization-mode: never
jpa:
generate-ddl: true
hibernate:
ddl-auto: create
properties:
hibernate:
format_sql: true
show-sql: true
logging:
level:
ROOT: ERROR
@@ -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,65 @@
<?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.7.8</version>
-->
<version>3.0.6</version>
<relativePath/>
</parent>
<groupId>ru.otus.example</groupId>
<artifactId>orm-solution-02</artifactId>
<name>orm-solution-02</name>
<version>0.0.1-SNAPSHOT</version>
<properties>
<!--
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
-->
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
</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>
</project>
@@ -0,0 +1,17 @@
package ru.otus.example.ormdemo;
import org.h2.tools.Console;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.sql.SQLException;
@SpringBootApplication
public class OrmDemoApplication {
public static void main(String[] args) throws SQLException {
SpringApplication.run(OrmDemoApplication.class, args);
//Console.main(args);
}
}
@@ -0,0 +1,22 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "avatars")
public class Avatar {
@Id
private long id;
@Column(name = "photo_url")
private String photoUrl;
}
@@ -0,0 +1,22 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "courses")
public class Course {
@Id
private long id;
@Column(name = "name")
private String name;
}
@@ -0,0 +1,23 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "emails")
public class EMail {
@Id
private long id;
@Column(name = "email")
private String email;
}
@@ -0,0 +1,27 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.*;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity // Указывает, что данный класс является сущностью
@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность
public class OtusStudent {
@Id // Позволяет указать какое поле является идентификатором
private long id;
// Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности
@Column(name = "name")
private String name;
//private Avatar avatar;
//private List<EMail> emails;
//private List<Course> courses;
}
@@ -0,0 +1,20 @@
spring:
datasource:
url: jdbc:h2:mem:testdb
initialization-mode: never
jpa:
generate-ddl: true
hibernate:
ddl-auto: create
properties:
hibernate:
format_sql: true
show-sql: true
logging:
level:
ROOT: ERROR
@@ -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,66 @@
<?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.7.8</version>
-->
<version>3.0.6</version>
<relativePath/>
</parent>
<groupId>ru.otus.example</groupId>
<artifactId>orm-solution-03</artifactId>
<name>orm-solution-03</name>
<version>0.0.1-SNAPSHOT</version>
<properties>
<!--
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
-->
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
</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>
</project>
@@ -0,0 +1,17 @@
package ru.otus.example.ormdemo;
import org.h2.tools.Console;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.sql.SQLException;
@SpringBootApplication
public class OrmDemoApplication {
public static void main(String[] args) throws SQLException {
SpringApplication.run(OrmDemoApplication.class, args);
//Console.main(args);
}
}
@@ -0,0 +1,25 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "avatars")
public class Avatar {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "photo_url")
private String photoUrl;
}
@@ -0,0 +1,25 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "courses")
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "name")
private String name;
}
@@ -0,0 +1,26 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "emails")
public class EMail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "email")
private String email;
}
@@ -0,0 +1,32 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity // Указывает, что данный класс является сущностью
@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность
public class OtusStudent {
@Id // Позволяет указать какое поле является идентификатором
@GeneratedValue(strategy = GenerationType.IDENTITY) // Позволяет указать стратегию генерации id
private long id;
// Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности
@Column(name = "name")
private String name;
//private Avatar avatar;
//private List<EMail> emails;
//private List<Course> courses;
}
@@ -0,0 +1,20 @@
spring:
datasource:
url: jdbc:h2:mem:testdb
initialization-mode: never
jpa:
generate-ddl: true
hibernate:
ddl-auto: create
properties:
hibernate:
format_sql: true
show-sql: true
logging:
level:
ROOT: ERROR
@@ -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,67 @@
<?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.7.8</version>
-->
<version>3.0.6</version>
<relativePath/>
</parent>
<groupId>ru.otus.example</groupId>
<artifactId>orm-solution-04</artifactId>
<name>orm-solution-04</name>
<version>0.0.1-SNAPSHOT</version>
<properties>
<!--
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
-->
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
</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>
</project>
@@ -0,0 +1,17 @@
package ru.otus.example.ormdemo;
import org.h2.tools.Console;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.sql.SQLException;
@SpringBootApplication
public class OrmDemoApplication {
public static void main(String[] args) throws SQLException {
SpringApplication.run(OrmDemoApplication.class, args);
//Console.main(args);
}
}
@@ -0,0 +1,25 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "avatars")
public class Avatar {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "photo_url")
private String photoUrl;
}
@@ -0,0 +1,25 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "courses")
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "name")
private String name;
}
@@ -0,0 +1,26 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "emails")
public class EMail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "email")
private String email;
}
@@ -0,0 +1,41 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity // Указывает, что данный класс является сущностью
@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность
public class OtusStudent {
@Id // Позволяет указать какое поле является идентификатором
@GeneratedValue(strategy = GenerationType.IDENTITY) // Стратегия генерации идентификаторов
private long id;
// Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности
@Column(name = "name", nullable = false, unique = true)
private String name;
// Указывает на связь между таблицами "один к одному"
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
// Задает поле, по которому происходит объединение с таблицей для хранения связанной сущности
@JoinColumn(name = "avatar_id")
private Avatar avatar;
//private List<EMail> emails;
//private List<Course> courses;
}
@@ -0,0 +1,20 @@
spring:
datasource:
url: jdbc:h2:mem:testdb
initialization-mode: never
jpa:
generate-ddl: true
hibernate:
ddl-auto: create
properties:
hibernate:
format_sql: true
show-sql: true
logging:
level:
ROOT: ERROR
@@ -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,67 @@
<?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.7.8</version>
-->
<version>3.0.6</version>
<relativePath/>
</parent>
<groupId>ru.otus.example</groupId>
<artifactId>orm-solution-05</artifactId>
<name>orm-solution-04</name>
<version>0.0.1-SNAPSHOT</version>
<properties>
<!--
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
-->
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
</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>
</project>
@@ -0,0 +1,14 @@
package ru.otus.example.ormdemo;
import org.h2.tools.Console;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class OrmDemoApplication {
public static void main(String[] args) {
SpringApplication.run(OrmDemoApplication.class, args);
//Console.main(args);
}
}
@@ -0,0 +1,30 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "avatars")
public class Avatar {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "photo_url")
private String photoUrl;
@OneToOne(fetch = FetchType.LAZY)
private OtusStudent student;
}
@@ -0,0 +1,25 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "courses")
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "name")
private String name;
}
@@ -0,0 +1,26 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "emails")
public class EMail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "email")
private String email;
}
@@ -0,0 +1,38 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity // Указывает, что данный класс является сущностью
@Table(name = "otus_students") // Задает имя таблицы, на которую будет отображаться сущность
public class OtusStudent {
@Id // Позволяет указать какое поле является идентификатором
@GeneratedValue(strategy = GenerationType.IDENTITY) // Стратегия генерации идентификаторов
private long id;
// Задает имя и некоторые свойства поля таблицы, на которое будет отображаться поле сущности
@Column(name = "name", nullable = false, unique = true)
private String name;
// Указывает на связь между таблицами "один к одному"
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
private Avatar avatar;
//private List<EMail> emails;
//private List<Course> courses;
}
@@ -0,0 +1,20 @@
spring:
datasource:
url: jdbc:h2:mem:testdb
initialization-mode: never
jpa:
generate-ddl: true
hibernate:
ddl-auto: create
properties:
hibernate:
format_sql: true
show-sql: true
logging:
level:
ROOT: ERROR
@@ -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,67 @@
<?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.7.8</version>
-->
<version>3.0.6</version>
<relativePath/>
</parent>
<groupId>ru.otus.example</groupId>
<artifactId>orm-solution-06</artifactId>
<name>orm-solution-04</name>
<version>0.0.1-SNAPSHOT</version>
<properties>
<!--
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
-->
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
</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>
</project>
@@ -0,0 +1,15 @@
package ru.otus.example.ormdemo;
import org.h2.tools.Console;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class OrmDemoApplication {
public static void main(String[] args) {
SpringApplication.run(OrmDemoApplication.class, args);
//Console.main(args);
}
}
@@ -0,0 +1,30 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "avatars")
public class Avatar {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "photo_url")
private String photoUrl;
@OneToOne(fetch = FetchType.LAZY)
private OtusStudent student;
}
@@ -0,0 +1,25 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "courses")
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "name")
private String name;
}
@@ -0,0 +1,26 @@
package ru.otus.example.ormdemo.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "emails")
public class EMail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "email")
private String email;
}

Some files were not shown because too many files have changed in this diff Show More