코딩항해기

[과제/Spring] Spring Service, ServiceImpl 연습 본문

problem solving/과제&실습 코딩

[과제/Spring] Spring Service, ServiceImpl 연습

miniBcake 2024. 10. 5. 19:32

 

 

  • 기존 memberDAO와 boardDAO에 Service와 ServiceImpl 추가하기
  • Client(Class)에서 new 지시자 사용없이 출력하기

 

아직 DAO에 new가 가득한데 이 new를 제거하는 진도까지 나가진 않았다.

기존 DAO까지는 동일하며 이번 과제에서 DAO에 추가된 부분은 @Repository 어노테이션 뿐이었다.

따라서 Service와 ServiceImpl만 추가된 형태이다.

 

먼저 ServiceImpl의 메서드 시그니처가 DAO와 통일되는 것이 중요하기 때문에 구현할 인터페이스 Service를 만들었다.

public interface MemberService {
	List<MemberDTO> selectAll(MemberDTO memberDTO);
	MemberDTO selectOne(MemberDTO memberDTO);
	boolean insert(MemberDTO memberDTO);
	boolean update(MemberDTO memberDTO);
	boolean delete(MemberDTO memberDTO);
}
public interface BoardService {
    List<BoardDTO> selectAll(BoardDTO boardDTO);
    BoardDTO selectOne(BoardDTO boardDTO);
    boolean insert(BoardDTO boardDTO);
    boolean update(BoardDTO boardDTO);
    boolean delete(BoardDTO boardDTO);
}

 

이제 이 Service인터페이스를 구현하는 ServiceImpl을 만든다. ServiceImpl은 JSP 프로젝트를 진행할 때 Action 역할을 하며 실 기능은 DAO이기 때문에 DAO를 리턴한다. 이때 Spring은 객체 관리를 컨테이너가 해주므로 의존성 주입이 필요하다.

@Service("memberService") //memberService로 호출
public class MemberServiceImpl implements MemberService {
	@Autowired //의존성 주입
	private MemberDAO memberDAO;
	
	@Override
	public List<MemberDTO> selectAll(MemberDTO memberDTO) {
		return this.memberDAO.selectAll(memberDTO);
	}

	@Override
	public MemberDTO selectOne(MemberDTO memberDTO) {
		return this.memberDAO.selectOne(memberDTO);
	}

	@Override
	public boolean insert(MemberDTO memberDTO) {
		return this.memberDAO.insert(memberDTO);
	}

	@Override
	public boolean update(MemberDTO memberDTO) {
		return this.memberDAO.update(memberDTO);
	}

	@Override
	public boolean delete(MemberDTO memberDTO) {
		return this.memberDAO.delete(memberDTO);
	}
}
@Service("boardService")//boardService로 호출
public class BoardServiceImpl implements BoardService {
    @Autowired //의존성주입
    private BoardDAO boardDAO;

    @Override
    public List<BoardDTO> selectAll(BoardDTO boardDTO) {
        return this.boardDAO.selectAll(boardDTO);
    }

    @Override
    public BoardDTO selectOne(BoardDTO boardDTO) {
        return this.boardDAO.selectOne(boardDTO);
    }

    @Override
    public boolean insert(BoardDTO boardDTO) {
        return this.boardDAO.insert(boardDTO);
    }

    @Override
    public boolean update(BoardDTO boardDTO) {
        return this.boardDAO.update(boardDTO);
    }

    @Override
    public boolean delete(BoardDTO boardDTO) {
        return this.boardDAO.delete(boardDTO);
    }
}

 

이때 자동으로 의존성을 주입하기 때문에 해당 객체가 컨테이너에서 관리되고 있어야 의존주입을 할 수 있다.

DAO에 @Repository를 작성한다. Autowired는 타입을 보고 객체를 찾기 때문에 따로 이름을 설정할 필요는 없다.

(객체관리가 컨테이너에서 이뤄지지 않는 JSP 수업 실습 때 JDBC 코드를 그대로 가져왔으므로 접은 글로 달았다)

더보기
@Repository
public class BoardDAO {
    private final String SELECTALL = "select NUM, CONTENT from board";
    private final String SELECTONE = "SELECT NUM, CONTENT FROM BOARD B where NUM=?";

