mirror of
https://github.com/spring-projects/spring-petclinic.git
synced 2025-04-25 20:02:47 +00:00
feat: implement course creation API
This commit is contained in:
parent
2aa53f929d
commit
d12b51ce2e
8 changed files with 160 additions and 0 deletions
|
@ -35,6 +35,7 @@ dependencies {
|
||||||
// Workaround for AOT issue (https://github.com/spring-projects/spring-framework/pull/33949) -->
|
// Workaround for AOT issue (https://github.com/spring-projects/spring-framework/pull/33949) -->
|
||||||
implementation 'io.projectreactor:reactor-core'
|
implementation 'io.projectreactor:reactor-core'
|
||||||
|
|
||||||
|
compileOnly 'org.projectlombok:lombok'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-cache'
|
implementation 'org.springframework.boot:spring-boot-starter-cache'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
||||||
|
@ -58,6 +59,8 @@ dependencies {
|
||||||
testImplementation 'org.testcontainers:mysql'
|
testImplementation 'org.testcontainers:mysql'
|
||||||
checkstyle "io.spring.javaformat:spring-javaformat-checkstyle:${springJavaformatCheckstyleVersion}"
|
checkstyle "io.spring.javaformat:spring-javaformat-checkstyle:${springJavaformatCheckstyleVersion}"
|
||||||
checkstyle "com.puppycrawl.tools:checkstyle:${checkstyleVersion}"
|
checkstyle "com.puppycrawl.tools:checkstyle:${checkstyleVersion}"
|
||||||
|
|
||||||
|
annotationProcessor 'org.projectlombok:lombok'
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named('test') {
|
tasks.named('test') {
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package org.springframework.samples.petclinic.course;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.EnumType;
|
||||||
|
import jakarta.persistence.Enumerated;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.samples.petclinic.model.BaseEntity;
|
||||||
|
import org.springframework.samples.petclinic.vet.Vet;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Entity
|
||||||
|
@Table(name = "courses")
|
||||||
|
public class Course extends BaseEntity {
|
||||||
|
private String name;
|
||||||
|
private String description;
|
||||||
|
// 예: 초급, 중급, 고급
|
||||||
|
private String difficulty;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "vet_id")
|
||||||
|
private Vet instructor;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package org.springframework.samples.petclinic.course;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.samples.petclinic.course.dto.CreateCourseRequest;
|
||||||
|
import org.springframework.samples.petclinic.vet.Vet;
|
||||||
|
import org.springframework.samples.petclinic.vet.VetRepository;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RequestMapping("/courses")
|
||||||
|
public class CourseController {
|
||||||
|
private final CourseService courseService;
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping()
|
||||||
|
public ResponseEntity<Integer> createCourse(@RequestBody CreateCourseRequest request) {
|
||||||
|
System.out.println(request);
|
||||||
|
|
||||||
|
Course course = courseService.createCourse(request.getName(), request.getDescription(), request.getDescription(), request.getVetId());
|
||||||
|
|
||||||
|
return ResponseEntity.ok(course.getId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package org.springframework.samples.petclinic.course;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface CourseRepository extends JpaRepository<Course, Integer> {
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package org.springframework.samples.petclinic.course;
|
||||||
|
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.samples.petclinic.vet.Vet;
|
||||||
|
import org.springframework.samples.petclinic.vet.VetRepository;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class CourseService {
|
||||||
|
private final CourseRepository courseRepository;
|
||||||
|
private final VetRepository vetRepository;
|
||||||
|
|
||||||
|
|
||||||
|
@Transactional()
|
||||||
|
public Course createCourse(String name, String description, String difficulty, Integer vetId) {
|
||||||
|
Collection<Vet> all = vetRepository.findAll();
|
||||||
|
|
||||||
|
all.forEach(course -> {
|
||||||
|
System.out.println(course.getId());
|
||||||
|
});
|
||||||
|
|
||||||
|
Vet instructor = vetRepository.findById(vetId)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Vet not found"));
|
||||||
|
|
||||||
|
Course course = new Course();
|
||||||
|
course.setName(name);
|
||||||
|
course.setDescription(description);
|
||||||
|
course.setDifficulty(difficulty);
|
||||||
|
course.setInstructor(instructor);
|
||||||
|
courseRepository.save(course);
|
||||||
|
|
||||||
|
return course;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package org.springframework.samples.petclinic.course.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter()
|
||||||
|
public class CreateCourseRequest {
|
||||||
|
private String name;
|
||||||
|
private String description;
|
||||||
|
private String difficulty;
|
||||||
|
private Integer vetId;
|
||||||
|
|
||||||
|
public CreateCourseRequest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateCourseRequest(String name, String description, String difficulty, Integer vetId) {
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
this.difficulty = difficulty;
|
||||||
|
this.vetId = vetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CreateCourseRequest{" +
|
||||||
|
"name='" + name + '\'' +
|
||||||
|
", description='" + description + '\'' +
|
||||||
|
", difficulty='" + difficulty + '\'' +
|
||||||
|
", vetId=" + vetId +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ import org.springframework.data.repository.Repository;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repository class for <code>Vet</code> domain objects All method names are compliant
|
* Repository class for <code>Vet</code> domain objects All method names are compliant
|
||||||
|
@ -37,6 +38,13 @@ import java.util.Collection;
|
||||||
*/
|
*/
|
||||||
public interface VetRepository extends Repository<Vet, Integer> {
|
public interface VetRepository extends Repository<Vet, Integer> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a <code>Vet</code> from the data store.
|
||||||
|
* @return a <code>Optional</code> of <code>Vet</code>
|
||||||
|
*/
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
Optional<Vet> findById(Integer id) throws DataAccessException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve all <code>Vet</code>s from the data store.
|
* Retrieve all <code>Vet</code>s from the data store.
|
||||||
* @return a <code>Collection</code> of <code>Vet</code>s
|
* @return a <code>Collection</code> of <code>Vet</code>s
|
||||||
|
|
|
@ -62,3 +62,13 @@ CREATE TABLE visits (
|
||||||
);
|
);
|
||||||
ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets (id);
|
ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets (id);
|
||||||
CREATE INDEX visits_pet_id ON visits (pet_id);
|
CREATE INDEX visits_pet_id ON visits (pet_id);
|
||||||
|
|
||||||
|
CREATE TABLE courses (
|
||||||
|
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||||
|
name VARCHAR(255),
|
||||||
|
description VARCHAR(1000),
|
||||||
|
difficulty VARCHAR(255),
|
||||||
|
vet_id INTEGER
|
||||||
|
);
|
||||||
|
CREATE INDEX courses_vet_id ON courses (vet_id);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue