본문 바로가기
BackEnd/Spring

스프링 4일차(CRUD_입력, 수정, 삭제, 조회)

by JaeHa.K 2021. 8. 26.
728x90

지난 스프링 3일차에서는 Spring에서 MariaDB와 연결시켜 데이터를 리스트로 쫙 뽑아오는 것을 했습니다.

오늘은 DataBase의 기본인 DML(Data Manipulation Language)를 해보겠습니다.

원리는 3일차에 배웠던 것과 동일했습니다.

 

User -> Controller -> Service -> DAO -> DB순으로 신호를 보내고,

역순으로 DB -> DAO -> Service -> Controller -> User순으로 신호를 받아온다.

(신호를 보내고, 받는 순간은 찰나이지만 그 찰나의 순간동안 정말 많이 왔다갔다 하는 것이 신기하다.)

 

 

 

1. TestController

(파일명이 익숙치 않거나 잘 이해가 되지 않는다면 스프링 3일차를 참고하면 좋을 듯 싶습니다.)

@Controller
public class TestController {
	@Autowired
	private TestService testService;
	
    /********************* 입력(Insert) ***********************/
    // GetMapping은 글쓰기 위한 write.jsp에 접근 했을때
	@GetMapping("/write")
	public String write() {
		return "write";
	}
    // PostMapping은 글쓰기 완료후 DB로 값을 보내 저장시키기 위해 접근 했을때
	@PostMapping("/write")
	public String write2(TestDTO testDTO) {
		//no 넣어주기(no는 사용자 ID를 갖고 오기 위함_아직 로그인 기능이 없어 세션값 대신 지정값으로 설정)
		testDTO.setNo(9);
		testService.write(testDTO);
        
		return "redirect:/board";
	}
	
    /********************* 조회(Select) ***********************/
	@GetMapping("/detail")
	public ModelAndView detail(@RequestParam("bno") int bno) {
		TestDTO dto = testService.detail(bno);
		ModelAndView mv = new ModelAndView("detail");
		mv.addObject("dto", dto);
        
		return mv;
	}
	
    /********************* 삭제(Delete) ***********************/
	@GetMapping("/delete")
	public String delete(@RequestParam("bno") int bno) {
		testService.delete(bno);
        
		return "redirect:/board?success="+bno;
	}
	
    /********************* 수정(Update) ***********************/
    // GetMapping은 detail.jsp에서 수정하기 위해 update.jsp로 접근 했을때
	@GetMapping("/update")
	public ModelAndView update(HttpServletRequest request) {
		ModelAndView mv = new ModelAndView("update");
		// 글 번호 가져오기
		int bno = Integer.parseInt(request.getParameter("bno"));
		TestDTO dto = testService.detail(bno);
		mv.addObject("dto", dto);
        
		return mv;
	}
    // PostMapping은 update.jsp에서 글수정 완료 후 DB로 값을 보내 저장시키기 위해 접근 했을때
	@PostMapping("/update")
	public String updateDetail(TestDTO testDTO) {
		testService.update(testDTO);
		return "redirect:/detail?bno=" + testDTO.getBno() + "&&success=1";
	}
}

delete와 update에 success라는 파라미터를 추가시킨 이유는 사용자가 글을 삭제 했을 때와 수정했을 때, 자신이 수정 또는 삭제 했음을 사용자에게 알려주기 위한 작업을 하기 위해 추가 시켰습니다.

 

 

2. TestService

@Service
public class TestService {
	@Autowired
	private TestDAO testDAO;

	public void write(TestDTO testDTO) {
		testDAO.write(testDTO);
	}

	public TestDTO detail(int bno) {
		return testDAO.detail(bno);
	}

	public void delete(int bno) {
		testDAO.delete(bno);
	}

	public void update(TestDTO testDTO) {
		testDAO.update(testDTO);
	}
}

코드량이 대폭 감소한 느낌이다. 한번 설정해주고 나니 넘나 편한 것~

여기서는 Controller에서 보낸 값을 잡아 DAO로 날라갑니다.

 

 

3. TestDAO

@Repository
public class TestDAO {
	@Autowired
	private SqlSession sqlSession;

	public void write(TestDTO testDTO) {
		sqlSession.insert("test.write", testDTO);
	}

	public TestDTO detail(int bno) {
		return sqlSession.selectOne("test.detail", bno);
	}

