์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
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 |
- reflection
- fontstyle
- ์ฝ๋์
- Python
- menutab
- IOC
- OpenAPI
- ์ฑ์ฉํ์ ํ
- ๊ฐ์ฒด์งํฅํ๋ก๊ทธ๋๋ฐ
- udp
- uri
- 2024-08-21
- di
- tcp
- Factory Method Pattern
- 2024-08-20
- ๊ธฐ์ด100์
- swagger
- ํ๋ IT&E
- Dialog
- datepicker
- FACTORY
- URN
- http method
- Kotlin
- AndroidStudio
- ์ด๋ ธํ ์ด์
- Android Studio
- url
- OOP
dingdong coding
์ด๋ ธํ ์ด์ ์ ๋ฆฌ @ ๋ณธ๋ฌธ
์ด๋ ธํ ์ด์ ์ด๋?
• @ ์ฌ์ธ ํ๋๋ก ๋ง์ ์ปจํ ์คํธ๋ค์ ์ ๊ณต ๋ฐ์ ์ ์๊ฒ ํ๋ค.
• @ ์ฌ์ธ์ผ๋ก ์์ํ๋ ๊ฒ์ ์ด๋ ธํ ์ด์ ์ด๋ผ๊ณ ํ๋ค.
Spring์ผ๋ก ๊ฐ๋ฐํ ๋ ์ด๋ ธํ ์ด์ ์์ด ๊ฐ๋ฐํ๋ ๊ฒ์ ๊ฑฐ์ ๋ณผ ์ ์๋ค. Controller ๋ฑ๋ก์ด๋ Service, Repository, Test ๋ฑ ์์ฐ์ด๋ ๊ณณ์ด ์์ ์ ๋๋ค.
๋ง์ด ์ฐ์์๋ ๊ฐ๋ฐํ๋ค๊ฐ ๊ฐ๋ ์๊ฐ์ด ์๋๊ฑฐ๋ ๊น๋จน์ ๋๊ฐ ์๊ธฐ์ ์ง๊ธ์ด๋ผ๋ ์กฐ๊ธ์ฉ ์ ๋ฆฌํ ์๊ฐ์ด๋ค.
ํฌ์คํธ์ ์ฒ๋ผ ๊ณ์ ์ถ๊ฐํ ์์ โ๏ธ
@AfterEach
: ๊ฐ ํ ์คํธ๊ฐ ์ข ๋ฃ๋ ๋๋ง๋ค ์คํ
1) Test Case๋ฅผ ์์ฑํ๋ ๊ฒฝ์ฐ : ๋ฉ๋ชจ๋ฆฌ DB์ ๋จ์์๋ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ๋ค. (์ง์ ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํด์ค)
clearStore ๋ฉ์๋
public void clearStore(){
store.clear();
}
test case์ ์ถ๊ฐ
@AfterEach
public void afterEach(){
repository.clearStore();
}
@BeforeEach
: ๊ฐ ํ ์คํธ ์คํ ์ ์ ํธ์ถ
1) ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ , ์์กด๊ด๊ณ๋ ์๋ก ๋งบ์ด์ค
@BeforeEach
public void beforeEach(){
memberRepository = new MemoryMemberRepository();
memberService = new MemberService(memberRepository);
}
@AfterEach, @BeforeEach ๋ชจ๋ ํ ์คํธ์ผ์ด์ค ์์ฑ ์ ๋ฐ์๊ฐ๋ฅํ ์ค๋ฅ๋ฅผ ์ต์ํ์ํค๊ธฐ ์ํด ์ฌ์ฉ
@ComponentScan
: @Component, @Service, @Repository, @Controller, @Configuration ๋ฑ๋ฑ ์ฐ๋ฆฌ๊ฐ ๋ฑ๋กํ๊ณ ์ถ๋ค๊ณ ์ค์ ํ ๋น๋ค์ ์ฐพ์์ ๋น์ผ๋ก ๋ง๋ค์ด์ฃผ๋ ๊ฒ
: ํด๋น @ComponentScan์ด ์์ฑ๋ ํจํค์ง ์ดํ์ ํด๋์ค๋ค์ ์ํํ๋ฉฐ ๋น์ผ๋ก ๋ฑ๋ก๋ ๊ฐ์ฒด๋ค์ ํ์ํ๋ค.
** ํ์ํ ํจํค์ง์ ์์์์น๋ฅผ ์ง์ ํ๋ ๋ฐฉ๋ฒ
** ๊ถ์ฅ์ฌํญ์ ์๋๋ค. ์ค์ ์ ๋ณด ํด๋์ค์ ์์น๋ฅผ ํ๋ก์ ํธ ์ต์๋จ์ ๋๋ ๊ฒ์ ๊ถ์ฅ
@ComponentScan(
basePackages = "hello.core", basePackageClasses = AutoAppConfig.class,
)
• basePackages : ํ์ํ ํจํค์ง์ ์์ ์์น๋ฅผ ์ง์ ํ๋ค. ์ด ํจํค์ง๋ฅผ ํฌํจํด์ ํ์ ํจํค์ง๋ฅผ ๋ชจ๋ ํ์
• basePackages = {"hello.core", "hello.service"} ์ฌ๋ฌ ์์น๋ฅผ ์ง์ ํ ์๋ ์๋ค.
• basePackageClasses : ์ง์ ํ ํด๋์ค์ ํจํค์ง๋ฅผ ํ์ ์์น๋ก ์ง์ ํ๋ค.
๋ง์ฝ ์ง์ ํ์ง ์์ผ๋ฉด @ComponentScan์ด ๋ถ์ ์ค์ ์ ๋ณด ํด๋์ค์ ํจํค์ง๊ฐ ์์ ์์น๊ฐ ๋๋ค.
** @ComponentScan์ผ๋ก ๋ฑ๋กํ๋ ๋น์ ๊ธฐ๋ณธ์ด๋ฆ์ ํด๋์ค ๋ช ์ ์ฌ์ฉํ๋ ๋งจ ์๊ธ์๋ง ์๋ฌธ์๋ฅผ ์ฌ์ฉํ๋ค **
• ๋น ์ด๋ฆ ๊ธฐ๋ณธ ์ ๋ต : MemberServiceImpl ํด๋์ค => memberServiceImpl
• ๋น ์ด๋ฆ ์ง์ ์ง์ : ๋ง์ฝ ์คํ๋ง ๋น์ ์ด๋ฆ์ ์ง์ ์ง์ ํ๊ณ ์ถ๋ค๋ฉด @Component("memberService2") ์ด๋ฐ์์ผ๋ก ์ด๋ฆ์ ๋ถ์ฌํ๋ฉด ๋๋ค.
** filter ์ต์ **
• includeFilters : ์ปดํฌ๋ํธ ์ค์บ ๋์์ ์ถ๊ฐ๋ก ์ง์
• ์ถ๊ฐํ ํด๋์ค๋ @MyIncludeComponent๋ก ์ง์ ํด ์คํ๋ง ๋น์ ๋ฑ๋ก๋๋ค.
• excludeFilters : ์ปดํฌ๋ํธ ์ค์บ์์ ์ ์ธํ ๋์์ ์ง์
• ์ ์ธํ ํด๋์ค๋ @MyExcludeComponent๋ก ์ง์ ํด ์คํ๋ง ๋น์ ๋ฑ๋กํ์ง ์๋๋ค.
@Configuration
@ComponentScan(
includeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyIncludeComponent.class),
excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyExcludeComponent.class)
) static class ComponentFilterAppConfig {
}
** filter type ์ต์ **
• ANNOTATION : ๊ธฐ๋ณธ ๊ฐ, ์ ๋ ธํ ์ด์ ์ ์ธ์ํด ๋์
• ASSIGNABLE_TYPE : ์ง์ ํ ํ์ ๊ณผ ์์ ํ์ ์ ์ธ์ํด์ ๋์
• ASPECTJ : AspectJ ํจํด ์ฌ์ฉ
• REGEX : ์ ๊ท ํํ์
• CUSTOM : TypeFilter ์ด๋ผ๋ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด ์ฒ๋ฆฌ
@Configuration
: ์คํ๋ง ์ค์ ์ ๋ณด์์ ์ฌ์ฉ. ์คํ๋ง ์ค์ ์ ๋ณด๋ก ์ธ์ํ๊ณ , ์คํ๋ง ๋น์ด ์ฑ๊ธํค์ ์ ์งํ๋๋ก ์ถ๊ฐ์ฒ๋ฆฌ๋ฅผ ํ๋ค.
@Autowired
: ๊ฐ ์ํฉ์ ํ์ ์ ๋ง๋ Ioc ์ปจํ ์ด๋ ์์ ์กด์ฌํ๋ Bean์ ์๋์ผ๋ก ์ฃผ์ ํด ์ค๋ค. ( DI ์์กด์ฑ ์ฃผ์ )
: ์์ฑ์์ ์ง์ ํ๋ฉด, ์คํ๋ง ์ปจํ ์ด๋๊ฐ ์๋์ผ๋ก ํด๋น ์คํ๋ง ๋น์ ์ฐพ์์ ์ฃผ์ ํ๊ณ , ์์ฑ์์์ ์ฌ๋ฌ ์์กด๊ด๊ณ๋ ํ๋ฒ์ ์ฃผ์ ๋ฐ์ ์ ์๋ค.
: 'getBean(MemberRepository.class)'์ ๋์ผํ๋ค๊ณ ์ดํดํ๋ฉด ๋จ
: @Autowired์ ๊ธฐ๋ณธ๋์์ ์ฃผ์ ํ ๋์์ด ์์ผ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค. ์ฃผ์ ํ ๋์์ด ์์ด๋ ๋์ํ๊ฒ ํ๋ ค๋ฉด
@Autowired( required = false )๋ก ์ง์ ํ๋ฉด ๋๋ค.
@Autowired(required = false)
public void setNoBean1(Member noBean1){ // Member๋ ๋น์ผ๋ก ๋ฑ๋ก๋์ง ์์์
System.out.println("noBean1 = " +noBean1);
}
** @Autowired( required = false ) ** ์ ๊ฐ์ด ์๋์ฃผ์ ๋์์ ์ต์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ
org.springframework.lang.@Nullable : ์๋ ์ฃผ์ ํ ๋์์ด ์์ผ๋ฉด null์ด ์ ๋ ฅ
Optional< > : ์๋ ์ฃผ์ ํ ๋์์ด ์์ผ๋ฉด Optional.empty ๊ฐ ์ ๋ ฅ
@Autowired
public void setNoBean2(@Nullable Member noBean2){
System.out.println("noBean1 = " +noBean2);
}
@Autowired
public void setNoBean3(Optional<Member> noBean3){
System.out.println("noBean1 = " +noBean3);
}
• @Autowired๋ ๋น์ ์๋์ผ๋ก ์ฃผ์ ํด์ฃผ๊ณ Type์ผ๋ก ์กฐํ( ac.getBean(DiscountPolicy.class)์ ์ ์ฌ )ํ๊ธฐ ๋๋ฌธ์ ํ์ ์กฐํ ์ ์ ํ๋ ๋น์ด 2๊ฐ ์ด์์ผ ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค. ( ์ฆ ์กฐํ ๋น์ด 2๊ฐ ์ด์์ผ ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ )
.NoUniqueBeanDefinitionException: No qualifying bean of type 'hello.core.discount.DiscountPolicy' available: expected single matching bean but found 2: fixDiscountPolicy,rateDiscountPolicy
ํด๊ฒฐ๋ฐฉ๋ฒ
1. @Autowired ํ๋ ๋ช ๋งค์นญ
: @Autowired๋ ํ์ ๋งค์นญ์ ์๋ํ๊ณ , ์ด ๋ ์ฌ๋ฌ ๋น์ด ์์ผ๋ฉด ํ๋ ์ด๋ฆ, ํ๋ผ๋ฏธํฐ ์ด๋ฆ์ผ๋ก ๋น ์ด๋ฆ์ ์ถ๊ฐ ๋งค์นญํ๋ค.
: ํ๋๋ช ์ ๋น ์ด๋ฆ์ผ๋ก ๋ณ๊ฒฝ
: ํ๋๋ช ๋งค์นญ์ ํ์ ๋งค์นญ์ ๋จผ์ ์๋ํ ํ์ ๊ทธ ๊ฒฐ๊ณผ ์ฌ๋ฌ ๋น์ด ์๋ ๊ฒฝ์ฐ ์ถ๊ฐ๋ก ๋์ํ๋ ๊ธฐ๋ฅ
2. @Qualifier @Qualifier๋ผ๋ฆฌ ๋งค์นญ ๋น ์ด๋ฆ ๋งค์นญ
3. @Primary ์ฌ์ฉ
@Qualifier
: ๋น ๋ฑ๋ก ์ ๋ช ์์ ์ผ๋ก ์ด๋ฆ์ ์ง์ ํ ์ ์๋ค.
: ์ถ๊ฐ ๊ตฌ๋ถ์๋ฅผ ๋ถ์ฌ์ฃผ์ด ๋น์ ๋งค์นญํ๋ ๋ฐฉ๋ฒ
: ๋น์ ์ฃผ์ ๋ฐ์ ๋ ๋ชจ๋ ์ฝ๋์ @Qualifier์ ๋ถ์ฌ์ฃผ์ด์ผ ํ๋ค.
: ๋งค์ฐ ์์ธํ๊ฒ ๋์ํ๋ค.
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {}
@Autowired
public OrderServiceImpl(MemberRepository memberRepository,
@Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
@Primary
: ์ฐ์ ์์๋ฅผ ์ ํ๋ ๋ฐฉ๋ฒ์ผ๋ก @Autowired ์ ์ฌ๋ฌ ๋น์ด ๋งค์นญ๋๋ฉด @Primary๋ก ์ง์ ๋ ๋น์ด ์ฐ์ ๊ถ์ ๊ฐ์ง๋ค.
: @Qualifier์ง์ ์์ด ํธ๋ฆฌํ๊ฒ ์กฐํ ๊ฐ๋ฅํ๋ค. ๊ธฐ๋ณธ ๊ฐ์ฒ๋ผ ๋์.
@RequiredArgsConstructor
: ์์ฑ์ ์ฃผ์ ์ Lombok ํ๋ฌ๊ทธ์ธ์ ํ์ฉํ์ฌ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ผ๋ก ์์ฑ์ ์ฃผ์ ์ ํ ์ ์๋ค.
: final or @NotNull์ด ๋ถ์ ํ๋์ ์์ฑ์๋ฅผ ์๋ ์์ฑํด์ฃผ๋ Lombok @
: ์์กด์ฑ ์ฃผ์ ์ ํธ์์ฑ์ ์ํด ์ฌ์ฉ๋๊ณค ํ๋ค.
@ResponseBody
: ์๋ฐ ๊ฐ์ฒด๋ฅผ HTTP ์์ฒญ์ body ๋ด์ฉ์ผ๋ก ์ง์ ๋งคํ
: viewResolver ์ฌ์ฉํ์ง ์์
: ๊ธฐ๋ณธ ๋ฌธ์ ์ฒ๋ฆฌ StringHttpMessageConverter
: ๊ธฐ๋ณธ ๊ฐ์ฒด ์ฒ๋ฆฌ : MappingJackson2HttpMessageConverter
: byte ์ฒ๋ฆฌ ๋ฑ ๊ธฐํ ์ฌ๋ฌ HttpMessageConverter๊ฐ ๊ธฐ๋ณธ ๋ฑ๋ก
@RequestBody
: @RequestBody์ ๋ถ์ ํ๋ผ๋ฏธํฐ๋ HTTP ์์ฒญ์ ๋ณธ๋ฌธ body๋ถ๋ถ์ด ์๋ฐ ๊ฐ์ฒด ๊ทธ๋๋ก ์ ๋ฌ
: json ํํ๋ก ๋ฐ์ HTTP Body ๋ฐ์ดํฐ๋ฅผ MessageConverter๋ฅผ ํตํด Java Object๋ก ๋ณํ์ํด
: ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ Body๊ฐ ์กด์ฌํ์ง ์๋ HTTP Get ๋ฉ์๋์ @RequestBody๋ฅผ ํ์ฉํ๋ฉด Error
: ๊ฐ์ ์ฃผ์ ํ์ง ์๊ณ ๋ณํ์ ์ํค๋ฏ๋ก ๋ณ์๋ค์ ์์ฑ์๋ Setter ํจ์๊ฐ ์์ด๋ ์ ์์ ์ผ๋ก ๊ฐ์ด ํ ๋น๋จ
@ModelAttribute
: ํด๋ผ๋ฆฌ์ธํธ๊ฐ ์ ์กํ๋ multipart/form-data ํํ์ HTTP Body ๋ด์ฉ๊ณผ HTTP ํ๋ผ๋ฏธํฐ์ ๊ฐ๋ค์ ์์ฑ์๋ Setter๋ฅผ ํตํด ์ฃผ์ ํ๊ธฐ ์ํด ์ฌ์ฉ๋จ
: @ModelAttribute์๋ ๋งคํ์ํค๋ ํ๋ผ๋ฏธํฐ์ ํ์ ์ด ๊ฐ์ฒด์ ํ์ ๊ณผ ์ผ์นํ๋์ง๋ฅผ ํฌํจํ ๋ค์ํ ๊ฒ์ฆ์์ ์ด ์ถ๊ฐ์ ์ผ๋ก ์งํ๋๋ค.
: ์ฌ์ฉ์๊ฐ ์์ฒญ ์ ์ ๋ฌํ๋ ๊ฐ์ ์ค๋ธ์ ํธ ํํ๋ก ๋งคํํด์ค๋ค.
: ๊ฐ์ฒด ๋งคํ
: Json์ด๋ XML๊ณผ ๊ฐ์ ํํ์ ๋ฐ์ดํฐ๋ฅผ MessageConverter๋ฅผ ํตํด ๋ณํ์ํค๋ @RequestBody์ ๋ฌ๋ฆฌ, @ModelAttribute๋ multipart/form-data ํํ์ HTTP Body์ HTTP ํ๋ผ๋ฏธํฐ๋ค์ ์์ฑ์๋ ์์ ์๋ก ์ฃผ์ ์ํจ๋ค๋ ์ฐจ์ด๊ฐ ์๋ค.
@RequestParam
@RequestParam( "๊ฐ์ ธ์ฌ ๋ฐ์ดํฐ ์ด๋ฆ" ) [ ๋ฐ์ดํฐ ํ์ ] [ ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ฅผ ๋ด์ ๋ณ์ ]
: 1๊ฐ์ HTTP ์์ฒญ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐ๊ธฐ ์ํด ์ฌ์ฉ
: @RequestParma์ ํ์ ์ฌ๋ถ๊ฐ True์ด๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฐ๋์ ํด๋น ํ๋ผ๋ฏธํฐ๊ฐ ์ ์ก๋์ด์ผ ํจ
: ํด๋น ํ๋ผ๋ฏธํฐ๊ฐ ์ ์ก๋์ง ์์ผ๋ฉด 404 Error
: ๋ฐ๋์ ํ์ํ ๋ณ์๊ฐ ์๋๋ผ๋ฉด required ๊ฐ์ false
@RequestMapping
: @RequestMapping ์ด๋ ธํ ์ด์ ์ Spring ์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ๊ฐ์ฅ ์์ฃผ ์ฌ์ฉ
: http request๋ก ๋ค์ด์ค๋ url ํน์ controller ํด๋์ค๋ ๋ฉ์๋๋ก ์ฐ๊ฒฐ์ํค๋ ์ญํ
: controller์ class์ ์ ์ฉํ ์ ์๊ณ ํน์ method์ ์ ์ฉ ๊ฐ๋ฅ
@Controller
: ์ ํต์ ์ธ Spring MVC์ ์ปจํธ๋กค๋ฌ, ์ฃผ๋ก View๋ฅผ ๋ฐํํ๊ธฐ ์ํด ์ฌ์ฉ.
: ํ๋ ์ ํ ์ด์ ๋ ์ด์ด, ์น ์์ฒญ๊ณผ ์๋ต์ ์ฒ๋ฆฌ
: ํธ๋ค๋ฌ๊ฐ ์ค์บํ ์ ์๋ ๋น(Bean) ๊ฐ์ฒด๊ฐ ๋์ด ์๋ธ๋ฆฟ์ฉ ์ปจํ ์ด๋์ ์์ฑ ( @Repository, @service ๋ ๋ง์ฐฌ๊ฐ์ง๋ก ํด๋น ํด๋์ค๋ฅผ ๋ฃจํธ ์ปจํ ์ด๋ Bean ๊ฐ์ฒด๋ก ์์ฑํด์ค๋ค. )
@Service
: ์คํ์ธ ๋น์ฆ๋์ค ๋ก์ง์์ ์ฌ์ฉ. ์๋น์ค ๋ ์ด์ด, ๋ด๋ถ์์ ์๋ฐ ๋ก์ง์ ์ฒ๋ฆฌํจ
: ํน๋ณํ ์ฒ๋ฆฌ๋ฅผ ํ๊ธฐ๋ณด๋ค๋ ๊ฐ๋ฐ์๋ค์ด ํต์ฌ ๋น์ฆ๋์ค ๊ณ์ธต์ ์ธ์ํ๋๋ฐ ๋์
@Repository
: ์คํ๋ง ๋ฐ์ดํฐ ์ ๊ทผ ๊ณ์ธต์์ ์ฌ์ฉ.
: ๋ฐ์ดํฐ ๊ณ์ธต์ ์์ธ๋ฅผ ์คํ๋ง ์์ธ๋ก ๋ณํ
: ์ธ๋ถ I/O ์ฒ๋ฆฌ, ํผ์์คํดํธ ๋ ์ด์ด, DB๋ ํ์ผ ๊ฐ์ ์ธ๋ถ I/O ์์ ์ ์ฒ๋ฆฌํจ
@GetMapping
: HTTP GET ์์ฒญ์ ํน์ ํธ๋ค๋ฌ ๋ฉ์๋์ ๋งคํ, ์ฃผ์์ ํ๋ผ๋ฏธํฐ๊ฐ ๋ ธ์ถ
: ๋ฉ์๋์๋ง ์ ์ฉ
@RestController
public class UserController {
@Autowired
UserService userService;
@GetMapping("users")
public ResponseEntity<List<User>> getAll() {
return new ResponseEntity<>(userService.getAll(), HttpStatus.OK);
}
@GetMapping("users/{id}")
public ResponseEntity<User> getById(@PathVariable long id) {
Optional<User> user = userService.getById(id);
if (user.isPresent()) {
return new ResponseEntity<>(user.get(), HttpStatus.OK);
} else {
throw new RecordNotFoundException();
}
}
}
@PathVariable
: ๊ฒฝ๋ก์ ํน์ ์์น ๊ฐ์ด ๊ณ ์ ๋์ง ์๊ณ ๋ฌ๋ผ์ง ๋ ์ฌ์ฉํ๋ค.
: URL๊ฒฝ๋ก์ ๋ณ์๋ฅผ ๋ฃ์ด์ฃผ๋ ๊ฒ
@PostMapping
: HTTP POST ์์ฒญ์ ์ฒ๋ฆฌํ๋ ํน์ํ๋ ์ฃผ์ ๋ฒ์ . ์ฃผ์์ฐฝ์ ํ๋ผ๋ฏธํฐ๊ฐ ๋ ธ์ถ๋์ง ์์
: @RequestMapping(method = RequestMethod.POST) ์ ๋จ์ถํค ์ญํ
@PostMapping(path = "users",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<User> create(@RequestBody User newUser) {
User user = userService.save(newUser);
if (user == null) {
throw new ServerException();
} else {
return new ResponseEntity<>(user, HttpStatus.CREATED);
}
}
@SpringBootTest
: ์คํ๋ง ์ปจํ ์ด๋์ ํ ์คํธ๋ฅผ ํจ๊ป ์คํํ๋ค.
@Transactional
: TestCase์ @Transactional์ด ์์ผ๋ฉด ํ ์คํธ ์์ ์ ์ ํธ๋์ญ์ ์ ์์, ์๋ฃ ํ์๋ ํญ์ RollBack
: ๋ค์ Test์ ์ํฅ์ ์ฃผ์ง ์๋๋ค.
๊ฐ์ฒด์ ํ ์ด๋ธ ๋งคํ @Entity, @Table
@Entity
: JPA ๋ฅผ ์ฌ์ฉํด์ ํ ์ด๋ธ๊ณผ ๋งคํํ ํด๋์ค๋ @Entity ํ์์
: @Entity๊ฐ ๋ถ์ ํด๋์ค๋ JPA๊ฐ ๊ด๋ฆฌํ๋ ๊ฒ์ผ๋ก, ์ํฐํฐ๋ผ๊ณ ๋ถ๋ฆผ
• ์์ฑ
- name : JPA์์ ์ฌ์ฉํ ์ํฐํฐ ์ด๋ฆ์ ์ง์ , ๋ณดํต ๊ธฐ๋ณธ ๊ฐ์ธ ํด๋์ค ์ด๋ฆ์ ์ฌ์ฉ
• ์ฃผ์์ฌํญ
- ๊ธฐ๋ณธ ์์ฑ์๋ ํ์ ( JPA๊ฐ ์ํฐํฐ ๊ฐ์ฒด ์์ฑ์ ๊ธฐ๋ณธ ์์ฑ์๋ฅผ ์ฌ์ฉ, ํ๋ผ๋ฏธํฐ๊ฐ ์๋ public ๋๋ protected ์์ฑ์ )
- final ํด๋์ค, enum, interface, inner class์๋ ์ฌ์ฉ ๋ถ๊ฐ
- ์ ์ฅํ ํ๋์ final ์ฌ์ฉ ๋ถ๊ฐ
@Table
: ์ํฐํฐ์ ๋งคํํ ํ ์ด๋ธ์ ์ง์
: ์๋ต ์ ๋งคํํ ์ํฐํฐ ์ด๋ฆ์ ํ ์ด๋ธ ์ด๋ฆ์ผ๋ก ์ฌ์ฉ
• ์์ฑ
- name : ๋งคํํ ํ ์ด๋ธ ์ด๋ฆ ( default ์ํฐํฐ ์ด๋ฆ์ ์ฌ์ฉ)
- catalog : catalog ๊ธฐ๋ฅ์ด ์๋ DB์์ catalog ๋งคํ ( default DB๋ช )
- schema : schema ๊ธฐ๋ฅ์ด ์๋ DB์์ schema๋ฅผ ๋งคํ
- uniqueConstraints : DDL ์์ฑ ์ ์ ๋ํฌ ์ ์ฝ์กฐ๊ฑด์ ๋ง๋ฆ , ์คํค๋ง ์๋์์ฑ ๊ธฐ๋ฅ์ ์ฌ์ฉํด DDL์ ๋ง๋ค ๋๋ง ์ฌ์ฉ
ํ๋์ ์ปฌ๋ผ ๋งคํ @Column
@Column
: ๊ฐ์ฒด ํ๋๋ฅผ ํ ์ด๋ธ ์ปฌ๋ผ์ ๋งคํ
: ์์ฑ ์ค name, nullable์ด ์ฃผ๋ก ์ฌ์ฉ๋๊ณ ๋๋จธ์ง๋ ์ ์ฌ์ฉ๋์ง ์์
• ์์ฑ
- name : ํ๋์ ๋งคํํ ํ ์ด๋ธ ์ปฌ๋ผ ์ด๋ฆ (default. ๊ฐ์ฒด์ ํ๋ ์ด๋ฆ)
- nullable (DDL) : null ๊ฐ์ ํ์ฉ ์ฌ๋ถ ์ค์ , false ์ค์ ์ not null (default. true)
@Colunm ์ฌ์ฉ ์ nullable = false ๋ก ์ค์ ํ๋ ๊ฒ์ด ์์
- unique (DDL) : @Table์ uniqueConstraints์ ๊ฐ์ง๋ง ํ ์ปฌ๋ผ์ ๊ฐ๋จํ ์ ๋ํฌ ์ ์ฝ์กฐ๊ฑด์ ์ ์ฉ
- columnDefinition (DDL) : ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ปฌ๋ผ ์ ๋ณด๋ฅผ ์ง์ ์ค ์ ์์.
(default. ํ๋์ ์๋ฐ ํ์ ๊ณผ ์ ๋ณด๋ฅผ ์ฌ์ฉํด ์ ์ ํ ์ปฌ๋ผ ํ์ ์ ์์ฑ)
- length (DDL) : ๋ฌธ์ ๊ธธ์ด ์ ์ฝ์กฐ๊ฑด, String ํ์ ์๋ง ์ฌ์ฉ (default. 255)
- precistion, scale(DDL) : BigDecimal, BigInteger ํ์ ์์ ์ฌ์ฉ, ์์ฃผ ํฐ ์ซ์๋ ์ ๋ฐํ ์์๋ฅผ ๋ค๋ฃฐ ๋๋ง ์ฌ์ฉ
(default. precistion= 19, scale = 2 )
@JoinColumn
: ์ธ๋ ํค๋ฅผ ๋งคํํ ๋ ์ฌ์ฉ
• ์์ฑ
- name : ๋งคํํ ์ธ๋ ํค ์ด๋ฆ (default. ์ฐธ์กฐํ๋ ํ ์ด๋ธ์ ๊ธฐ๋ณธ ํค ์ปฌ๋ผ๋ช )
- foreignKey (DDL) : ์ธ๋ํค ์ ์ฝ ์กฐ๊ฑด์ ์ง์ ์ง์ ํ ์ ์๋ค. ์ด ์์ฑ์ ํ ์ด๋ธ์ ์์ฑํ ๋๋ง ์ฌ์ฉํ๋ค.
- referencedColumnName : ์ธ๋ ํค๊ฐ ์ฐธ์กฐํ๋ ๋์ ํ ์ด๋ธ์ ์ปฌ๋ผ๋ช ( ์ฐธ์กฐํ๋ ํ ์ด๋ธ์ ๊ธฐ๋ณธํค ์ปฌ๋ผ๋ช )
unique nullable insertable updatable columnDefinition table ์ @Column ์์ฑ๊ณผ ๊ฐ๋ค.
@Temporal
: ๋ ์ง ํ์ ๋งคํ(java.util.Date, java.util.Calendar)
: LocalDate, LocalDateTime์ ์ฌ์ฉํ ๋๋ ์๋ต๊ฐ๋ฅ (์ต์ ํ์ด๋ฒ๋ค์ดํธ ์ง์)
• ์์ฑ
value
TemporalType.DATE : ๋ ์ง, ๋ฐ์ดํฐ๋ฒ ์ด์ค date ํ์ ๊ณผ ๋งคํ (ex:2013-10-11)
TemporalType.TIME : ์๊ฐ, ๋ฐ์ดํฐ๋ฒ ์ด์ค time ํ์ ๊ณผ ๋งคํ (ex:11:11:11)
TemporalType.TIMESTAMP : ๋ ์ง์ ์๊ฐ, ๋ฐ์ดํฐ๋ฒ ์ด์ค timestamp ํ์ ๊ณผ ๋งคํ (ex:2013-10-11 11:11:11)
@Enumerated
: ์๋ฐ enum ํ์ ๋งคํ
• ์์ฑ
value (ORDINAL ์ฌ์ฉํ๋ฉด ์๋๋ค)
EnumType.ORDINAL : enum ์์๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ๋ค. (default)
EnumType.STRING : enum ์ด๋ฆ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ๋ค.
@Lob
: CLOB(๋งคํํ๋ ํ๋ ํ์ ์ด ๋ฌธ์ String, char[], java.sql.CLOB), BLOB(byte[], java.sql.BLOB) ๋งคํ
: @Lob์๋ ์ง์ ํ ์ ์๋ ์์ฑ์ด ์๋ค.
@Transient
: ํน์ ํ๋๋ฅผ ์ปฌ๋ผ์ ๋งคํํ์ง ์์ (๋งคํ๋ฌด์)
: ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ, ์กฐํ ํ์ง ์์
: ์ฃผ๋ก ๋ฉ๋ชจ๋ฆฌ ์์์ ์์๋ก ๊ฐ์ ๋ณด๊ดํ๊ณ ์ถ์ ๋ ์ฌ์ฉ
@Transient
private Integer temp;
๊ธฐ๋ณธ ํค ๋งคํ @Id @GeneratedValue
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Id
: JPA ์ํฐํฐ ๊ฐ์ฒด์ ์๋ณ์๋ก ์ฌ์ฉํ ํ๋์ ์ ์ฉ
• ์ง์ ํ ๋น : ๊ธฐ๋ณธํค๋ฅผ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ง์ ํ ๋น
- em.persist()๋ฅผ ํธ์ถํ๊ธฐ ์ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ง์ ์๋ณ์ ๊ฐ์ ํ ๋นํด์ผ ํจ. ์๋ณ์ ๊ฐ์ด ์์ ๊ฒฝ์ฐ ์๋ฌ ๋ฐ์
@GeneratedValue
๊ธฐ๋ณธ ํค ์์ฑ ์ ๋ต
• ์๋ ์์ฑ : ๋๋ฆฌํค ์ฌ์ฉ๋ฐฉ์
- IDENTITY : ๊ธฐ๋ณธ ํค ์์ฑ์ ๋ฐ์ดํฐ ๋ฒ ์ด์ค์ ์์, MYSQL (=AUTO_INCREMENT)
: em.persist() ์์ ์ ์ฆ์ INSERT SQL ์คํํ๊ณ DB์์ ์๋ณ์ ์กฐํ
@Entity
public class Member{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}
- SEQUENCE: ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํ์ค๋ฅผ ์ฌ์ฉํด์ ๊ธฐ๋ณธ ํค๋ฅผ ํ ๋น, @SequenceGenerator
๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํ์ค์์ ์๋ณ์ ๊ฐ์ ํ๋ํ ํ ์์์ฑ ์ปจํ ์คํธ์ ์ ์ฅ
์ ์ผํ ๊ฐ์ ์์๋๋ก ์์ฑ (Oracle, PostgreSQL, DB2, H2)
- TABLE: ํค ์์ฑ ํ ์ด๋ธ์ ์ฌ์ฉ @TableGenerator
ํค ์์ฑ ์ ์ฉ ํ ์ด๋ธ ํ๋ ๋ง๋ค๊ณ ์ฌ๊ธฐ์ ์ด๋ฆ๊ณผ ๊ฐ์ผ๋ก ์ฌ์ฉํ ์ปฌ๋ผ์ ๋ง๋ค์ด
๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํ์ค๋ฅผ ํ๋ด๋ด๋ ์ ๋ต, ํ ์ด๋ธ์ ์ฌ์ฉํ๋ฏ๋ก ๋ชจ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฉ ๊ฐ๋ฅ
- AUTO : ์ ํํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ๋ผ ๋ฐฉ์์ ์๋์ผ๋ก ์ ํ (Default)
Ex) Oracle ์ ํ ์ SEQUNCE, MySQL ์ ํ ์ IDENTITY ์ฌ์ฉ
์ฐ๊ด๊ด๊ณ ๋งคํ @ManyToOne @OneToMany
@ManyToOne
: ๋ค๋์ผ ๊ด๊ณ ๋งคํ
• ์์ฑ
optional : false๋ก ์ค์ ํ๋ฉด ์ฐ๊ด๋ ์ํฐํฐ๊ฐ ํญ์ ์์ด์ผ ํ๋ค. (default. TRUE)
fetch : ๊ธ๋ก๋ฒ ํจ์น ์ ๋ต์ ์ค์ ํ๋ค. ( @ManyToOne=FetchType.EAGER @OneToMany=FetchType.LAZY )
cascade : ์์์ฑ ์ ์ด ๊ธฐ๋ฅ
targetEntity : ์ฐ๊ด๋ ์ํฐํฐ ํ์ ์ ๋ณด๋ฅผ ์ค์ , ๊ฑฐ์ ์ฌ์ฉํ์ง ์๋๋ค. ์ปฌ๋ ์ ์ ์ฌ์ฉํด๋ ์ ๋ค๋ฆญ์ผ๋ก ํ์ ์ ๋ณด๋ฅผ ์ ์ O
@OneToMany
: ์ผ๋๋ค ๊ด๊ณ ๋งคํ
• ์์ฑ
mappedBy : ์ฐ๊ด๊ด๊ณ์ ์ฃผ์ธ ํ๋๋ฅผ ์ ํํ๋ค.
@Aspect
: ํด๋น ํด๋์ค๊ฐ Aspect๋ฅผ ๋ํ๋ด๋ ํด๋์ค ์์ ๋ช ์
• Aspect : ํฉ์ด์ง ๊ด์ฌ์ฌ๋ฅผ ๋ชจ๋ํ ํ ๊ฒ. ์ฃผ๋ก ๋ถ๊ฐ ๊ธฐ๋ฅ์ ๋ชจ๋ํ ํจ
@PersistenceContext
: ์ํฐํฐ ๋ฉ๋์ ( EntityManager ) ์ฃผ์
@PersistenceUnit
: ์ํฐํฐ ๋ฉ๋ํฐ ํฉํ ๋ฆฌ( EntityManagerFactory ) ์ฃผ์
'๐Spring > Basic' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
JDBC vs JDBC Template vs JPA (0) | 2022.06.18 |
---|---|
Spring Framework, Spring Boot (0) | 2022.06.18 |
Spring Bean, Spring Container (0) | 2022.06.17 |
MVC, Spring MVC (0) | 2022.06.16 |
์ ์ด์ ์ญ์ ๊ณผ ์์กด์ฑ ์ฃผ์ ( Inversion of Control, Dependency Injection ) (0) | 2022.01.26 |