학원/SPRING

12/15 65-1 [SPRING] 주말에 할 것 +delete/edit

도원결의 2022. 12. 15. 19:26

어제 내가 놓친 거
글에 따른 댓글목록을 가져와야했음
특정 no 에서(부모)
linecomments를 뿌려야함(자식)
그래서 
부모dto에  List<LineCommentDTO> comments;
를 추가한거
그리고 그거 연결한게 resultmap 을 쓴 거임!

이건 아직 이해 잘 못함 이거도 주말로 ....

어제못한거 
남의 글은 수정하지 못 하게 막기!!

이거 view 에서 밑에 스크립문에서

동적으로 처리해야함... ajax를 써야 한다는말임.... 하놔

//※댓글 목록의 제목 클릭시-click이벤트걸때 반드시  $(document).on('이벤트명','셀렉터',콜백함수)으로
	//그래야 동적으로 추가된 요소에도 이벤트가 발생한다
	$(document).on('click','.line-comment',function(){
		//먼저 각 댓글 작성자의 아이디를 Ajax로 가져온다. 
		console.log('댓글번호:',$(this).attr('title'));
		var this_= $(this); //클릭한 제이쿼리 객체
		
		$.ajax({
			url:"<c:url value="/onememo/comments/GetId.do"/>",
			data:"lno="+this_.attr('title')
			
		}).done(function(data){
			
			console.log('댓글 작성자 아이디:',data);
			if('${sessionScope.id}'===data){//본인 댓글만 수정
				//입력상자값을 클릭한 제목으로 변경
				$('#linecomment').val(this_.html());
				//버튼의 텍스트를 수정으로 변경
				$('#submit').val('수정');
				//폼의 hidden인 lno의 value를 클릭한 제목의 lno값으로 설정
				$('input[name=lno]').val(this_.attr('title'));
				console.log('히든값 설정 확인(lno):',$('input[name=lno]').val());
			}
		}).fail(function(error){
			console.log('아이디 찾기 오류:',error);
		});
		
	});

얘는..... 주말에 진짜 열심히공부해보자

이거 뭔지를 모르니까 오류를 잡을 수가 없음....


[delete] 게시판글 삭제하기!

다른게시판과 다르게 까다로움

왜냐면 댓글이라는  자식이 참조하고 있기 때문임!!!

그래도 로직은 똑같으니까 우선 해보자

 

뷰(views) -> 컨트롤러(.web) -> 서비스(impl) -> DAO (.mapper : 쿼리문작성하는 .xml)

 

1.뷰(views)

뷰는 view.jsp 에 있으니까 따로 안만들어도 됨 그거 참면 되지만

아무나 삭제하게 하면 또 안되니까

문 추가 해 주자

<c:if test="${sessionScope.id==record.id}" var="isWriter">
    <a href="<c:url value="/onememo/bbs/Edit.do?no=${record.no}"/>" class="btn btn-success">수정</a>
    <a href="javascript:isDelete(${record.no})" class="btn btn-success">삭제</a>
</c:if>

 

그리고 삭제 전에 한 번 더묻는 알림을 띄울거라스크립트태그에 코드 추가

function isDelete(no){
    if(confirm("삭제 하실꺼??")){
        location.replace("<c:url value="/onememo/bbs/Delete.do?no="/>"+no);
    }		
}

 

2.컨트롤러(.web)

MemoController.java

이젠 안적어도 되겠지 .. 기존꺼 로직은 생략하고 삭제관련된 코드만.....

@SessionAttributes("id")   //로그인 되어있는 사람만 들어오기!!!!
@Controller
@RequestMapping("/onememo/bbs")
public class MemoController {
	@Autowired
	private OneMemoService<OneMemoDTO> memoService;
	
    //삭제
	@GetMapping("/Delete.do")
	public String delete(@ModelAttribute("id") String id,@RequestParam Map map){
		//서비스호출
		memoService.delete(map);
		//뷰정보 반환
		return "forward:/onememo/bbs/List.do";
	}
}

 

3.서비스(impl)

여기서 로직처리

삭제할 때는 트랜젝션 처리가 필요하다!

만약

댓글(자식) 을 다 삭제 했는데도
부모가 어떤 이유에서든 삭제가 안된다면 다시 다 돌려놔야하니까 !!

 

트랜젝션 쓰려면  관련 빈 등록 하면 됨 
등록은 databaseConfig 에다가 추가 !!

이거 이제주입해서 쓰면 된다

	//트랜젝션 관련 빈 등록
	@Bean
	public DataSourceTransactionManager transactionManager(HikariDataSource hikariDataSource) {
		return new DataSourceTransactionManager(hikariDataSource);	
	} 
	
	@Bean
	public TransactionTemplate transactionTemplate(DataSourceTransactionManager transactionManager ) {
		TransactionTemplate  transactionTemplate=new TransactionTemplate(); 
		transactionTemplate.setTransactionManager(transactionManager);
		return transactionTemplate;
	}

 

 //https://mybatis.org/spring/transactions.html
 [삭제 작업을 트랜잭션 처리하기]
 1.빈 설정파일(root-context.xml)에 DataSourceTransactionManager 등록
 2.빈 설정파일(root-context.xml)에 TransactionTemplate 등록
 3.TransactionTemplate 주입받는다
 4.TransactionTemplate객체의 execute()메소드로 트랜잭션 작업 실행
   You can omit to call the commit and rollback method using the TransactionTemplate.

 ※트랜잭션 작업에서 런타임 오류 시 롤백,정상 실행 시 커밋된다
  트랜잭션 처리는 @Service어노테이션이 붙은 클래스에서 하자

