일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- jsp
- 건담
- html
- メソッド
- 単語
- Flutter
- C로 시작하는 컴퓨터 프로그래밍4판
- 일본어
- CSS
- Python
- 비즈니스일본어
- 一日一つメソッド
- rails
- javascript
- 디지몬
- 연습문제
- nico
- 반다이몰
- Web
- 인프런
- 건담베이스
- 자바
- 日本語
- rails7
- Spring
- ruby
- java
- springboot
- vscode
- DART
- Today
- Total
AR삽질러
SpringBoot_Gradle_Mysql_JPA - listAPI만들기(1) 본문
혼자서만 배우고 작업해봤지 협업은 처음이여서 API를 만드는데 애를 먹었다...Class명 DB명만 다르지 게시판이랑 똑같으니 보시는분들 참고하시고 도움이 되었으면 좋겠습니다!
RESTful API개발?
Representational State Transfer(표현 상태 전이) 웹서비스를 구현하는 아키텍처 스타일 중 하나로 RESTful API개발은 REST 아키텍처 스타일을 따라 설계된 API를 구현하는것을 의미한다.
1. Stateless
- Client가 Server에 요청을 보낼때 요청에 필요한 모든 정보를 함께 보내게 되는데 서버는 각 요청에 대한 Context를 유지하거나 관리할 필요없이 상태 유지 문제를 해결할 수 있다.
2. Uniform Interface
- URL(Uniform Resource Identifier)로 리소스를 구분한다. HTTP Method(GET, POST, PUT, DELETE)를 이용해서 리소스에 대한 작업을 수행하고 요청과 응답메시지는 일관된 형식으로 구성한다.
3. Cacheable
- 캐시기능을 이용해 응답시간을 단축시키는것이 가능하다.
4. Self-Descriptiveness
- 요청과 응답의 내용을 이해할 수 있도록 자체적으로 설명할 수 있는 메시지를 제공해야한다.
5. Client-Server구조
- Server는 리소스 제공자의 역할만 수행, Client는 리소스 소비자의 역할만 수행
- Servier - Client구조는 서로간의 의존성을 줄여 확장성과 유연성을 갖게 해준다.
1. 개발환경
OS : Window11
IDE : Intellij
FrameWork : SpringBoot
빌드도구 : Gradle : 2.7
Mysql : 8
JPA
2. bulid.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.11'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
group =
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'junit:junit:4.13.1'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
implementation 'mysql:mysql-connector-java:8.0.33'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
3. Controller
@RestController
@RequestMapping("/api/lectures")
public class LectureController {
private final LectureService lectureService;
public LectureController(LectureService lectureService) {
this.lectureService = lectureService;
}
// GET /api/lectures
@GetMapping
public ResponseEntity<List<LectureDto>> getAllLectures() {
List<LectureDto> lectureList = lectureService.getAllLectures();
return ResponseEntity.ok(lectureList);
}
@RestController
- REST API요청을 처리한다.
- @RestController 어노테이션이 붙은 클래스 내부에서는 웹 요청 경로와 요청방식(HTTP method)에 따라 메서드를 정의한다.
@RequestMapping("/api/lectures")
- api/lectures는 /api/lectures경로로 들어오는 요청을 이 클래스가 처리한다는 것을 의미한다.
LectureController class
- LectureService인스턴스를 매개변수로 받아 lectureSerice필드에 저장하여 LectureController내부에서 LectureService의 메서드를 호출할 수 있다.
Instance(인스턴스) : class기반으로 생성된 object(객체)를 의미 = 특정 클래스의 속성과 메서드를 사용할 때 필요하며 객체를 생성하고 인스턴스로 만들어 객체의 속성들을 읽어 오거나 Method를 호출할 수 있다.
Parameter(매개변수) : Method호출시 전달되는 값 = 객체를 생성할 때 해당 매개변수를 전달해 줄 수 있고 객체 내부에서 해당 값을 사용할 수 있다.
Method(메소드 = 메서드) : Class내부에 있는 Function과 같은 기능으로 특정한 기능을 수행한다.
@GetMapping
- HTTP GET요청을 처리하는 것을 나타내는 어노테이션으로 /api/lectures 경로로 GET요청이 들어오면 getAllLectures()메서드가 호출된다.
ReseponseEntity<List<LectureDto>>
-반환할 데이터 : List<LectureDto> 타입을 나타낸다. = ResponseEntity는 응답 코드와 응답바디를 함께 전달하는데 사용되는 객체로 ok()메서드를 호출해 ResponseEntity객체를 생성하고 응답코드 200(OK)로 설정한다.
getAllLectures()
- LectureService의 getAllLectures()메서드를 호출하여 모든 강의 정보를 List<LectureDto>형태로 가져와서 반환한다.
4. Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Setter
@Entity
@Table(name = "lecture1")
public class LectureEntity extends TimeEntity {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
//@Column(name = "lecture_id")
private Long lecture_id;
@Column(name = "author", nullable = false)
private String author;
@Column(name = "max_participants", nullable = false)
private Integer max_participants;
@Column(name = "category")
private String category;
@Column(name = "bank_name")
private String bank_name;
@Column(name = "account_name")
private String account_name;
@Column(name = "account_number")
private String account_number;
@Column(name = "price")
private Integer price;
@Column(name = "title")
private String title;
@Column(name = "content", columnDefinition = "TEXT")
private String content;
@Column(name = "start_date", columnDefinition = "datetime")
private LocalDateTime start_date;
@Column(name = "end_date", columnDefinition = "datetime")
private LocalDateTime end_date;
@Column(name = "region")
private String region;
@Column(name = "image_url")
private String image_url;
@Column(name = "created_date", columnDefinition = "datetime DEFAULT CURRENT_TIMESTAMP", nullable = false)
@CreatedDate
private LocalDateTime created_date;
@Builder
public LectureEntity(Long lecture_id, String author, Integer max_participants, String category,
String bank_name, String account_name, String account_number, Integer price, String title, String content,
LocalDateTime start_date, LocalDateTime end_date, String region, String image_url,
LocalDateTime created_date) {
this.lecture_id = lecture_id;
this.author = author;
this.max_participants = max_participants;
this.category = category;
this.bank_name = bank_name;
this.account_name = account_name;
this.account_number = account_number;
this.price = price;
this.title = title;
this.content = content;
this.start_date = start_date;
this.end_date = end_date;
this.region = region;
this.image_url = image_url;
this.created_date = created_date;
}
}
JPA(Java Peristence API)를 이용해 DataBase와 연동하기 위핸 Entity클래스이다.
@NoArgsConstructor(access = AccessLevel.PROTECTED)
- 인자가 없는 생성자를 생성해 해당 생성자는 protected 접근제한자가 되어있다.
@Getter / @Setter
- 클래스내 모든 필드에 대한 Getter/Setter 메서드를 생성한다.
@Entity
- JPA의 엔티티를 나타낸다.
@Table(name = "lecture")
- 해당 엔티티가 매핑될 테이블명을 지정한다.
@Id
- Primary Key를 나타낸다.
@GeneratedValue(strategy = GenerationType.IDENTITY)
- Primary Key의 생성규칙
@Column(name = "author", nullable = false)
- 필드에 매핑되는 컬럼 정보를 지정한다. = author컬럼 이름을 가지며 Not Null옵션이 설정되어 있다.
@Column(name = "content", columnDefinition = "TEXT")
- columnDefinition을 이용하여 데이터 타입 및 길이 등을 설정할 수 있다.
@CreatedDate
- create날자를 관리하기 위한 어노테이션이다.
public LectureEntity(Long lecture_id..........
- 빌드메서드 배열 생성자로 @Builder어노테이션을 이용하여 생성자의 인자를 관리한다.
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class TimeEntity {
@CreatedDate
private LocalDateTime created_date;
@LastModifiedDate
private LocalDateTime updated_date;
}
JPA에서 제공하는 Auduting기능을 사용하기 위한 추상클래스이다.
@MappedSuperclass
- 이 클래스를 상송하는 하위 클래스에서 매핑 정보를 상속받도록 지정한다.
@EntityListeners(AuditingEntityListener.class)
- 이 엔티티에서 이벤트를 처리하기 위한 리스너를 지정한다.AuditingEntityListener.class를 지정하여 엔티티 저장시간을 자동으로 기록한다.
public abstract class TimeEntity
- 클래스는 추상 클래스로 이 클래스를 상속받는 클래스에서 createDate, modifiedDate를 사용하기 위한 추상 메서드를 정의한다.
5. Dto
@Getter
@Setter
@ToString
@NoArgsConstructor
public class LectureDto {
private Long lecture_id;
private String author;
private Integer max_participants;
private String category;
private String bank_name;
private String account_name;
private String account_number;
private Integer price;
private String title;
private String content;
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm")
private LocalDateTime start_date;
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm")
private LocalDateTime end_date;
private String region;
private String image_url;
private LocalDateTime created_date;
public LectureEntity toEntity() {
LectureEntity lectureEntity = LectureEntity.builder()
.lecture_id(lecture_id)
.author(author)
.max_participants(max_participants)
.category(category)
.bank_name(bank_name)
.account_name(account_name)
.account_number(account_number)
.price(price)
.title(title)
.content(content)
.start_date(start_date)
.end_date(end_date)
.region(region)
.image_url(image_url)
.created_date(created_date)
.build();
return lectureEntity;
}
@Builder
public LectureDto(Long lecture_id, String author, Integer max_participants, String category,
String bank_name, String account_name, String account_number, Integer price, String title, String content,
LocalDateTime start_date, LocalDateTime end_date, String region, String image_url,
LocalDateTime created_date) {
this.lecture_id = lecture_id;
this.author = author;
this.max_participants = max_participants;
this.category = category;
this.bank_name = bank_name;
this.account_name = account_name;
this.account_number = account_number;
this.price = price;
this.title = title;
this.content = content;
this.start_date = start_date;
this.end_date = end_date;
this.region = region;
this.image_url = image_url;
this.created_date = created_date;
}
}
DTO(Data Transfer Object)클래스로 Entity와 View에서 사용되는 다양한 모델간의 데이터를 변환하는 역할을 수행
@ToString
- 클래스의 toString()메서드를 생성한다.
@NoArgsConstructor
- 인자가 없는 생성자를 생성하는 어노테이션
LectureEntity toEntity()
- LectureDto에서 LectureEntity로 변환하는 메소드로 Bulider패턴을 사용하는 생성자이다.
@DateTimeFormat(patter - "yyyy-MM-dd'T'HH:mm")
- 문자열 형태로 받은 날짜를 LocalDateTime객체로 바꾸어준다.
6. Repository
public interface LectureRepository extends JpaRepository<LectureEntity, Long> {
List<LectureEntity> findByTitleContaining(String title);
}
Spring Data JPA에서 제공하는 JpaResponsitory인터페이스를 상속하여 LectureEntity객체를 다루는 인터페이스이다.
- extends JpaRepository<LectureEntity, Long> : JpaReposotory인터페이스를 상속해 Spring Data JPA에서 제공하는 CRUD기능을 제공하는 인터페이스이다. 이 기능을 통해 우리는 직접 구현할 필요하없다 :D
7. Service
@Service
public class LectureService {
private final LectureRepository lectureRepository;
public LectureService(LectureRepository lectureRepository) {
this.lectureRepository = lectureRepository;
}
public List<LectureDto> getAllLectures() {
List<LectureEntity> lectureEntities = lectureRepository.findAll();
return lectureEntities.stream()
.map(this::convertToDto)
.collect(Collectors.toList());
}
LectureEntity를 LectureDto로 변환하고 객체들을 List로 반환하는 서비스 클래스
@Service
- 클래스가 비즈니스 로직을 처리하는 Service클래스로 명시한다.
private final LectureRepository lectureRepository
- LectureRepository 객체를 주입받는다.
public LectureService(LectureRepository lectureRepository)
- LectureService생성자로 DI(Dependency Injection)을 주입받는다.
public List<LectureDto> getAlllecture()
- 모든 lectureEntity를 찾아 stream()메소드로 stream객체를 생성하고 map()으로 개별 Entity를 DTO로 변환후 collect()로 리스트를 리턴한다.
List<LectureEntity> lectureEntities = lectureRepository.findAll();
- LectureEntity를 모두 찾는다.
- List<LectureEntity>에서 Stream<LectureEntity>로 객체를 변환 후 map()을 사용해 convertToDto()메소드로 개별 객체(Entity)를 DTO로 변환후 Stream객체를 다시 리스트로 변환하여 반환한다.
---------------------------------
다음시간에는 postman VS Junit5 차이점과 postman사용법을 게시하겠습니다!
'JAVA > SpringBoot' 카테고리의 다른 글
SpringBoot_Gradle_Mysql_JPA_API테스트_postman과JUnit5차이(2) (0) | 2023.05.22 |
---|---|
SpringBoot - 회원관리기초(2) (0) | 2023.03.20 |
SpringBoot-회원관리기초(1) (0) | 2023.03.20 |