	public void delete(int bno) {
		sqlSession.delete("test.delete", bno);
	}

	public void update(TestDTO testDTO) {
		sqlSession.update("test.update", testDTO);
	}
}

조회와 삭제, 그리고 수정을 할 때는 해당 글의 정보 즉, 글 번호를 갖고 있어야 사용자가 원하는 글을 수정하고, 삭제하고, 조회할 수 있을 것입니다. Controller에서부터 쭉 보면 bno라는 파라미터값을 갖고 이동하고 있는 모습을 발견할 수 있습니다.(bno는 데이터베이스상에서 게시글에 부여된 고유 번호라고 보면 된다.)

 

 

4. testMapper

<mapper namespace="test">
	<insert id="write" parameterType="TestDTO">
		INSERT INTO board (btitle, bcontent, no) VALUES (#{btitle }, #{bcontent }, #{no })	
	</insert>
	
	<select id="detail" parameterType="integer" resultType="TestDTO">
		SELECT * FROM boardview where bno=#{bno}
	</select>
	
	<delete id="delete" parameterType="integer">
		DELETE FROM board WHERE bno=#{bno}
	</delete>

	<update id="update" parameterType="TestDTO">
		UPDATE board SET btitle=#{btitle}, bcontent=#{bcontent} WHERE bno=#{bno}
	</update>
</mapper>

(우리는 지난번 시간에 mybatisConfig라는 파일에 java.lang.Integer와 com.ramg.web.TestDTO를 각각 integer와 TestDTO로 사용한다고 mybatis에 등록을 시켜줬었습니다. 그렇기 때문에 parameterType과 resultType에서 등록된 객치명을 사용할 수 있습니다.)

 

여기까지 흐름도를 살펴보면 아래와 같습니다.

User -> Controller -> Service -> DAO(-> testMapper -> mybatis -> mybatisConfig) -> DB

1. 사용자가 요청을 하면 Controller 는 요청받은 값을 저장시켜 Service 에게 명령을 보냅니다.

2. Service 는 DAO로 가기전 Controller 에서 받은 내용을 정리해서, 해당되는 DAO로 연결시켜줍니다.

3. DAO에서는 Mapper와 통신하여 DB에 명령을 보냅니다.

4. 이 모든 작업이 끝난 후 Controller가 return하여 사용자에게 전달하는 구조입니다.

 

 

별첨. 수정과 삭제했을 때 JS로 사용자에게 알려주기

사실 기능이 완벽하게 작동되면 끝이긴 하지만, '궁극적으로 이 서비스는 사용자를 위한 서비스이다' 라는 관점에서 간단한 기능을 추가해봤습니다.

게시글을 삭제한 후 다시 board.jsp로 돌아가게 되는데 이 때 JS로 파라미터값을 조회했을 때 success라는 파라미터가 있다면 "OO번 글이 정상적으로 삭제되었습니다."라는 메세지를 보여주는 방식입니다.

 

 

board.jsp

<script>
$(function(){
	var success = ${param.success}
	if(success != null && success != "" && success > 0){
		alert(success + "번 글이 정상적으로 삭제되었습니다.");
	};
	history.replaceState({}, null, location.pathname);
});
</script>

게시글을 수정했을 때도 마찬가지입니다. 정상적으로 수정을 했다면 detail.jsp로 넘어가게 될 것입니다.

그때 detail.jsp에서 JS로 수정한 이력이 있는지 확인하는 기능만 추가하면 됩니다.

 

 

detail.jsp

<script>
$(function(){
	var success = ${param.success}
	var bno = ${param.bno}
	if(bno != null && bno != "" && bno > 0 && success == 1){
		alert(bno + "번 글이 정상적으로 수정되었습니다.");
	};
	history.replaceState({}, null, location.pathname);
});
</script>

(참고로 파라미터를 잡을 때는 JSTL을 사용했습니다!)

 

마지막에 파라미터를 초기화 해줌으로써 새로고침을 했을 때 반복적으로 메세지를 보여주는 오류를 잡을 수 있겠죠?😋

 

- 결과화면 -

 

삭제 후 board.jsp
메세지 확인 후 URL창, 파라미터가 없어졌쥬?

 

이런식으로 하면 확실히 사용자도 시각적으로 내가 삭제했다는 인식을 갖을 수 있게 되겠죠?ㅎㅎ

반응형