방법은 2가지

타입파라미터 사용하거나 람다함수 사용하거나 !!

@Service("memoService")
public class OneMemoServiceImpl implements OneMemoService<OneMemoDTO> {

	@Autowired
	private OneMemoDAO dao;


	트랜젝션 처리 관련 빈 주입 받기
	@Autowired
	private TransactionTemplate transactionTemplate;
	@Autowired
	private LineCommentDAO ldao;  //글번호에 따른 댓글삭제용 dao 주입받기

	@Override
	public int delete(Map map) {
		int affected=0; //삭제 된 댓글의 총 수 저장용
	
	
    
    [타입파라미터 <T> : 트랜젝션 처리 작업 후 반환 할 타입으로 지정]
	affected = transactionTemplate.execute(new TransactionCallback<Integer>() {

            @Override  //여기 매소드에서 트랜젝션 처리함(작업들 기술하는 메소드!)
            public Integer doInTransaction(TransactionStatus status) {

                //글 번호에 따른 모든 댓글 삭제
                int deletedCommentCount=ldao.deleteByNo(map);				
                //해당 원본 글 삭제
                dao.delete(map);
                //doInTransactiond의 반환 값이 execute메소드의 반환 값이다.
                return deletedCommentCount;
                }					
	   });
		
  
		[이번엔 람다함수 사용(추상 메소드라 1개라서 가능)]
		affected = transactionTemplate.execute(status->{
			int deletedCommentCount=ldao.deleteByNo(map);
			dao.delete(map);
			return deletedCommentCount;
		});							
		return affected ;
	}

주말에 람다도 공부해야 하나... 하...

 

 4.DAO (.mapper : 쿼리문작성하는 .xml)

서비스단에서나 복잡하지

나머지는 간단간단

@Repository
public class OneMemoDAO {	 
	public int delete(Map map) {		
		return template.delete("memoDelete",map);
     }
}

+ 쿼리문 작성

<delete id="memoDelete" parameterType="Map">
    DELETE onememo WHERE no=#{no}
</delete>

 


[edit]  - 수정하기

 

1.뷰

edit.jsp

이것은 문제였음 

뷰에 hidden 속성넣는 걸 못했음 

부들부들

Write.jsp를 복붙  -> 등록버튼을 수정으로 변경 ->

그리고 !!!!

<input type="hidden" name="no" value="${record.no }"/> 

이걸  추가아아아아!!!!

	<c:if test="${! empty InputError}">
	<div class="alert alert-success alert-dismissible fade show">
		  <button type="button" class="close" data-dismiss="alert">&times;</button>
		  <strong>Failure!</strong> ${InputError}
		</div>
	</c:if>
	<form method="post" action="<c:url value="/onememo/bbs/Edit.do"/>">
	<input type="hidden" name="no" value="${record.no }"/>
	<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
      <div class="form-group">
        <label><kbd class="lead">제목</kbd></label>
        <input type="text" value="${record.title}" class="form-control" placeholder="제목을 입력하세요" name="title">
      </div>
      <div class="form-group">
		<label><kbd class="lead">내용</kbd></label>
		<textarea class="form-control" rows="5" name="content">${record.content}</textarea>
	  </div>
      <button type="submit" class="btn btn-primary">수정</button>
    </form>

 

2.컨트롤러

MemoController.java

@SessionAttributes("id")   //로그인 되어있는 사람만 들어오기!!!!
@Controller
@RequestMapping("/onememo/bbs")
public class MemoController {
    @Autowired
    private OneMemoService<OneMemoDTO> memoService;
    
	//수정폼으로 이동
    @GetMapping("/Edit.do")
    public String Edit(@ModelAttribute("id") String id,Model model,@RequestParam Map map) {
        //서비스 호출		
        OneMemoDTO record=memoService.selectOne(map);
        //데이터저장
        model.addAttribute("record",record);	
        //뷰정보반환
        return "onememo10/bbs/Edit";
    }
		//수정처리	
    @PostMapping("/Edit.do")
    public String Editok(
            @ModelAttribute("id") String id,
            @RequestParam Map map
            ) {
        //서비스 호출
        memoService.update(map);	
        //뷰정보반환  forward: 안붙이면 앞뒤로  /WEB-INF/views 랑jsp가 붙음
        return "forward:/onememo/bbs/View.do";
    }
 }

 

3.서비스

@Service("memoService")
public class OneMemoServiceImpl implements OneMemoService<OneMemoDTO> {

	//OneMemoDAO주입받는다
	@Autowired
	private OneMemoDAO dao;
	
    @Override
	public int update(Map map) {		
		return dao.update(map);
	}
}

 

4.DAO+쿼리문

@Repository
public class OneMemoDAO {	
	public int update(Map map) {
	return template.update("momoUpdate",map);
	}
}

+쿼리

<update id="momoUpdate" parameterType="Map">
    UPDATE onememo SET title=#{title},content=#{content} WHERE no=#{no}
</update>