2022_02_20 - oneso123456789/2022 GitHub Wiki

other

#8.2.4 update 처리 마지막으로 update 처리를함
게시물의 업데이트는 제목, 내용 작성자를 수정한다고 가정함
업데이트를 할 때는 최종 수정 시간을 데이터베이스 내 현재 시간으로 수정함
Update는 delete와 마찬가지로 '몇 개의 데이터가 수정되었는가'를 처리할 수 있게 int 타입으로 메서드를 설계할 수 있음

BoardMapper 인터페이스 일부(update추가 부분만 적음)

    public int update(BoardVO board); 

매개변수 잘 설계하기 BoardVO 로 해야할것을 Long 으로 설계함

BoardMapper.xml의 일부

    <update id="update">
        update tbl_board
        set title = #{title},
        content = #{content},
        writer = #{writer},
        updateDate = sysdate
        where bno = #{bno}
    </update>

SQL에서 주의 깊게 봐야 하는 부분은 update 칼럼이 최종 수정시간을 의미하는 칼럼이기 때문에
현재 시간으로 변경해 주고 있다는 점과, regdate 칼럼은 최초 생성 시간이므로 건드리지 않는다는 점임
#{title}과 같은 부분은 파라미터로 전달된 BoardVO 객체의 getTitle()과 같은 메서드들을
호출해서 파라미터들이 처리됨

테스트 코드는 read()를 이용해서 가져온 BoardVO 객체의 일부를 수정하는 방식이나
직접 BoardVO 객체를 생성해서 처리할 수 있음
예제는 객체를 생성해서 테스트를 진행함

BoardMapperTests 클래스의 일부

    @Test
    public void testUpdate() {
        BoardVO board = new BoardVO();
        board.setBno(5L);
        board.setTitle("update제목");
        board.setContent("update내용");
        board.setWriter("update작성자");
        
        int count = mapper.update(board);
        log.info("UPDATE COUNT: " + count);
    }

Chapter 09 비즈니스 계층

비즈니스 계층은 고객의 요구사항을 반영하는 계층으로 프레젠테이션 계층과
영속 계층의 중간다리 역활을 하게됨
영속 계층은 데이터베이스를 기준으로 해서 설계를 나눠 구현하지만,
비즈니스 계층은 로직을 기준으로 해서 처리하게 됨.

예컨대, '쇼핑몰에서 상품을 구매한다'고 가정해 봄
해당 쇼핑몰의 로직이 '물건을 구매한 회원에게는 포인트를 올려준다'고 하면
영속 계층의 설계는 '상품'과'회원'으로 나누어서 설계하게 됨.

반면에 비즈니스 계층은 상품 영역과 회원 영역을 동시에 사용해서 하나의 로직을
처리하게 되므로 다음과 같은 구조를 만들게 됨

현재 예제는 단일한 테이블을 이용하기 때문에 위와 같은 구조는 아니지만,
설계를 할 때는 원칙적으로 영역을 구분해서 작성해야 함.
일반적으로 비즈니스 영역에 있는 객체들은 '서비스(Service)'라는 용어를 많이 사용함

9.1 비지니스 계층의 설정

비즈니스 계층을 위해서 프로젝트 내 com.crow.service라는 패키지를 작성함

설계를 할 때 각 계층 간의 연결은 인터페이스를 이용해서 느슨한(loose) 연결(결합)을 함
게시물은 BoardService 인터페이스와 인터페이스를 구현한 BoardServiceImpl클래스를 선언함

BoardService 인터페이스

package com.crow.service;

import java.util.List;

import com.crow.domain.BoardVO;

public interface BoardService {
    
    public void register();
    
    public BoardVO get(Long bno);
    
    public boolean modify(BoardVO board);
    
    public boolean remove(Long bno);
    
    public List<BoardVO> getList();
}

BoardService 메서드를 설계할 때 메서드 이름은 현실적인 로직의
이름을 붙이는 것이 관례임
명백하게 반환해야 할 데이터가 있는 'select'를 해야 하는 메서드는 리턴 타입을 지정 할 수 있음
게시물은 특정한 게시물을 가져오는 get() 메서드와 전체 리스트를 구하는 getList()의 경우
처음부터 메서드의 리턴 타입을 결정해서 진행할 수 있음

BoardService 인터페이스를 구현하는 구현체는 BoardServiceImpl이라는 클래스로 구현
클래스의 상세 내용은 조금 미루고, 약간의 로그를 기록할 수 있는 정도의 코드를 작성함

BoardServiceImpl 클래스의 일부

package com.crow.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.crow.domain.BoardVO;
import com.crow.mapper.BoardMapper;

import lombok.AllArgsConstructor;
import lombok.Setter;
import lombok.extern.log4j.Log4j;

@Log4j
@Service
@AllArgsConstructor
public class BoardServiceImpl implements BoardService {
    
    private BoardMapper mapper;
    
    @Override
    public void register() {
        // TODO Auto-generated method stub

    }
    ...

BoardServiceImpl 클래스에 가장 중요한 부분은 @Service라는 어노테이션임
@Service는 계층 구조상 주로 비즈니스 영역을 담당하는 객체임을 표시하기 위해서 사용
작성된 어노테이션은 패키지를 읽어 들이는 동안 처리됨
BoardServiceImpl가 정상적으로 동작하기 위해서는 BoardMapper 객체가 필요함

이는 @Autowired와 같이 직접 설정해 줄 수 있고, Setter를 이용해서 처리할 수도 있음
Lombok을 이용한다면 아래와 같은 방식으로 만들 수 있음

@Log4j
@Service
@AllArgsConstructor
public class BoardServiceImpl implements BoardService {
    
    @Setter(onMethod_ = @Autowired)
    private BoardMapper mapper;
...

스프링 4.3부터는 단일 파라미터를 받는 생성자의 경우에는 필요한 파라미터를 자동으로 주입 할 수 있음
@AllArgsContstructor는 모든 파라미터를 이용하는 생성자를 만들기 때문에 실제 코드는
BoardMapper를 주입받는 생성자가 만들어지게 됨

프로젝트 구조에서 클래스를 조사해 보면 스프링 4.3의 자동주입 기능으로 인해 앞의 그림과 같은 형태가됨
(201p 아래 그림 참조)

⚠️ **GitHub.com Fallback** ⚠️