Spring(기초)-2주차
1. RDBMS(RDB)
RDBMS
- 관계형 데이터베이스 (정보 저장소)
- 컴퓨터에 정보를 저장하고 관리하는 기술
- 매우 고도화된 엑셀
- SQL: 데이터 읽고, 저장, 변경, 삭제하는 구체적인 문법
RDBMS의 종류
- H2
- In-memory DB, 인메모리 DB란 서버가 작동하는 동안에만 내용을 저장하고, 서버가 작동을 멈추면 데이터가 모두 삭제되는 데이터베이스
- 연습용
- MySQL
- 스프링과 궁합이 좋음, 많은 회사에서 사용
- 서비스 배포용
- Oracle
- PostgreSQL
H2 웹콘솔 띄워보기
- src > main > resources > application.properties > 설정 복사
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb
- Run
- http://localhost:8080/h2-console 접속
- Connect 버튼 클릭
- 오류 발생시, JDBC URL에 아래를 붙여넣기
jdbc:h2:mem:testdb
- 테이블 생성 / 데이터 삽입 / 데이터 조회
2. JPA
JPA란?
- SQL을 쓰지 않고 데이터를 생성, 조회, 수정, 삭제할 수 있도록 해주는 번역기 (자바로 DB를 사용하도록 도와주는 녀석)
- 자바로 코드 작성하면 SQL 번역뿐만 아니라 기본적인 기능 거의 있음
- 테이블: Domain, SQL: Repository
JPA가 없다면?
- 자바 짜다가 갑자기 SQL 짜고, 그걸 잘 맞추어 넣어야함 (복잡)
JPA가 있다면?
- 설정은 아래 한 줄이면 끝
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
- 명령도 그냥 자바로 만들면 됨
JPA 시작하기
- src > main > java > com.주소명.프로젝트명에 domain 이라는 패키지 생성
- 클래스(Course.java), 인터페이스(CourseRepository.java) 파일 생성
- 클래스(Course.java)
- Id는 getter를 따로 쓰지 않음
- Setter가 없는 이유는 repository 에서 자동으로 설정해주기 때문임
@NoArgsConstructor // 기본생성자를 대신 생성해줍니다.
@Entity // 테이블임을 나타냅니다.
public class Course {
@Id // ID 값, Primary Key로 사용하겠다는 뜻입니다.
@GeneratedValue(strategy = GenerationType.AUTO) // 자동 증가 명령입니다.
private Long id;
@Column(nullable = false) // 컬럼 값이고 반드시 값이 존재해야 함을 나타냅니다.
private String title;
@Column(nullable = false)
private String tutor;
public String getTitle() {
return this.title;
}
public String getTutor() {
return this.tutor;
}
public Course(String title, String tutor) {
this.title = title;
this.tutor = tutor;
}
}
/* 같은 개념
CREATE TABLE IF NOT EXISTS courses (
id bigint(5) NOT NULL AUTO_INCREMENT,
title varchar(255) NOT NULL,
tutor varchar(255) NOT NULL,
PRIMARY KEY (id)
);
*/
- 인터페이스(CourseRepository.java)
- extends 뒤에 있는 기능을 가져와서 쓴다는 의미
- class Course의 id 자료형이 Long이다
- 인터페이스: JPA는 Repository를 통해서만 사용할 수 있음 (클래스에서 멤버가 빠진, 메소드 모음집)
public interface CourseRepository extends JpaRepository<Course, Long> {
}
JPA 사용해보기
- SQL이 보이도록 application.properties를 세팅해야한다 (resources폴더 안에 있음)
spring.jpa.show-sql=true
- application의 메인 메소드에 아래의 코드를 붙여넣는다
// Week02Application.java 의 main 함수 아래에 붙여주세요.
@Bean
public CommandLineRunner demo(CourseRepository repository) {
return (args) -> {
};
}
@Bean
public CommandLineRunner demo(CourseRepository repository) {
return (args) -> {
Course course1 = new Course("웹 개발의 봄 Spring", "남병관");
repository.save(course1);
List<Course> courseList = repository.findAll();
for (int i=0; i<courseList.size(); i++) {
Course c = courseList.get(i);
System.out.println(c.getTitle());
System.out.println(c.getTutor());
}
};
}
생성일자, 수정일자
- extends: 클래스의 상속개념 (이미 만들어둔 것 가져다가 쓰자)
- DB 기본 중의 기본은 "생성일자"와 "수정일자"를 필드로 가지는 것
- domain 에서 Timestaped 클래스를 생성
package com.sparta.week02.domain;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;
@MappedSuperclass // 상속했을 때, 컬럼으로 인식하게 합니다.
@EntityListeners(AuditingEntityListener.class) // 생성/수정 시간을 자동으로 반영하도록 설정
public abstract class Timestamped {
@CreatedDate // 생성일자임을 나타냅니다.
private LocalDateTime createdAt;
@LastModifiedDate // 마지막 수정일자임을 나타냅니다.
private LocalDateTime modifiedAt;
}
- LocalDateTime: 시간을 나타내는 자바의 자료형 중 하나
- 어노테이션 (@~~): 스프링한테 어떤 역할인지 알려주는 것
- Auditing: 수정해서 자료형에 자동으로 반영을 해주는 것
- abstract: 직접 구현 불가능, 상속으로만 사용해라 -> Course에서 상속을 해준다 (Course extends Timestamped)
class Course extends Timestamped {
- 마지막에 Application에 @EnableJpaAuditing을 붙여줘야함 (그래야 작동됨)
@EnableJpaAuditing
@SpringBootApplication
public class Week02Application {
- In-memory DB, 인메모리 DB란 서버가 작동하는 동안에만 내용을 저장하고, 서버가 작동을 멈추면 데이터가 모두 삭제되는 데이터베이스
- 연습용
- 스프링과 궁합이 좋음, 많은 회사에서 사용
- 서비스 배포용
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb
jdbc:h2:mem:testdb
JPA란?
- SQL을 쓰지 않고 데이터를 생성, 조회, 수정, 삭제할 수 있도록 해주는 번역기 (자바로 DB를 사용하도록 도와주는 녀석)
- 자바로 코드 작성하면 SQL 번역뿐만 아니라 기본적인 기능 거의 있음
- 테이블: Domain, SQL: Repository
JPA가 없다면?
- 자바 짜다가 갑자기 SQL 짜고, 그걸 잘 맞추어 넣어야함 (복잡)
JPA가 있다면?
- 설정은 아래 한 줄이면 끝
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
- 명령도 그냥 자바로 만들면 됨
JPA 시작하기
- src > main > java > com.주소명.프로젝트명에 domain 이라는 패키지 생성
- 클래스(Course.java), 인터페이스(CourseRepository.java) 파일 생성
- 클래스(Course.java)
- Id는 getter를 따로 쓰지 않음
- Setter가 없는 이유는 repository 에서 자동으로 설정해주기 때문임
@NoArgsConstructor // 기본생성자를 대신 생성해줍니다.
@Entity // 테이블임을 나타냅니다.
public class Course {
@Id // ID 값, Primary Key로 사용하겠다는 뜻입니다.
@GeneratedValue(strategy = GenerationType.AUTO) // 자동 증가 명령입니다.
private Long id;
@Column(nullable = false) // 컬럼 값이고 반드시 값이 존재해야 함을 나타냅니다.
private String title;
@Column(nullable = false)
private String tutor;
public String getTitle() {
return this.title;
}
public String getTutor() {
return this.tutor;
}
public Course(String title, String tutor) {
this.title = title;
this.tutor = tutor;
}
}
/* 같은 개념
CREATE TABLE IF NOT EXISTS courses (
id bigint(5) NOT NULL AUTO_INCREMENT,
title varchar(255) NOT NULL,
tutor varchar(255) NOT NULL,
PRIMARY KEY (id)
);
*/
- 인터페이스(CourseRepository.java)
- extends 뒤에 있는 기능을 가져와서 쓴다는 의미
- class Course의 id 자료형이 Long이다
- 인터페이스: JPA는 Repository를 통해서만 사용할 수 있음 (클래스에서 멤버가 빠진, 메소드 모음집)
public interface CourseRepository extends JpaRepository<Course, Long> {
}
JPA 사용해보기
- SQL이 보이도록 application.properties를 세팅해야한다 (resources폴더 안에 있음)
spring.jpa.show-sql=true
- application의 메인 메소드에 아래의 코드를 붙여넣는다
// Week02Application.java 의 main 함수 아래에 붙여주세요.
@Bean
public CommandLineRunner demo(CourseRepository repository) {
return (args) -> {
};
}
@Bean
public CommandLineRunner demo(CourseRepository repository) {
return (args) -> {
Course course1 = new Course("웹 개발의 봄 Spring", "남병관");
repository.save(course1);
List<Course> courseList = repository.findAll();
for (int i=0; i<courseList.size(); i++) {
Course c = courseList.get(i);
System.out.println(c.getTitle());
System.out.println(c.getTutor());
}
};
}
생성일자, 수정일자
- extends: 클래스의 상속개념 (이미 만들어둔 것 가져다가 쓰자)
- DB 기본 중의 기본은 "생성일자"와 "수정일자"를 필드로 가지는 것
- domain 에서 Timestaped 클래스를 생성
package com.sparta.week02.domain;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;
@MappedSuperclass // 상속했을 때, 컬럼으로 인식하게 합니다.
@EntityListeners(AuditingEntityListener.class) // 생성/수정 시간을 자동으로 반영하도록 설정
public abstract class Timestamped {
@CreatedDate // 생성일자임을 나타냅니다.
private LocalDateTime createdAt;
@LastModifiedDate // 마지막 수정일자임을 나타냅니다.
private LocalDateTime modifiedAt;
}
- LocalDateTime: 시간을 나타내는 자바의 자료형 중 하나
- 어노테이션 (@~~): 스프링한테 어떤 역할인지 알려주는 것
- Auditing: 수정해서 자료형에 자동으로 반영을 해주는 것
- abstract: 직접 구현 불가능, 상속으로만 사용해라 -> Course에서 상속을 해준다 (Course extends Timestamped)
class Course extends Timestamped {
- 마지막에 Application에 @EnableJpaAuditing을 붙여줘야함 (그래야 작동됨)
@EnableJpaAuditing
@SpringBootApplication
public class Week02Application {
CRUD
→ 생성 (Create)
→ 조회 (Read)
→ 변경 (Update)
→ 삭제 (Delete)
- 데이터 저장하기 (Create) & 조회하기 (Read)
- Repository의 save와 findAll 등을 이용
// 데이터 저장하기
repository.save(new Course("프론트엔드의 꽃, 리액트", "임민영"));
// 데이터 전부 조회하기
List<Course> courseList = repository.findAll();
for (int i=0; i<courseList.size(); i++) {
Course course = courseList.get(i);
System.out.println(course.getId());
System.out.println(course.getTitle());
System.out.println(course.getTutor());
}
// 데이터 하나 조회하기
Course course = repository.findById(1L).orElseThrow(
() -> new IllegalArgumentException("해당 아이디가 존재하지 않습니다.")
);
- 스프링의 구조
- Controller : 가장 바깥 부분, 요청/응답을 처리함
- Service : 중간 부분, 실제 중요한 작동이 많이 일어나는 부분
- Repo : 가장 안쪽 부분, DB와 맞닿아 있음 (Repository, Entity)
Service 만들기
- Course 클래스에 update 메소드 추가
public void update(Course course) {
this.title = course.title;
this.tutor = course.tutor;
}
- src > main > java > com.주소명.프로젝트명 > service 패키지 생성
- 클래스(CourseService.java) 만들기
@Service // 스프링에게 이 클래스는 서비스임을 명시
public class CourseService {
// final: 서비스에게 꼭 필요한 녀석임을 명시
private final CourseRepository courseRepository;
// 생성자를 통해, Service 클래스를 만들 때 꼭 Repository를 넣어주도록
// 스프링에게 알려줌
public CourseService(CourseRepository courseRepository) {
this.courseRepository = courseRepository;
}
@Transactional // SQL 쿼리가 일어나야 함을 스프링에게 알려줌
public Long update(Long id, Course course) {
Course course1 = courseRepository.findById(id).orElseThrow(
() -> new IllegalArgumentException("해당 아이디가 존재하지 않습니다.")
);
course1.update(course);
return course1.getId();
}
}
- update 실행해보기
@Bean
public CommandLineRunner demo(CourseRepository courseRepository, CourseService courseService) {
return (args) -> {
courseRepository.save(new Course("프론트엔드의 꽃, 리액트", "임민영"));
System.out.println("데이터 인쇄");
List<Course> courseList = courseRepository.findAll();
for (int i=0; i<courseList.size(); i++) {
Course course = courseList.get(i);
System.out.println(course.getId());
System.out.println(course.getTitle());
System.out.println(course.getTutor());
}
Course new_course = new Course("웹개발의 봄, Spring", "임민영");
courseService.update(1L, new_course);
courseList = courseRepository.findAll();
for (int i=0; i<courseList.size(); i++) {
Course course = courseList.get(i);
System.out.println(course.getId());
System.out.println(course.getTitle());
System.out.println(course.getTutor());
}
};
}
- 데이터 삭제하기 (Delete)
@Bean
public CommandLineRunner demo(CourseRepository courseRepository, CourseService courseService) {
return (args) -> {
courseRepository.save(new Course("프론트엔드의 꽃, 리액트", "임민영"));
System.out.println("데이터 인쇄");
List<Course> courseList = courseRepository.findAll();
for (int i=0; i<courseList.size(); i++) {
Course course = courseList.get(i);
System.out.println(course.getId());
System.out.println(course.getTitle());
System.out.println(course.getTutor());
}
Course new_course = new Course("웹개발의 봄, Spring", "임민영");
courseService.update(1L, new_course);
courseList = courseRepository.findAll();
for (int i=0; i<courseList.size(); i++) {
Course course = courseList.get(i);
System.out.println(course.getId());
System.out.println(course.getTitle());
System.out.println(course.getTutor());
}
courseRepository.deleteAll();
};
}
3. Lombok / DTO
Lombok
- 자바 프로젝트를 진행하는데 거의 필수적으로 필요한 메소드/생성자 등을 자동생성
- 코드 절약할 수 있도록 도와주는 라이브러리
- 환경설정
- command + ,
- 검색: Annotation Processors
- Enable 체크 후 OK
- Shift 두 번 누르고 plugins 입력 후 엔터
- lombok 입력 후 아이콘 우측 Install
- Course.java
- Course 클래스 Getter, NoArgsConstructor 적용
- CourseService.java
- CourseService 클래스 RequiredArgsConstructor 적용
Author And Source
이 문제에 관하여(Spring(기초)-2주차), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@kju190920/Spring-2주차1-RDBMS
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
- command + ,
- 검색: Annotation Processors
- Enable 체크 후 OK
- Shift 두 번 누르고 plugins 입력 후 엔터
- lombok 입력 후 아이콘 우측 Install
- Course 클래스 Getter, NoArgsConstructor 적용
- CourseService 클래스 RequiredArgsConstructor 적용
Author And Source
이 문제에 관하여(Spring(기초)-2주차), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@kju190920/Spring-2주차1-RDBMS저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)