    public List<BoardDTO> selectAll(BoardDTO boardDTO) {
        List<BoardDTO> datas = new ArrayList<>();
        Connection conn= JDBCUtil.connect();
        PreparedStatement pstmt = null;
        try {
            pstmt = conn.prepareStatement(SELECTALL);
            ResultSet rs=pstmt.executeQuery();
            while(rs.next()) {
                BoardDTO data = new BoardDTO();
                data.setBoardNum(rs.getInt("NUM"));
                data.setContent(rs.getString("CONTENT"));
                datas.add(data);
            }
        } catch (SQLException e) {
            System.out.println("SQLException: " + e.getMessage());
        } finally {
            JDBCUtil.disconnect(pstmt,conn);
        }
        return datas;
    }
    public BoardDTO selectOne(BoardDTO boardDTO) {
        BoardDTO data=null;

        Connection conn=JDBCUtil.connect();
        PreparedStatement pstmt = null;
        try {
            pstmt=conn.prepareStatement(SELECTONE);
            pstmt.setInt(1, boardDTO.getBoardNum());
            ResultSet rs=pstmt.executeQuery();
            if(rs.next()) {
                data=new BoardDTO();
                data.setBoardNum(rs.getInt("NUM"));
                data.setContent(rs.getString("CONTENT"));
            }
        } catch (SQLException e) {
            System.out.println("SQLException: " + e.getMessage());
            return null;
        } finally {
            JDBCUtil.disconnect(pstmt,conn);
        }
        return data;
    }
    public boolean insert(BoardDTO boardDTO) {
        return false;
    }
    public boolean update(BoardDTO boardDTO) {
        return false;
    }
    public boolean delete(BoardDTO boardDTO) {
        return false;
    }
}
@Repository
public class MemberDAO {
	private final String SELECTALL = "select MID,PASSWORD,NAME,ROLE from member";
	private final String INSERT = "INSERT INTO MEMBER (MID,PASSWORD,NAME,ROLE) VALUES(?,?,?,?)";

	public List<MemberDTO> selectAll(MemberDTO memberDTO) {
		List<MemberDTO> datas = new ArrayList<MemberDTO>();
		Connection conn=JDBCUtil.connect();
		PreparedStatement pstmt;
		try {
			pstmt = conn.prepareStatement(SELECTALL);
			ResultSet rs=pstmt.executeQuery();
			while(rs.next()) {
				MemberDTO data = new MemberDTO();
				data.setMid(rs.getString("MID"));
				data.setName(rs.getString("NAME"));
				data.setPassword(rs.getString("PASSWORD"));
				data.setRole(rs.getString("ROLE"));
				datas.add(data);
			}
		} catch (SQLException e) {
			System.out.println("SQLException: " + e.getMessage());
			datas.clear();
		}
		return datas;
	}
	public MemberDTO selectOne(MemberDTO memberDTO) {
		return  null;
	}
	public boolean insert(MemberDTO memberDTO) {
		Connection conn=JDBCUtil.connect();
		PreparedStatement pstmt=null;
		try {
			pstmt=conn.prepareStatement(INSERT);
			pstmt.setString(1, memberDTO.getMid());
			pstmt.setString(2, memberDTO.getPassword());
			pstmt.setString(3, memberDTO.getName());
			pstmt.setString(4, memberDTO.getRole());
			int result=pstmt.executeUpdate();
			if(result<=0) {
				return false;
			}
		} catch (SQLException e) {
			System.out.println("SQL문 실패");
			return false;
		}
		JDBCUtil.disconnect(pstmt,conn);
		return true;
	}
	public boolean update(MemberDTO memberDTO) {
		return false;
	}
	public boolean delete(MemberDTO memberDTO) {
		return false;
	}
}

 

이제 Client에서 호출해서 syso(sout)해보면 바로 나올 것 같지만 한 군데 더 확인해줘야한다.

바로 어노테이션 범위 지정 부분이다. 현재 GenericXmlApplicationContext컨테이너를 생성해 사용하고 있으므로 해당 컨테이너 xml에서 어노테이션을 제대로 확인하고 있는지 범위를 확인해야한다.

 

확인해보니 수업 때 작성한대로 member 패키지만 확인하도록 되어있어 범위를 확장했다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
						http://www.springframework.org/schema/beans/spring-beans.xsd
						http://www.springframework.org/schema/context
						http://www.springframework.org/schema/context/spring-context-4.2.xsd">
	
	<context:component-scan base-package="com.koreait.app.biz" />
</beans>

 

 

이제 Client에서 호출해서 확인하면..

public class Client {
	public static void main(String[] args) {
		AbstractApplicationContext factory = new GenericXmlApplicationContext("applicationContext.xml");
		// 컨테이너를 구동시키는 코드
		
		MemberService ms = (MemberService)factory.getBean("memberService");
		System.out.println(ms.selectAll(null));

		BoardService bs = (BoardService)factory.getBean("boardService");
		System.out.println(bs.selectAll(null));
				
		factory.close();
	}
}

 

정상출력을 확인할 수 있다.

이 때 원래 DTO객체를 new해서 보냈었는데,, 이 부분도 new를 제거하는 방법을 배우게 될 것 같다.

(board 테이블 데이터는 비어있는 상태라서 출력되지 않았다. (전의 수업 JDBC코드 가져온 거라 로그 추가는 생략했다))