Spring Boot To do List_03 할 일 추가

송지윤·2024년 4월 13일
0

Spring Framework

목록 보기
19/65
  1. main.html 에 할 일 추가 할 곳 html 작성 후 추가하기 버튼 눌렀을 때 요청이 가게 form 태그 안에 넣어주기
  2. 요청 받은 주소 mapping 해서 parameter 로 html 에서 넘겨준 값 받아서 service 호출
  3. 요청 받은 서비스 클래스에서 매개변수로 받은 값을 하나로 합쳐서 mapper 호출
    (sql 로 여러 개 매개변수를 전달할 수 없음)
  4. mapper.xml 에서 insert 로 구문 작성 후 다시 service로 반환
  5. service 에서 controller 로 반환할 때 insert 구문은 트랜잭션 처리 (어노테이션으로 대신함)
  6. 돌려 받은 값에 따라 message 띄워줄건데 main 페이지로 redirect 해줄 거라서 message 값을 request 에 실을 수 없음 RedirectAttributes 이용해서 보내줌
  7. html 에서 값을 받아서 message 띄워줄 건데 여기 저기서 띄워줄거라서 따로 html 만들어서 불러서 사용할 거

1. main.html 에 할 일 추가 할 곳 html 작성 후 추가하기 버튼 눌렀을 때 요청이 가게 form 태그 안에 넣어주기

main.html

    <!-- 할 일 추가 form -->
    <form action="/todo/add" method="post">
        <h4>할 일 추가</h4>

        <div>
            제목 : <input type="text" name="todoTitle">
        </div>

        <div>
            <textarea name="todoContent"
                cols="50" rows="5" placeholder="상세 내용"></textarea>
        </div>

        <button>추가하기</button>
    </form>

2. 요청 받은 주소 mapping 해서 parameter 로 html 에서 넘겨준 값 받아서 service 호출

/todo 로 시작하는 모든 요청 매핑해줄 Controller 생성해서 RequestMapping 먼저 해주고
service 호출
add PostMapping 해주고 service 로 값 전달

@RequestMapping("todo") // "/todo"로 시작하는 모든 요청 매핑
@Controller
public class TodoController {

	@Autowired // 같은 타입/상속관계 Bean 의존성 주입 (DI)
	private TodoService service;
	
	@PostMapping("add") // "/todo/add" Post 방식 요청 매핑
	public String addTodo(
			@RequestParam("todoTitle") String todoTitle,
			@RequestParam("todoContent") String todoContent
			) {

		// 서비스 메서드 호출 후 결과 반환 받기 (insert)
		int result = service.addTodo(todoTitle, todoContent);

3. 요청 받은 서비스 클래스에서 매개변수로 받은 값을 하나로 합쳐서 mapper 호출 (sql 로 여러 개 매개변수를 전달할 수 없음)

serviceImpl

	@Override
	public int addTodo(String todoTitle, String todoContent) {
		
		// 마이바티스에서 SQL에서 전달할 수 있는 파라미터 개수는
		// 오직 1개
		// -> todoTitle, todoContent 를 Todo DTO 로 묶어서 전달
		
		Todo todo = new Todo();
		todo.setTodoTitle(todoTitle);
		todo.setTodoContent(todoContent);
		
		return mapper.addTodo(todo);
	}

int result = mapper.addTodo(todo);
return result;
==> return mapper.addTodo(todo);

4. mapper.xml 에서 insert 로 구문 작성 후 다시 service로 반환

	<insert id="addTodo" parameterType="Todo">
		INSERT INTO TB_TODO
		VALUES(SEQ_TODO_NO.NEXTVAL, #{todoTitle}, #{todoContent}, DEFAULT, DEFAULT)
	</insert>

parameterType : 전달 받은 값(전달 인자/매개변수)의 타입을 명시
-> DTO, Map 인 경우 필드명/key 를 입려해서 하나씩 꺼내올 수 있음

mapper 에서 java 의 data(파라미터)를 SQL에 삽입하는 방법

1) #{변수명 | 필드명} : SQL에 삽입 시 양쪽에 ''(홑따옴표) 붙여서 삽입

2) ${변수명 | 필드명} : SQL에 삽입 시 양쪽에 ''(홑따옴표) 붙이지 않고 삽입

-> ${} 는 삽입한 값이 숫자일 경우 (숫자 리터럴에 '' 없음)
==> 숫자는 #{}로 써도 됨 DB에서 자동 변환

-> SQL문 자체가 변해야 하는 경우에 사용
ex) java 에서 보낸 파라미터가 String ENROLL_DATE
SELECT MEMBER_NAME, ${key} FROM "MEMBER"

