효습
스터디 2주차 본문
회원 관리 예제 - 웹 MVC 개발
- [
localhost](http://localhost) 8080
요청이 오면 먼저controller
에서 찾음 → 맵핑된 게 있으면 이controller
호출되고 끝나는거, 그래서 기존에 만들었던index.html
은 무시- controller 가 정적파일보다 우선순위가 높음
- 기본적으로 url 창에 치는 건
@GetMapping
, 조회할 때 주로 사용 @PostMapping
은 보통 data를 form 같은데다가 넣어서 전달할 때 사용
public class MemberForm {
//private이라 막 접근을 못
private String name;
public String getName() {
return name;
}
// 그래서 저장할 이름이 setName을 통해서 들어가게
public void setName(String name) {
this.name = name;
}
}
- html 파일에서
${members}
는 모델 안에 값을 꺼내는 거임 - 단축키 : ctrl + E 는 최근에 봤던 파일
스프링 DB 접근 기술
- JDBC URL : jdbc:h2:tcp://localhost/~/test
- 파일에 직접 접근하는게 아니라 소켓을 통해서 접근함
- 이렇게 해야 여러 곳에서 접근할 수 있음
generated by default as identity
- DB가 null 값 , 값을 세팅하지 않고 insert 하면 자동으로 값을 채워줌
- spring에서는 id가 Long이었는데 sql에서는 bigint
- 스프링을 왜 쓰냐? 객체지향적인 설계가 좋다고 하는 이유는 ,,,,
- 다형성을 활용(인터페이스를 두고 구현체를 바꿔끼우기를 할 수 있음)
- 스프링 편리하게 되도록 스프링 컨테이너가 이걸 지원을 해줌
- DI(dependency injection) 덕분에
- 기존의 코드는 하나도 손대지 않고 오직 applicatopn을 설정하는 코드, 이 코드만 손대면 나머지 실제 application에 관련된 코드는 하나도 손댈게 없음
- 개방-폐쇄 원칙(OCP, Open-Closed Principle)
- 확장에는 열려있고 수정, 변경에는 닫혀있음
- 객체지향에서 다형성이라는 개념을 잘 활용을 하면 이렇게 기능을 완전히 변경을 해도 애플리케이션 전체를 수정할 필요가 없음 물론 조립하는 코드는 변경을 해야하지만 애플리케이션이 동작하는데 필요한 코드들은 수정할 필요가 없는거
- 스프링의 DI (Dependencies Injection)을 사용하면 기존 코드를 전혀 손대지 않고, 설정만으로 구현 클래스를 변경할 수 있다.
- 회원을 등록하고 DB에 결과가 잘 입력되는지 확인하자.
- 데이터를 DB에 저장하므로 스프링 서버를 다시 실행해도 데이터가 안전하게 저장된다.
스프링 통합 테스트
@Transactional
이라는 어노테이션을 테스트에다가 달면 테스트를 실행할 때 테스트를 먼저 실행하고 DB에 데이터를 insert 쿼리하고 다 넣은 다음에 테스트가 끝나면 rollback을 해줌 →DB에 넣었던 데이터가 반영이 안되고 다 지워짐 (테스트에 붙었을 때만 이렇게 실행됨)@SpringBootTest
: 스프링 컨테이너와 테스트를 함께 실행한다.- 순수한 단위테스트가 훨씬 더 좋은 테스트일 확률이 더 높음
JDBC 템플릿
- 생성자가 하나만 있으면 , 스프링 빈으로 등록이 되면
@Autowired
생략할 수 있음
//스프링이 자동으로 datasource injection 해줌
@Autowired
public JdbcTemplateMemberRepository(DataSource datasource) {
jdbcTemplate = new JdbcTemplate(datasource);
}
jpa
- JPA는 기존의 반복 코드는 물론이고, 기본적인 SQL도 JPA가 직접 만들어서 실행해준다.
- JPA를 사용하면, SQL과 데이터 중심의 설계에서 객체 중심의 설계로 패러다임을 전환을 할 수 있다.
- JPA를 사용하면 개발 생산성을 크게 높일 수 있다
- jpa는 회원 객체를 보고 테이블도 다 만들수 있음 - 근데 이미 만들어져있기 때문에 자동으로 만들어지는 건 끄자
spring.jpa.hibernate.ddl-auto=create
//위와 같으면 테이블도 자동으로 생성해
- jpa는 인터페이스만 제공이 되는거임 , 객체랑 ORM(Object Relational Mapping)이라는 기술
@Entity
는 jpa가 관리하는 엔티티라는 의미임- DB에 값을 넣으면 DB가 ID를 자동으로 생성해주는 것을 IDENTITY 전략이라고 함
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;//시스템이 저장하는 아이디
- 만약 DB에서 Column명이 username이면 다음과 같이 한다
@Column(name ="username")
private String name;
이 어노테이션을 가지고 데이터베이스와 매핑을 하는 거
- jpa는 엔티티매니저라는 걸로 모든 걸 동작함
- jpa 라이브러리를 받으면 스프링 부트가 엔티티 매니저라는 것을 생성해줌
- 현재 데이터 베이스랑 다 연결해가지고 만들어주고 만들어진 걸 injection 받으면 됨
findByName
같은 경우에는 JPQL이라는 객체지향쿼리를 써야함, 거의 sql이랑 똑같은데 좀 다르다.
@Override
public Optional<Member> findByName(String name) {
List<Member> result = em.createQuery("select m from Member m where m.name=name",Member.class)
.setParameter("name",name)
.getResultList();
return result.stream().findAny();
}
- Refector this 단축키: ctrl+alt+shift+t
- 저장,조회할 때 sql 짤 필요 없음 , 다 자동으로 되는데 pk 기반이 아닌 나머지는 JPQL을 작성해줘야함
- jpa기술을 스프링에 감싸서 제공하는 스프링 데이터 jpa가 있음 → 그럼 jpql을 안짜도 됨
- 주의할 점
- 항상 transaction이라는 게 있어야 함 → service 계층에
@Transactional
- 데이터를 저장하거나 변경할 때 항상 transaction이 있어야함
- 항상 transaction이라는 게 있어야 함 → service 계층에
스프링 데이터 JPA
- 스프링 데이터 JPA는 JPA를 편리하게 사용하도록 도와주는 기술
- 인터페이스가 인터페이스를 받을 때에는
extends
- 인터페이스만 만들어놓으면 스프링 데이터 jpa가 인터페이스에 대한 구현체를 만들어냄 → 스프링 빈에 등록을 해놓음 그래서 injection을 받을 수 있음
- SpringDataJpaMemberRepository
package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface SpringDataJpaMemberRepository extends JpaRepository<Member,Long> ,MemberRepository {
@Override
Optional<Member> findByName(String name);
}
- SpringConfig
package hello.hellospring;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig {
private final MemberRepository memberRepository;
@Autowired
public SpringConfig(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Bean
public MemberService memberService(){
return new MemberService(memberRepository);
}
}
- 스프링 데이터 jpa가
SpringDataJpaMemberRepository
를 보고 스프링 빈을 자동으로 만들어서 프록시라는 기술을 가지고 객체를 생성해서 스프링 빈으로 올림
- 스프링 데이터 JPA 제공 기능
- 인터페이스를 통한 기본적인 CRUD
- findByName() , findByEmail() 처럼 메서드 이름 만으로 조회 기능 제공
- 페이징 기능 자동 제공
- 복잡한 동적 쿼리는 Querydsl이라는 라이브러리를 사용
AOP
AOP가 필요한 상황
- 모든 메서드의 호출 시간을 측정하고 싶다면?
- 공통 관심 사항(cross-cutting concern) vs 핵심 관심 사항(core concern)
- 회원 가입 시간, 회원 조회 시간을 측정하고 싶다면?
문제
- 회원가입, 회원 조회에 시간을 측정하는 기능은 핵심 관심 사항이 아니다.
- 시간을 측정하는 로직은 공통 관심 사항이다.
- 시간을 측정하는 로직과 핵심 비즈니스의 로직이 섞여서 유지보수가 어렵다.
- 시간을 측정하는 로직을 별도의 공통 로직으로 만들기 매우 어렵다.
- 시간을 측정하는 로직을 변경할 때 모든 로직을 찾아가면서 변경해야 한다
AOP : Aspect Oriented Programming
- 공통 관심 사항(cross-cutting concern) vs 핵심 관심 사항(core concern) 분리
- Inline Variable : ctrl+alt+n
해결
- 회원가입, 회원 조회등 핵심 관심사항과 시간을 측정하는 공통 관심 사항을 분리한다.
- 시간을 측정하는 로직을 별도의 공통 로직으로 만들었다.
- 핵심 관심 사항을 깔끔하게 유지할 수 있다.
- 변경이 필요하면 이 로직만 변경하면 된다.
- 원하는 적용 대상을 선택할 수 있다
- 프록시라고 하는 가짜 스프링 빈을 만들어냄
- 가짜 스프링 빈이 끝나면 joinPoint.proceed() 해서 진짜를 호출
'스터디 > Spring' 카테고리의 다른 글
스프링컨테이너와 스프링 빈 (0) | 2023.06.25 |
---|---|
스프링 핵심 원리 이해2 - 객체 지향 원리 적용 (0) | 2023.06.21 |
스프링 핵심 원리 이해1 - 예제 만들기 (0) | 2023.05.03 |
객체 지향 설계와 스프링 (0) | 2023.05.03 |
스터디 1주차 (0) | 2023.04.05 |