위에 태그에 TIL을 제외하고는 오늘 배운 것들로 채워넣으면, 나중에 편할 것 같다고 생각해서 이렇게 해 놓으려고 한다.
어제 심화반 줌에서 물어본 질문인데
튜터님의 무기
DB (정형 데이터 : 엑셀 -> MySQL)
(비정형 데이터 : 시계열 데이터 -> NoSQL)
-> >>그런 매커니즘을 말로 표현할 수 있었고, 실험을 많이 해봐서 사람들이 모르는 셋팅을 잘했음<<
Spring을 극도로
Web CS를 극도로
코테를 극도로
다양한 걸 만들어 본 사람
등등이 자기의 "무기"이다
무기를 만들자..
DB 연결하는방법
- build.gradle 에 MySQL 추가
깃허브 subtree 쓰면 파일들이 다 합쳐지는건 좋지만 커밋이 하나로 합쳐진다
-> 브랜치를 다 따로 파서 올리면?
https://santokki.tistory.com/24
이분 블로그 따라했음!
3 Layer Architecture
역할 분리하기
Controller의 비즈니스 로직들을 Service를 만들어서 분리하는것,
Repository 기능 또한 Service에서 분리
변환, 전달, 확인 등의 과정만 남기고, 하위 기능들은 모두 Service -> Repository 순으로 분리
거름망? 원심분리기 같은?
공용 메서드 (findById 같은) 들은 맨 아래로 모음 -> 가독성 굿
-> 약간 내가 취약한 부분!!
IoC(제어의 역전), DI(의존성 주입)
김볶밥 맛있게 만드는 방법 = 설계 원칙
김볶밥 레시피 = 디자인 패턴
의존성 : 말 그대로 의존성
다리와 목발, 치킨과 소비자 같은 관계
ex)
소비자 클래스에서 Chicken chicken = new Chicken(); 하면
치킨만 먹을수 있는데, 다른 거 먹으려면 계속 수정해야 한다.
이런 강한 의존성을 느슨하게 하기 위해선
자바의 interface를 활용해서 Food 인터페이스 객체를 만들면 느슨해짐!
public class Consumer {
void eat(Food food) {
food.eat();
}
public static void main(String[] args) {
Consumer consumer = new Consumer();
consumer.eat(new Chicken());
consumer.eat(new Pizza());
}
}
interface Food {
void eat();
}
class Chicken implements Food{
@Override
public void eat() {
System.out.println("치킨을 먹는다.");
}
}
class Pizza implements Food{
@Override
public void eat() {
System.out.println("피자를 먹는다.");
}
}
consumer.eat(new Chicken()); <--- 바로 객체를 넣는 이 부분, 다형성의 원리!!
public class Consumer {
Food food;
public Consumer(Food food) {
this.food = food;
}
void eat() {
this.food.eat();
}
public static void main(String[] args) {
Consumer consumer = new Consumer(new Chicken());
consumer.eat();
consumer = new Consumer(new Pizza());
consumer.eat();
}
}
interface Food {
void eat();
}
class Chicken implements Food{
@Override
public void eat() {
System.out.println("치킨을 먹는다.");
}
}
class Pizza implements Food{
@Override
public void eat() {
System.out.println("피자를 먹는다.");
}
}
메모장 프로젝트의 IoC & DI
(전)
문제점 해결하려면? 미리 만들어진 걸 전달!
1. 각 객체에 대한 생성은 1번
2. 생성된 객체를 재사용
3. 생성자 주입을 통해 필요로 하는곳에 전달!
= 제어의 흐름 : MemoController <- MemoService <- MemoRepository
제어의 역전!
(후)
IoC Container와 Bean
DI를 하기 위해선 객체 생성이 먼저
Spring이 해주고 있다
Bean : Spring이 관리하는 객체
Container : Bean 컨테이너
-> 클래스를 Bean 객체로 등록해야 함 : @Component
메인에서 ComponentScan을 한다
생성자가 1개면 생략이 되지만, 여러개면 @Autowired 붙여야 한다
객체의 불변성을 지켜주기 위해 생성자로 주입을 하고 있었음(final 쓸려고)
메서드로 주입하려면 @Autowired 붙여야 함
필드로 주입하는방법도 @Autowired 붙여야 함. private도 되지만, 불안정하므로 지양
Lombok으로 할 수 있음. @RequiredArgsConstructor
final을 생성자로 가져갑니다. 필드에 달아주면 됩니다
@Autowired 적용 조건
Spring에서 관리받는 Bean 클래스에서만 가능(당연)
수동 주입(x)
public MemoService(ApplicationContext context) {
// 1. 'Bean' 이름으로 가져오기 ( 난 안됌)
MemoRepository memoRepository = (MemoRepository)context.getBean("memoRepository");
this.memoRepository = memoRepository;
// 2. 'Bean' 클래스 형식으로 가져오기
MemoRepository memoRepository = context.getBean(MemoRepository.class);
this.memoRepository = memoRepository;
}
JPA
ORM : 객체와 DB를 매핑. SQL 작업을 줄여주기 위해 등장
JPA : Java ORM 표준 기술
JPA는 hibernate 를 씀
hibernate : SQL 자동 생성!
Entity
JPA에 의해서 관리되고 있는 Class. 객체(여기선 Java에서 만듬)
persistence.xml 에서 hibernate를 사용하고 있다
ID를 AutoIncrease 하고 싶다면? Memo - @Id 아래 @GeneratedValue(strategy = GenerationType.IDENTITY) 추가
영속성 컨텍스트
영속성 : Persistance, 영속성,지속성
Entity 객체를 효율적으로 쉽게 관리하기 위해 만들어진 공간
EntityManager : 영속성 컨텍스트에 접근하여 Entity 객체들을 조작하기 위함
개발자들은 EntityManager를 통해 Entity를 조작 가능
EntityManager는 EntityManagerFactory를 통해 생성
EntityManagerFactory : 만들기 위해서는 DB에 대한 정보를 전달해야 함
META-INF - persistence.xml 파일을 만들어 정보를 넣어두면 된다 (Persistence.createEntity),(
ex)
// setUp 부분
EntityManagerFactory emf;
EntityManager em;
@BeforeEach
void setUp() {
emf = Persistence.createEntityManagerFactory("memo");
em = emf.createEntityManager();
}
Transaction
약간 Git같은 느낌? 마지막에 COMMIT 하지 않으면 반영이 되지 않는다!
JPA의 트랜잭션
! Entity에서 Setter를 사용할 때 주의 !
영속성 컨텍스트들 안에서 PK로 Entity를 식별(identify)한다
쿼리 중 values (? ? ?) 했던것.. jdbcTemplete 이였지
EntityManager에서 EntityTransaction을 가져올 수 있다
et.begin()을 통해 트랜잭션 시작 / et.commit()을 통해 커밋 / et.close()로 종료까지
영속성 컨텍스트의 기능
1차 캐시 : 우리가 저장하는 Entity 객체들이 1차 캐시, 즉 1차 저장소에 저장된다
em.persist(객체) : 1차 캐시에 저장
캐시 저장소는 Map 자료구조 형태로 되어있다
key = Id, value = 해당 Entity 클래스의 객체
데이터베이스 조회 횟수를 줄인다.
em.find 할 때 마다 계속 select하는게 아니라, 1차 캐시에 중복이 있으니 그걸 사용하는 시스템?
객체 동일성 보장!
원래 객체 2개 생성해서 같다고 하면 틀리다
but
1차 캐시에 있는걸 받아온것이기 때문에 같다고 뜸!