${key} == ENROLL_DATE 인 경우
SELECT MEMBER_NAME, ENROLL_DATE FROM "MEMBER"

${key} == MEMBER_ADRESS 인 경우
SELECT MEMBER_NAME, MEMBER_ADDRESS FROM "MEMBER"

(이럴 때 #{}으로 쓰면 'ENROLL_DATE' 로 들어가서 컬럼명의 역할을 하지 못함)

5. service 에서 controller 로 반환할 때 insert 구문은 트랜잭션 처리 (어노테이션으로 대신함)

serviceImpl

@Transactional(rollbackFor = Exception.class)
public class TodoServiceImpl implements TodoService {

@Transactional

  • 트랜잭션 처리를 수행하라고 지시하는 어노테이션
    ( == 선언적 트랜잭션 처리)
  • 정상 코드 수행 시 COMMIT
  • 기본값 : Service 내부 코드 수행 중 RuntimeException 발생 시 rollback
  • rollbackFor 속성 : 어떤 예외가 발생했을 때 rollback 할 지 지정

(rollbackFor = Exception.class)

  • 모든 종류의 예외 발생 시 rollback 수행

6. 돌려 받은 값에 따라 message 띄워줄건데 main 페이지로 redirect 해줄 거라서 message 값을 request 에 실을 수 없음 RedirectAttributes 이용해서 보내줌

controller

RedirectAttributes ra
매개 변수 추가

	@PostMapping("add")
	public String addTodo(
			@RequestParam("todoTitle") String todoTitle,
			@RequestParam("todoContent") String todoContent,
			RedirectAttributes ra
			) {

RedirectAttributes : 리다이렉트 시 값을 1회성으로 전달하는 객체
RedirectAttributes.addFlashAttribute("key", value) 형식으로 작성하면 잠깐 세션에 속성을 추가 (원래는 request scope)

[원리]
응답 전 : request scope
redirect 중 : session scope 로 이동
응답 후 : request scope 복귀

controller

ra 에 실을 message 추가

		// 삽입 결과에 따라 message 값 지정
		String message = null;
		
		if(result > 0) message = "할 일 추가 성공";
		else message = "할 일 추가 실패";
		
		// 리다이렉트 후 1회성으로 사용할 데이터를 속성으로 추가
		ra.addFlashAttribute("message", message);
		
		return "redirect:/"; // 메인 페이지 재요청

7. html 에서 값을 받아서 message 띄워줄 건데 여기 저기서 띄워줄거라서 따로 html 만들어서 불러서 사용할 거

templates/common/footer.html

<!-- message 값 alert 띄워줄 script 작성 -->
<script th:inline="javascript">
    const message = /*[[${message}]]*/ "전달받은메세지";

    // 전달 받은 message가 없으면 null

    if(message != null) {
        alert(message);
    }

</script>

th:inline="javascript" 적어두면 script 태그 안에서 thymeleaf 사용할 수 있음

th:inline="javascript"

  • script 태그에 작성하는 속성
  • 타임리프 문법으로 출력된 내용/값을 JS에 알맞은 타입으로 변환
const message = /*[[${message}]]*/ "전달받은메세지";

JS Inline - Natural Template
스크립트 태그 내부에서 타임리프의 변수나 연산을 사용할 수 있게함

  • HTML 파일 독립 실행 시
    JS 내부 타임리프 코드 오류를 발생하지 않게함
  • HTML 문법 오류 (컴파일 오류)도 해결

0개의 댓글