1) File -> New -> Other
2) Spring Boot -> Spring Starter Project
3) Name / Group / Description / Package 수정
4) 의존성 선택
프로젝트 패키지 보면서 구조에 적응하기!!
src/main/java
src/main/resources
src/test/java
=> main과 test 폴더에 있던 파일들이 위로 올라와있음
package kr.ac.ewha.java2.web;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/web")
public String hello() {
return "Hello Spring~!!";
}
@RequestMapping("/java")
public String hi() {
return "안녕 스프링~!!";
}
}
package kr.ac.ewha.java2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HelloSpring1Application {
public static void main(String[] args) {
SpringApplication.run(HelloSpring1Application.class, args);
System.out.println("Hello Spring!");
}
}

HelloSpringApplication 실행하면 콘솔은 위와 같이 뜸
=> 실행할 때는 Application을 실행해야함!! 코드 수정 후 재실행할 때는 🟥눌러서 종료 후 다시 실행




/web 일 때와 /java 일 때 다른 화면이 출력되도록 매핑!
간단한 html 생성을 통해 그냥 / 일 때 출력될 화면 만들기
=> lab2를 통해 Spring Boot의 가장 기본적인 구조 익히기!!
핵심 어노테이션 )
@SpringBootApplication : 애플리케이션의 시작점, 대표 어노테이션
@RestController : JSON 등 REST API 응답을 반환하는 컨트롤러 지정
@GetMapping : HTTP GET 요청을 처리하는 메소드에 사용
@PostMapping : HTTP POST 요청을 처리하는 메소드에 사용
@RequestMapping : GET/POST 등 다양한 HTTP 요청을 클래스/메소드에 매핑
@PathVariable : URL 경로 내 변수를 가져올 때 사용
@RequestParam : 쿼리파라미터나 폼데이터를 받아올 때 사용
@Autowired : 스프링이 자동으로 Bean을 주입해주는 의존성 주입 어노테이션
계층형 어노테이션 )
@Component [공통] Spring Bean 등록 기본, 다른 어노테이션의 상위 개념
@Service [비즈니스 로직] 서비스 계층을 나타내는 component
@Repository [데이터 접근] DAO 역할
@Entity [데이터모델] JPA에서 테이블과 매핑되는 클래스, 반드시 @Id 필드를 포함해야함
package kr.ac.ewha.java2.web;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class HelloController2 {
@GetMapping("/hello")
public String helllo() {
return "Hello from /api/hello";
}
@GetMapping("/bye")
public String bye() {
return "GoobBye from /api/bye";
}
@GetMapping("/user/{name}")
public String getUserByName(@PathVariable("name") String name) {
return "Hello~~ " + name + "!!";
}
}
@RequestMapping 통해 /api 매핑
@GetMapping 통해 한번 더 매핑
마지막 GetMapping은 /user/{name} -> @PathVariable("name") String name 통해 return 문에서 name 사용할 수 있도록 함
-> 주의할점) @PathVariable의 " " 안의 이름과 String의 이름은 같게 하기



DI : @Autowired, 생성자 주입, setter 주입으로 구현
IoC : 개발자는 필요한 기능만 정의, 나머지는 Spring이!
자동구성 : Spring Boot의 가장 강력한 기능 중 하나
-> @SpringBootApplication 안에는 자동구성을 활성화 하는 @EnableAutoConfiguration이 들어있음
++ 기본 구조!! 익숙해지자@@@@

package kr.ac.ewha.java2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import kr.ac.ewha.java2.controller.GreetingController;
@SpringBootApplication
public class HelloSpring2Application {
private final GreetingController greetingController;
HelloSpring2Application(GreetingController greetingController) {
this.greetingController = greetingController;
}
public static void main(String[] args) {
SpringApplication.run(HelloSpring2Application.class, args);
System.out.println("start!");
}
}
package kr.ac.ewha.java2.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import kr.ac.ewha.java2.service.GreetingService;
@RestController
public class GreetingController {
@Autowired
private GreetingService greetingService;
@PostMapping("/hello")
public String sayHello(@RequestParam(name="name") String name) {
System.out.println(name);
return greetingService.getGreeting(name);
}
}
package kr.ac.ewha.java2.service;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
@Service
public class GreetingService {
public String getGreeting(@RequestParam("name") String name) {
return "안녕하세요! " + name + "님! 오늘도 좋은 하루 보내세요~!";
}
}


구조는 이렇다

