[ํ๊ฒฝxToss] 15์ฃผ์ฐจ ์์ฝ : Java SpringBoot + ์ฒซ ์คํ๋ง ๋ฐฑ์๋ ๊ฐ๋ฐ
๊ฐ์ธ์ ํ์ต ๋ด์ฉ ๊ธฐ๋ก ์ค, ๊ทนํ ์ผ๋ถ์ ๋ด์ฉ๋ง ์์ฑ๋์์ต๋๋ค.
์๋ฐ ์คํ๋ง๋ถํธ ๊ธฐ์ด
๐ฑ Spring ๊ฐ๋
- Java ๊ธฐ๋ฐ์ ์น ์ ํ๋ฆฌ์ผ์ด์ ํ๋ ์์ํฌ
- ๋ชฉํ: ํ๋ ์๋ฐ ๊ธฐ๋ฐ ์ํฐํ๋ผ์ด์ฆ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ํ๋ก๊ทธ๋๋ฐ ๋ฐ ์ค์ ๋ชจ๋ธ ์ ๊ณต
โจ Spring์ ์ฃผ์ ํน์ง
- POJO ์งํฅ
- POJO (Plain Old Java Object): ์ธ๋ถ ๊ธฐ์ ์์ด ์์ Java๋ก ์์ฑ๋ ๊ฐ์ฒด
- ๊ฒฝ๋ ์ปจํ ์ด๋
- ๊ฐ์ฒด ์์ฑ ๋ฐ ๊ด๋ฆฌ๋ฅผ ์์ฒด์ ์ผ๋ก ์ํ
- IoC (์ ์ด์ ์ญ์ ) / DI (์์กด์ฑ ์ฃผ์ )
- ๊ฐ์ฒด ๊ฐ ์์กด์ฑ์ ์ธ๋ถ์์ ์ฃผ์ ํ์ฌ ์ ์ฐํ ๊ตฌ์กฐ ์ค๊ณ ๊ฐ๋ฅ
- AOP (๊ด์ ์งํฅ ํ๋ก๊ทธ๋๋ฐ)
- ๊ณตํต ๊ด์ฌ ์ฌํญ(๋ก๊น , ๋ณด์ ๋ฑ)์ ํต์ฌ ๋ก์ง๊ณผ ๋ถ๋ฆฌํ์ฌ ๊ด๋ฆฌ
๐ Spring Boot ์ฃผ์ ์ด๋ ธํ ์ด์
๐น @SpringBootApplication
- 3๊ฐ์ง ์ด๋
ธํ
์ด์
์ ์กฐํฉ:
- @ComponentScan: Bean ๋ฑ๋ก
- @EnableAutoConfiguration: ์๋ ์ค์
- @SpringBootConfiguration: ์ค์ ํด๋์ค
โ Bean (๋น)
- Spring์ด ๊ด๋ฆฌํ๋ ๊ฐ์ฒด
- ์ฑ๊ธํค์ผ๋ก ๊ด๋ฆฌ๋จ (์ด๋ฆ ์ค๋ณต ๋ถ๊ฐ)
- ์ด๋ฆ ๊ท์น: ์ฒซ ๊ธ์ ์๋ฌธ์
Bean ๋ฑ๋ก ๋ฐฉ๋ฒ
@Configuration + @Bean | ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ | ์๋ ๋ฑ๋ก |
@Component + @Autowired | ์ง์ ์์ฑํ ํด๋์ค | ์๋ ๋ฑ๋ก |
๐ง Autowired ์ฃผ์ ๋ฐฉ์
(์๋ฐ ๋น ์์ฑ)
- ํ๋ ์ฃผ์
- ํ๋์ @Autowired ๋ถ์ฌ ์ฃผ์
- ๊ฐ์ฅ ๊ฐ๋จํ์ง๋ง, ํ ์คํธ๋ ์ ์ง๋ณด์์์ ๋ถ๋ฆฌํ ์ ์์
- ์์ฑ์ ์ฃผ์
(๊ถ์ฅ)
- ์์ฑ์์ @Autowired๋ฅผ ๋ถ์ฌ ์ฃผ์
- final๋ก ์ ์ธ ๊ฐ๋ฅ → ๋ถ๋ณ์ฑ ์ ์ง
- ํ ์คํธ์ ์ ๋ฆฌํ๊ณ ์ฝ๋ ๊ฐ๋ ์ฑ์ด ๋์
- ์ธํฐ ์ฃผ์
- ์ธํฐ ๋ฉ์๋์ @Autowired ๋ถ์ฌ ์ฃผ์
- ์ ํ์ ์์กด์ฑ ์ฃผ์ ์ด ๊ฐ๋ฅ
@RestController
- @Controller + @ResponseBody๋ฅผ ํฉ์น ๊ฒ
- ์ฃผ๋ก JSON ๋ฐ์ดํฐ ๋ฐํ์ ์ฌ์ฉ๋จ
โ Lombok
- ๋ฐ๋ณต ์ฝ๋ ์ค์ฌ์ฃผ๋ Java ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- ์ฃผ์ ์ด๋
ธํ
์ด์
:
- @Getter, @Setter: ํ๋ ์ ๊ทผ ๋ฉ์๋ ์๋ ์์ฑ
- @ToString, @EqualsAndHashCode: ๊ฐ์ฒด ์ ๋ณด ๋ฉ์๋ ์๋ ์์ฑ
- @NoArgsConstructor, @AllArgsConstructor, @RequiredArgsConstructor: ์์ฑ์ ์๋ ์์ฑ
- @Data: ์ ์ฌ๋ฌ ์ด๋ ธํ ์ด์ ํฌํจ
- @Builder: ๋น๋ ํจํด ์ ๊ณต
โ Thymeleaf
- HTML ๊ธฐ๋ฐ ํ ํ๋ฆฟ ์์ง (Spring Boot์ ์ ์ฐ๋)
- ํน์ง:
- ๋ธ๋ผ์ฐ์ ์นํ์
- ์ง๊ด์ ๋ฌธ๋ฒ
- ์๋ฒ ๋ฐ์ดํฐ ์ฝ๊ฒ ์ฃผ์
- devtools๋ก ์๋ ๋ฆฌ๋ ๋๋ง ์ง์
Java์์ ๋ฐ์ดํฐ ์ ๋ฌ ๋ฐฉ์
- request, session: HTTP ๊ด๋ จ ๊ฐ์ฒด
- GET/POST ํ๋ผ๋ฏธํฐ: ํด๋ผ์ด์ธํธ ์ ๋ฌ ๋ฐ์ดํฐ
- Model: ๋ทฐ์ ๋ฐ์ดํฐ ์ ๋ฌ
- ModelAndView: ๋ชจ๋ธ๊ณผ ๋ทฐ๋ฅผ ํจ๊ป ์ ๋ฌ
๋ด์ฅ ๊ฐ์ฒด ์๋ช ์ฃผ๊ธฐ
- application: ์ฑ ์ ์ฒด ์๋ช ์ฃผ๊ธฐ
- session: ์ฌ์ฉ์ ๋จ์
- request: ํ ๋ฒ์ ์์ฒญ-์๋ต ์ฌ์ด
- model: request์ ๋์ผ
@Value ์ฉ๋
- Spring์ @Value: ์ค์ ๊ฐ ์ฃผ์ (@Value("${key}"))
- Lombok์ @Value: ๋ถ๋ณ ๊ฐ์ฒด ์์ฑ์ฉ (final, getter ์๋ ์์ฑ ๋ฑ)
์ญํ ์ ๋ฆฌ
- DTO: ๋ฐ์ดํฐ ์ ๋ฌ์ฉ ๊ฐ์ฒด(Data Transfer Object)
- DAO: DB ์ ๊ทผ ๊ฐ์ฒด
- Entity: DB ํ ์ด๋ธ ๋งคํ ํด๋์ค
- VO: ์ฝ๊ธฐ ์ ์ฉ ๋ฐ์ดํฐ ๋ด๋ ๊ฐ์ฒด
- Controller: HTTP ์์ฒญ ์ฒ๋ฆฌ
- Service: ๋น์ฆ๋์ค ๋ก์ง ์ฒ๋ฆฌ
- Repository: DB ์ฒ๋ฆฌ ๋ก์ง ๋ด๋น
โ H2DB (Java๋ฅผ ์ํด ํ์ด๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค)
๋ก์ปฌ ํ๊ฒฝ, ๊ท๋ชจ๊ฐ ํฌ์ง ์์ ํ๋ก์ ํธ์์ DB ์ ํ์ H2 ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ต๊ณ ์ ์ ํ์ด ๋ ์ ์์ต๋๋ค.
H2 = ์๋ฐ๋ก ์์ฑ๋ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ฆฌ ์์คํ
Entity : ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ๊ณผ ๋งคํ๋๋ ํด๋์ค
- @Entity ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํด JPA๊ฐ ์ด ํด๋์ค๋ฅผ ํ ์ด๋ธ๋ก ์ธ์ํ๊ฒ ํจ
- ํด๋์ค์ ํ๋ = ํ ์ด๋ธ์ ์ปฌ๋ผ์ด ๋จ.
- DB์ ์ง์ ์ฐ๊ฒฐ๋๋ ๊ฐ์ฒด๋ก, ๋ณดํต ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ์ฅ/์กฐํ์ฉ์ผ๋ก ์ฌ์ฉ
- @Id, @GeneratedValue, @Column ๋ฑ ๋ค์ํ JPA ์ด๋ ธํ ์ด์ ์ผ๋ก ์ปฌ๋ผ ์์ฑ์ ์ง์ ํ ์ ์์
@Entity
public class User { // User ํด๋์ค: user ํ
์ด๋ธ๋ก ๋งคํ๋จ
@Id
@GeneratedValue
private Long id;
private String name;
private String email;
// id, name, email์ ๊ฐ๊ฐ ์ปฌ๋ผ์ผ๋ก ์ฌ์ฉ
}
๐งช @SpringBootTest
: ์คํ๋ง ๋ถํธ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์ปจํ ์คํธ๋ฅผ ๋ก๋ฉํด์ ํ ์คํธํ ๋ ์ฌ์ฉํ๋ ์ด๋ ธํ ์ด์ .
๐ง ์ฃผ์ ํน์ง
- ์ค์ ์คํ๋ง ๋ถํธ ์ฑ์ฒ๋ผ ๋น(Bean)๋ค์ด ๋ชจ๋ ๋ฑ๋ก๋ ์ํ์์ ํ ์คํธ ๊ฐ๋ฅ
- ํตํฉ ํ ์คํธ์ ์ ํฉ (Controller, Service, Repository ๋ชจ๋ ์ฎ์ธ ํ ์คํธ)
@SpringBootTest
class UserServiceTest {
@Autowired
UserService userService;
@Test
void testCreateUser() {
// ํ
์คํธํ ๋ก์ง ์์ฑ
}
}
โ JpaRepository ๊ธฐ๋ณธ ํจ์
- findAll() : ์ ์ฒด ์กฐํ (SELECT *)
- save() :
- id ์์ผ๋ฉด INSERT
- id ์์ผ๋ฉด UPDATE
- delete() : ์ญ์ (DELETE)
์ฌ์ฉ์ ์ ์ ์ฟผ๋ฆฌ ๋ฉ์๋
- findByํ๋๋ช
() ํํ๋ก ์ฌ์ฉ
→ ์:- findById(2L) → SELECT * FROM member WHERE id = 2
- findByUserId("hong") → SELECT * FROM member WHERE user_id = 'hong'
JPA์์ SQL ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
- JPQL
- ANSI SQL ์ง์, DBMS ๋ ๋ฆฝ์
- FROM์ ์๋ ์ํฐํฐ ํด๋์ค๋ช ์ฌ์ฉ (์๋ฌธ์ โ)
- Native SQL
- DBMS์ ์ข ์์ ๊ธฐ๋ฅ ์ฌ์ฉ ๊ฐ๋ฅ (์: LIMIT, now(), sysdate)
- UPDATE, INSERT, DELETE ์
@Modifying, @Transactional ํ์
์๋ฐ์คํ๋ง์ผ๋ก ์ฒ์ API๋ฅผ ๊ฐ๋ฐํด๋ดค๋๋ฐ, ์๊ทผํ ์ฌ๋ฏธ์์๋ค (์ด๊ฒ..๊ทธ ์ทจ์
์๋๋ค๋ ์คํ๋ง๋ถํธ๊ตฌ๋!)
๊ทธ๋ฆฌ๊ณ ํ ์คํธ์ฝ๋๋ฅผ ์ฒ์ ์จ๋ณด์๋ค!
์์ง ํ ์คํธ์ฝ๋๋ฅผ ์ค์ ๋ก ์ด๋ป๊ฒ ์ ํ์ฉํด์ผ ํ๋์ง๋ ๋ชจ๋ฅด๊ฒ ์ง๋ง, ๊ณ์ ์ฐ์ตํด๋ณด๋ฉด ๊ฐ์ด ์กํ ๊ฒ ๊ฐ๋ค.
๋ฐฑ์๋๋ฅผ ๋ฐฐ์ฐ๋ฉด์ ๋๋๊ฑฐ์ง๋ง, ๋ด๊ฐ ํ๋ก ํธ์๋๋ฅผ ์ข์ํ๋ ์ด์ ์ค ํ๋๊ฐ
๊ฒฐ๊ณผ๋ฌผ์ด ์ง๊ด์ ์ผ๋ก ๋ฐ๋ก ๋์ ๋ณด์ด๊ธฐ ๋๋ฌธ์ด์๋ค (์ค์๊ฐ ๋ฆฌ๋ก๋ฉ ๊ฐ๋ฅ + ์ง๊ด์ฑ)
API๋ ๋ญ๊ฐ.. ์ฑ๊ณตํ๋ฉด ๋ฟ๋ฏํ๊ธด ํ๋ฐ ๋ต๋ตํ๋ค ใ ใ ใ ใ
FE๋ ๋ด ๊ฐ์ ์ธ ๋ฏธ๊ฐ์ ์ ํ์ฉํ ์ ์๊ธฐ๋ ํ๊ณ ,
๋์ผ๋ก ๋ฐ๋ก ํ์ธํ๋๊ฑธ ์ข์ํด์(์ ๋งคํ ๊ฑธ ์ซ์ดํจ) ๋ UI๊ฐ ์ข์ ^-^
์ฐ์ต ์ฝ๋ : https://github.com/inthhh/javaSpring_code