diff --git a/back-skeleton/README.MD b/back-skeleton/README.MD index 4ec03ee7d2825896b858a0b3733b23332dad2b3c..4bebebfa8d96376b293d1ec635ac06769d25f0cc 100644 --- a/back-skeleton/README.MD +++ b/back-skeleton/README.MD @@ -2,6 +2,7 @@ ## Set up 1. Copie-colle le .env.sample en .env +2. Fait un `docker-compose up` 2. Rajoute le pluggin : https://plugins.jetbrains.com/plugin/7861-envfile 3. <img src="img-readme/img.png"> 3. <img src="img-readme/img_1.png"> diff --git a/back-skeleton/initdb/1_TABLES.sql b/back-skeleton/initdb/1_TABLES.sql new file mode 100644 index 0000000000000000000000000000000000000000..a71ee28ad95b60a4cbd4df61229f60158cf6363b --- /dev/null +++ b/back-skeleton/initdb/1_TABLES.sql @@ -0,0 +1,30 @@ +create table students +( + id SERIAL PRIMARY KEY, + first_name TEXT not null, + last_name TEXT not null, + birthdate date null, + major_id int null, + image bytea null +); + +create table majors +( + id SERIAL PRIMARY KEY, + name TEXT not null, + description TEXT not null +); + +create table courses +( + id SERIAL PRIMARY KEY, + name TEXT not null, + hours int not null +); + +create table student_course +( + id SERIAL PRIMARY KEY, + student_id int not null, + course_id int not null +); diff --git a/back-skeleton/initdb/2_DEFAULT_ENTRIES.sql b/back-skeleton/initdb/2_DEFAULT_ENTRIES.sql new file mode 100644 index 0000000000000000000000000000000000000000..ae5925afbdbdd1ba3f9bb0a635c2fc7bfcd1d9e5 --- /dev/null +++ b/back-skeleton/initdb/2_DEFAULT_ENTRIES.sql @@ -0,0 +1,8 @@ +INSERT INTO majors (id, name, description) VALUES (1, 'MIN', 'Ouaiiis du code partout'); + +INSERT INTO students (id, first_name, last_name, birthdate, major_id, image) VALUES (1, 'Paul', 'Harrohide', '2002-06-15', 1, null); + +INSERT INTO courses (id, name, hours) VALUES (1, 'Java', 30); +INSERT INTO student_course (id, student_id, course_id) VALUES (1, 1, 1); + + diff --git a/back-skeleton/pom.xml b/back-skeleton/pom.xml index 9c08aa8f2eb5604c9ee19a31340788fd4e4d7fe2..d63e5302b76f69ae97195623daf5e7439bee2e5c 100644 --- a/back-skeleton/pom.xml +++ b/back-skeleton/pom.xml @@ -15,6 +15,8 @@ <description>Skeleton of an API project</description> <properties> <java.version>17</java.version> + <lombok.version>1.18.20</lombok.version> + <springdoc.version>2.2.0</springdoc.version> </properties> <dependencies> <dependency> @@ -36,6 +38,17 @@ <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <version>${lombok.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.springdoc</groupId> + <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> + <version>${springdoc.version}</version> + </dependency> </dependencies> <build> diff --git a/back-skeleton/src/main/java/com/takima/backskeleton/DAO/MajorDao.java b/back-skeleton/src/main/java/com/takima/backskeleton/DAO/MajorDao.java new file mode 100644 index 0000000000000000000000000000000000000000..9d54218305a010bef4efee75b5d85f827ef78b29 --- /dev/null +++ b/back-skeleton/src/main/java/com/takima/backskeleton/DAO/MajorDao.java @@ -0,0 +1,15 @@ +package com.takima.backskeleton.DAO; + +import com.takima.backskeleton.models.Major; +import com.takima.backskeleton.models.Student; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface MajorDao extends JpaRepository<Major, Long> { + @Query("SELECT m.students FROM Major m WHERE m.id= :majorId") + List<Student> getAllStudentsFromMajor(Long majorId); +} diff --git a/back-skeleton/src/main/java/com/takima/backskeleton/DAO/StudentDao.java b/back-skeleton/src/main/java/com/takima/backskeleton/DAO/StudentDao.java new file mode 100644 index 0000000000000000000000000000000000000000..3b12b1eedb6ddad993baec07dcc574e0c8932b13 --- /dev/null +++ b/back-skeleton/src/main/java/com/takima/backskeleton/DAO/StudentDao.java @@ -0,0 +1,14 @@ +package com.takima.backskeleton.DAO; + +import com.takima.backskeleton.models.Student; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface StudentDao extends JpaRepository<Student, Long> { + @Query("SELECT s FROM Student s JOIN s.courses c WHERE c.id= :courseId AND s.major.id = :majorId ") + List<Student> findByMajorIdAndCourseId(int majorId, int courseId); +} diff --git a/back-skeleton/src/main/java/com/takima/backskeleton/DTO/StudentDto.java b/back-skeleton/src/main/java/com/takima/backskeleton/DTO/StudentDto.java new file mode 100644 index 0000000000000000000000000000000000000000..f92a77828934868723bc4a490c0d8938260006c9 --- /dev/null +++ b/back-skeleton/src/main/java/com/takima/backskeleton/DTO/StudentDto.java @@ -0,0 +1,21 @@ +package com.takima.backskeleton.DTO; + +import com.takima.backskeleton.models.Course; +import com.takima.backskeleton.models.Major; +import com.takima.backskeleton.models.Student; +import lombok.Builder; +import lombok.Getter; +import org.springframework.web.multipart.MultipartFile; + +import java.time.Instant; +import java.util.List; +@Builder +@Getter +public class StudentDto { + private String firstName; + private String lastName; + private Instant birthdate; + private List<Course> courses; + private Major major; + private MultipartFile image; +} diff --git a/back-skeleton/src/main/java/com/takima/backskeleton/DTO/StudentMapper.java b/back-skeleton/src/main/java/com/takima/backskeleton/DTO/StudentMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..f2f8aab8bbdbe4cb3fc66a2e61fc225785ad0cd6 --- /dev/null +++ b/back-skeleton/src/main/java/com/takima/backskeleton/DTO/StudentMapper.java @@ -0,0 +1,29 @@ +package com.takima.backskeleton.DTO; + +import com.takima.backskeleton.models.Student; + +import java.io.IOException; + +public class StudentMapper { + public static Student fromDto(StudentDto dto, Long id) throws IOException { + return new Student.Builder() + .id(id) + .firstName(dto.getFirstName()) + .lastName(dto.getLastName()) + .birthdate(dto.getBirthdate()) + .courses(dto.getCourses()) + .major(dto.getMajor()) + .image(dto.getImage().isEmpty() ? dto.getImage().getBytes() : null) + .build(); + } + + public static StudentDto toDto (Student student){ + return StudentDto.builder() + .firstName(student.getFirstName()) + .lastName(student.getLastName()) + .birthdate(student.getBirthdate()) + .courses(student.getCourses()) + .major(student.getMajor()) + .build(); + } +} diff --git a/back-skeleton/src/main/java/com/takima/backskeleton/controllers/MajorController.java b/back-skeleton/src/main/java/com/takima/backskeleton/controllers/MajorController.java new file mode 100644 index 0000000000000000000000000000000000000000..b5315436e961bf04170d34178c6838011e7e669d --- /dev/null +++ b/back-skeleton/src/main/java/com/takima/backskeleton/controllers/MajorController.java @@ -0,0 +1,27 @@ +package com.takima.backskeleton.controllers; + +import com.takima.backskeleton.models.Major; +import com.takima.backskeleton.models.Student; +import com.takima.backskeleton.services.MajorService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@CrossOrigin +@RequestMapping("majors") +@RestController +@RequiredArgsConstructor +public class MajorController { + private final MajorService majorService; + + @GetMapping("") + public List<Major> findAll() { + return majorService.findAll(); + } + + @GetMapping("/{id}/students") + public List<Student> getStudentsOfMajor(@PathVariable Long id) { + return majorService.getStudentsOfMajor(id); + } +} diff --git a/back-skeleton/src/main/java/com/takima/backskeleton/controllers/StudentController.java b/back-skeleton/src/main/java/com/takima/backskeleton/controllers/StudentController.java new file mode 100644 index 0000000000000000000000000000000000000000..91fac9fce148445704a630ac8a0dafa851e3ded6 --- /dev/null +++ b/back-skeleton/src/main/java/com/takima/backskeleton/controllers/StudentController.java @@ -0,0 +1,39 @@ +package com.takima.backskeleton.controllers; + +import com.takima.backskeleton.DTO.StudentDto; +import com.takima.backskeleton.models.Student; +import com.takima.backskeleton.services.StudentService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@CrossOrigin +@RequestMapping("students") +@RestController +@RequiredArgsConstructor +public class StudentController { + private final StudentService studentService; + @GetMapping("") + public List<Student> listStudents(@RequestParam(required = false) Integer majorId, @RequestParam(required = false) Integer courseId) { + if (majorId != null && courseId !=null) { + return studentService.searchByMajorAndCourse(majorId, courseId); + } + return studentService.findAll(); + } + + @DeleteMapping("/{id}") + public void deleteStudent(@PathVariable Long id) { + studentService.deleteById(id); + } + + @PostMapping("") + public void addStudent(@RequestBody StudentDto studentDto) { + studentService.addStudent(studentDto); + } + + @PostMapping("/{id}") + public void updateStudent(@RequestBody StudentDto studentDto, @PathVariable Long id) { + studentService.updateStudent(studentDto, id); + } +} diff --git a/back-skeleton/src/main/java/com/takima/backskeleton/models/Course.java b/back-skeleton/src/main/java/com/takima/backskeleton/models/Course.java new file mode 100644 index 0000000000000000000000000000000000000000..bf8cd46b1fa43c7fe8e85422032affb74d252b8e --- /dev/null +++ b/back-skeleton/src/main/java/com/takima/backskeleton/models/Course.java @@ -0,0 +1,23 @@ +package com.takima.backskeleton.models; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Entity +@Table(name = "courses") +@NoArgsConstructor +@Getter +public class Course { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String name; + private Integer hours; + @ManyToMany(mappedBy = "courses") + @JsonIgnore + List<Student> students; +} diff --git a/back-skeleton/src/main/java/com/takima/backskeleton/models/Major.java b/back-skeleton/src/main/java/com/takima/backskeleton/models/Major.java new file mode 100644 index 0000000000000000000000000000000000000000..4746c4c0c82ccde04c18d5ff016b360056a11438 --- /dev/null +++ b/back-skeleton/src/main/java/com/takima/backskeleton/models/Major.java @@ -0,0 +1,25 @@ +package com.takima.backskeleton.models; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Entity +@Table(name = "majors") +@Getter +@NoArgsConstructor +public class Major { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String name; + private String description; + @OneToMany(mappedBy = "major") + @JsonIgnore + private List<Student> students; + +} + diff --git a/back-skeleton/src/main/java/com/takima/backskeleton/models/Student.java b/back-skeleton/src/main/java/com/takima/backskeleton/models/Student.java new file mode 100644 index 0000000000000000000000000000000000000000..894e4ec00a7ec6e93d63d42ab3c526f5725c9a5c --- /dev/null +++ b/back-skeleton/src/main/java/com/takima/backskeleton/models/Student.java @@ -0,0 +1,88 @@ +package com.takima.backskeleton.models; + +import jakarta.persistence.*; +import lombok.Getter; + +import java.time.Instant; +import java.util.List; + +@Entity +@Table(name = "students") +@Getter +public class Student { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + @Column(name = "first_name") + private String firstName; + @Column(name = "last_name") + private String lastName; + private Instant birthdate; + @ManyToMany + @JoinTable( + name = "student_course", + joinColumns = @JoinColumn(name = "student_id"), + inverseJoinColumns = @JoinColumn(name = "course_id")) + private List<Course> courses; + @ManyToOne() + @JoinColumn(name = "major_id") + private Major major; + @Column(name = "image") + private byte[] image; + + private Student(Builder builder) { + this.id = builder.id; + this.firstName = builder.firstName; + this.lastName = builder.lastName; + this.birthdate = builder.birthdate; + this.courses = builder.courses; + this.major = builder.major; + this.image = builder.image; + } + public Student() { + } + + public static class Builder { + private Long id; + private String firstName; + private String lastName; + private Instant birthdate; + private List<Course> courses; + private Major major; + private byte[] image; + + public Builder id (Long id) { + this.id = id; + return this; + } + + public Builder firstName(String firstName) { + this.firstName = firstName; + return this; + } + public Builder lastName(String lastName) { + this.lastName = lastName; + return this; + } + public Builder courses(List<Course> courses) { + this.courses = courses; + return this; + } + public Builder major(Major major) { + this.major = major; + return this; + } + public Builder birthdate(Instant birthdate) { + this.birthdate = birthdate; + return this; + } + public Builder image(byte[] image) { + this.image = image; + return this; + } + + public Student build() { + return new Student(this); + } + } +} diff --git a/back-skeleton/src/main/java/com/takima/backskeleton/services/MajorService.java b/back-skeleton/src/main/java/com/takima/backskeleton/services/MajorService.java new file mode 100644 index 0000000000000000000000000000000000000000..03feb0f83a1796d353faf3d891e4afcd2da83f5d --- /dev/null +++ b/back-skeleton/src/main/java/com/takima/backskeleton/services/MajorService.java @@ -0,0 +1,26 @@ +package com.takima.backskeleton.services; + +import com.takima.backskeleton.DAO.MajorDao; +import com.takima.backskeleton.models.Major; +import com.takima.backskeleton.models.Student; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +@RequiredArgsConstructor +public class MajorService { + private final MajorDao majorDao; + public List<Major> findAll() { + Iterable<Major> it = majorDao.findAll(); + List <Major> majors = new ArrayList<>(); + it.forEach(majors::add); + return majors; + } + + public List<Student> getStudentsOfMajor(Long id) { + return majorDao.getAllStudentsFromMajor(id); + } +} diff --git a/back-skeleton/src/main/java/com/takima/backskeleton/services/StudentService.java b/back-skeleton/src/main/java/com/takima/backskeleton/services/StudentService.java new file mode 100644 index 0000000000000000000000000000000000000000..21cb0d1fe765562d8fd54a7bbd22889634fe3e8c --- /dev/null +++ b/back-skeleton/src/main/java/com/takima/backskeleton/services/StudentService.java @@ -0,0 +1,56 @@ +package com.takima.backskeleton.services; + +import com.takima.backskeleton.DAO.StudentDao; +import com.takima.backskeleton.DTO.StudentDto; +import com.takima.backskeleton.DTO.StudentMapper; +import com.takima.backskeleton.models.Student; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.NoSuchElementException; + +@Component +@RequiredArgsConstructor +public class StudentService { + private final StudentDao studentDao; + + public List<Student> findAll() { + Iterable<Student> it = studentDao.findAll(); + List <Student> users = new ArrayList<>(); + it.forEach(users::add); + return users ; + } + + public void deleteById(Long id) { + studentDao.deleteById(id); + } + + public void addStudent(StudentDto studentDto) { + Student student; + try { + student = StudentMapper.fromDto(studentDto, null); + } catch (IOException e) { + throw new RuntimeException("Error with Student image", e); + } + studentDao.save(student); + } + + public void updateStudent(StudentDto studentDto, Long id) { + studentDao.findById(id) + .orElseThrow(() -> new NoSuchElementException("Student doesn't exist")); + Student student; + try { + student = StudentMapper.fromDto(studentDto, id); + } catch (IOException e) { + throw new RuntimeException("Error with Student image", e); + } + studentDao.save(student); + } + + public List<Student> searchByMajorAndCourse(int majorId, int courseId) { + return studentDao.findByMajorIdAndCourseId(majorId, courseId); + } +}