JpaResitory : CRUD 기능을 제공하는 인터페이스
@Entity : 해당 클래스가 DB 테이블과 매핑되는 객체임을 알려주는 어노테이션
1) 새로운 프로젝트 생성 : SpringBootDB
2) application.properties에 데이터베이스 연결정보 추가
spring.application.name=SpringBootDB
spring.datasource.hikari.jdbc-url=jdbc:mariadb://localhost:3306/test
spring.datasource.hikari.username=stdUser
spring.datasource.hikari.password=wkvmtlf2
spring.datasource.hikari.driver-class-name=org.mariadb.jdbc.Driver
spring.jpa.show-sql=true
3) User 클래스에 @Entity, @Id 어노테이션 붙이기
-> 기본생성자 넣기, id는 Auto Increment
(Generate Constructor, Generate Getter&Setter)
package kr.ac.ewha.java2.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private int age;
public User() {}
public User(String name, int age) {
super();
this.name = name;
this.age = age;
}
public User(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {return id;}
public String getName() {return name;}
public int getAge() {return age;}
public void setId(int id) {this.id = id;}
public void setName(String name) {this.name = name;}
public void setAge(int age) {this.age = age;}
}
4) UserRepository 인터페이스 생성 -> JpaRepository 상속 받기
=> 이것으로 DAO 구현이 끝난다!!
package kr.ac.ewha.java2.repository;
import org.springframework.data.jpa.repository.*;
import org.springframework.stereotype.Repository;
import kr.ac.ewha.java2.entity.User;
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
}
5) UserService와 DBController 구현
UserService : UserRepository 주입받은 후 CRUD 로직 구현
package kr.ac.ewha.java2.service;
import java.util.List;
import org.springframework.stereotype.Service;
import kr.ac.ewha.java2.entity.User;
import kr.ac.ewha.java2.repository.UserRepository;
@Service // 이 클래스가 Spring의 서비스 컴포넌트임을 나타냄 (비즈니스 로직 담당)
public class UserService {
// UserRepository를 주입받기 위한 필드 (데이터베이스 접근을 위한 인터페이스)
private final UserRepository repository;
// 생성자를 통한 의존성 주입 (Spring이 자동으로 주입해줌)
public UserService(UserRepository repository) {
this.repository = repository;
}
// CREATE: 새로운 사용자 생성 및 저장
public User create(User user) {
return repository.save(user); // JPA의 save() 메서드를 통해 DB에 저장
}
// READ: 모든 사용자 목록 조회
public List<User> read() {
return repository.findAll(); // 모든 사용자 엔티티를 리스트로 반환
}
// READ: ID로 사용자 조회 (없으면 null 반환)
public User readById(int id) {
return repository.findById(id).orElse(null); // Optional에서 값이 없으면 null 반환
}
// UPDATE: ID로 사용자 조회 후 이름과 나이를 수정
public User update(int id, User updatedUser) {
User user = readById(id); // 기존 사용자 조회
if (user == null) {
return null;
}
// 사용자 정보 업데이트
user.setName(updatedUser.getName());
user.setAge(updatedUser.getAge());
return repository.save(user);
}
// DELETE: ID로 사용자 삭제 (성공 여부를 Boolean으로 반환)
public Boolean delete(int id) {
if (!repository.existsById(id)) {
return false;
}
repository.deleteById(id); // 사용자 삭제
return true; // 삭제 성공 시 true 반환
}
}
DBController : UserService 호출 후 CRUD가 DB와 연동되도록 완성
// 사용자 관련 요청을 처리하는 Spring MVC 컨트롤러 클래스
package kr.ac.ewha.java2.controller;
import org.springframework.web.bind.annotation.*;
import kr.ac.ewha.java2.entity.User;
import kr.ac.ewha.java2.service.UserService;
import org.springframework.stereotype.Controller;
import java.util.List;
@Controller // 이 클래스가 Spring의 컨트롤러임을 나타냄
@RequestMapping("/user")
public class SpringDBController {
// 사용자 관련 비즈니스 로직을 처리하는 서비스 객체
private final UserService service;
// 생성자를 통해 UserService를 주입받음
public SpringDBController(UserService service) {
this.service = service;
}
// CREATE: 사용자 등록 처리
@PostMapping("/submitForm")
@ResponseBody // 반환값을 HTTP 응답 본문으로 직접 출력
public String create(@RequestParam("name") String name, @RequestParam("age") int age) {
service.create(new User(name, age)); // 사용자 생성 및 저장
return "<h3>등록 완료</h3><a href='/user-crud.html'>돌아가기</a>"; // 결과 HTML 반환
}
// READ: ID로 사용자 조회
@GetMapping // GET 요청 "/user?id=..." 처리
@ResponseBody
public String readById(@RequestParam("id") int id) {
User user = service.readById(id); // ID로 사용자 조회
if (user == null) return "사용자 없음!"; // 없으면 메시지 반환
// 사용자 정보 HTML로 반환
return "<h3>사용자 정보</h3>" +
"<p>ID: " + user.getId() + "</p>" +
"<p>이름: " + user.getName() + "</p>" +
"<p>나이: " + user.getAge() + "</p>" +
"<a href='/user-crud.html'>돌아가기</a>";
}
// READ: 전체 사용자 목록 조회
@GetMapping("/list") // GET 요청 "/user/list" 처리
@ResponseBody
public String list() {
List<User> users = service.read(); // 모든 사용자 조회
// HTML 테이블로 사용자 목록 구성
StringBuilder html = new StringBuilder("<h3>전체 사용자 목록</h3><table border='1'><tr><th>ID</th><th>이름</th><th>나이</th></tr>");
for (User u : users) {
html.append("<tr><td>").append(u.getId()).append("</td><td>")
.append(u.getName()).append("</td><td>")
.append(u.getAge()).append("</td></tr>");
}
html.append("</table><br><a href='/user-crud.html'>돌아가기</a>");
return html.toString(); // HTML 반환
}
// UPDATE: 사용자 정보 수정
@PostMapping("/updateForm") // POST 요청 "/user/updateForm" 처리
@ResponseBody
public String update(@RequestParam("id") int id,
@RequestParam("name") String name,
@RequestParam("age") int age) {
User result = service.update(id, new User(name, age)); // 사용자 수정
if (result == null) {
return "<h3>수정 실패: 사용자를 찾을 수 없습니다.</h3><a href='/user-crud.html'>돌아가기</a>"; // 실패 시 메시지
}
return "<h3>수정 완료</h3><a href='/user-crud.html'>돌아가기</a>"; // 성공 시 메시지
}
// DELETE: 사용자 삭제
@PostMapping("/deleteForm") // POST 요청 "/user/deleteForm" 처리
@ResponseBody
public String delete(@RequestParam("id") int id) {
boolean success = service.delete(id); // 사용자 삭제
if (!success) {
return "<h3>삭제 실패: 사용자를 찾을 수 없습니다.</h3><a href='/user-crud.html'>돌아가기</a>"; // 실패 시 메시지
}
return "<h3>삭제 완료</h3><a href='/user/list'>전체 목록 보기</a>"; // 성공 시 메시지
}
}
6) DBConfiguration 생성
package kr.ac.ewha.java2.config;
import javax.sql.DataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
@Configuration
@PropertySource("classpath:/application.properties")
public class DBConfiguration {
@Bean
@ConfigurationProperties(prefix="spring.datasource.hikari")
public HikariConfig hikariConfig() {
return new HikariConfig();
}
@Bean
public DataSource dataSource() throws Exception{
System.out.println("시작!");
DataSource dataSource = new HikariDataSource(hikariConfig());
//System.out.println(dataSource);
return dataSource;
}
}
7) input.html 입력 폼 생성
<html>
<body>
<meta charset="UTF-8">
<form method="post" action="http://127.0.0.1:8080/user/submitForm" accept-charset="UTF-8">
<input type="text" name="name" value="이름" />
<input type="number" name="age" value="5" />
<button type="submit" >보내기</button>
</form>
</body>
</html>
8) SpringBootDBApplication 실행
package kr.ac.ewha.java2;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import kr.ac.ewha.java2.entity.User;
import kr.ac.ewha.java2.service.UserService;
@SpringBootApplication
public class SpringBootDbApplication implements CommandLineRunner {
@Autowired
private UserService userService;
public static void main(String[] args) {
SpringApplication.run(SpringBootDbApplication.class, args);
System.out.println("Project : Spring Boot DB start!");
}
@Override //코드에서 테스트하기
public void run(String... args) throws Exception {
System.out.println("Spring DB is running");
List <User> users = userService.read();
for (User u : users) {
System.out.println(u.getId() + u.getName());
}
userService.create(new User("까만둥이",10));
User user =new User();
user.setName("유리유리");
user.setAge(5);
userService.create(user);
}
}
Spring Data JPA를 활용하면 CrudRepository나 JpaRepository로 인해 자동 쿼리 처리가 되어 복잡한 SQL 없이도 기본 CRUD를 쉽게 구현할 수 있음
아직 SQL 문법에 익숙하지 않은 상태였기에 Spring Data를 구성하는 구조들만 파악하면 훨씬 쉽게 만들 수 있었던 것 같음
특히 DAO를 구현하는 과정이 JDBC를 공부할 때는 많이 어려웠는데 Spring Data를 통해 만드니 UserRepository만 만들면 빠르게 DAO를 구현할 수 있었어 편리했음
그리고 src/main/java가 가장 위로 올라와있고, 그 밑에 각각의 패키지를 만들고 클래스를 분리하니 훨씬 보기에도 편리했고 역할의 분리와 코드 진행의 흐름이 눈에 더 잘 들어오는 것 같았음
이제 UserService와 DBController를 내가 원하는 기능들을 구현할 수 있게끔 잘 수정하고 만들기 위한 연습을 하면 좋을 것 같다