'삭제'에 해당되는 글 2건

  1. 2019.07.04 게시판 만들기 (게시물 수정, 파일 첨부, 첨부파일 삭제, 게시물 삭제)
  2. 2019.06.14 상품관리 (장바구니 기능구현 - 삭제, 비우기, 수정) 3

게시판 만들기 (게시물 수정, 파일 첨부, 첨부파일 삭제, 게시물 삭제)

Back-End/Spring 2019. 7. 4. 18:19
728x90
반응형

첨부파일이 저장되는 테이블을 작성



테이블이 중복될수 있으므로 테이블과 테이블에 관련된 제약조건을 삭제

1
drop table attach cascade constraints;
cs


테이블 생성
1
2
3
4
5
6
create table attach (
    fullName varchar2(150not null, //첨부파일 이름, null값 방지, 파일이름은 uuid를 이용해서 중복되지 않도록 할 예정
    bno number not null, //게시글 번호, null값 방지
    regdate date default sysdate, //등록날짜, 현재시간으로 설정
    primary key(fullName) //기본키를 첨부파일이름으로 설정
);
cs



attach테이블의 bno 속성(글번호)이 board테이블에 bno 속성 (글번호)를 참조하도록 외래키로 설정함. (제약조건 설정)

(게시글 번호가 꼬이면 안되기 때문, 게시글이 삭제되면 같이 삭제될수 있게끔...)

1
2
alter table attach add constraint fk_board_attach //fk_board_attach는 제약조건의 이름
foreign key (bno) references board(bno);
cs



중복될 수 있으므로 먼저 시퀀스를 삭제

1
drop sequence seq_board;
cs



board 테이블의 bno 컬럼을 위한 시퀀스를 생성

1
2
3
create sequence seq_board
start with 1 //시작값을 1로하고
increment by 1; //1씩 증가하도록 설정함
cs



===============================================================================================



view.jsp 페이지에서 common.js를 include 해야한다.

1
<script src="${path}/include/js/common.js"></script>
cs



view.jsp 중 일부

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$(".fileDrop").on("dragenter dragover",function(e){
        //기본 효과 막음, 기본효과가 있으면 이미지 파일이 실행되어 버림
        e.preventDefault();
    });
    $(".fileDrop").on("drop",function(e){
        e.preventDefault();
        //첫번째 첨부파일
//드롭한 파일을 폼 데이터에 추가함
        var files=e.originalEvent.dataTransfer.files;
        var file=files[0];
        //폼 데이터에 첨부파일 추가 (0번 인덱스이므로 첫번째 파일만 붙였다.)
        var formData=new FormData();
        formData.append("file",file);
        $.ajax({ //비동기 방식으로 호출
            url: "${path}/upload/uploadAjax"// uploadAjax를 호출함
            data: formData,  // formData를 보내고                   
            dataType: "text", // text 타입으로 보낸다.
            processData: false, // 요청으로 보낸 데이터를 query string 형태로 변환할지 여부
            contentType: false, // 서버로 보내지는 데이터의 기본값
            type: "post",
//호출처리가 완료된 다음 (성공한 후)에 실행되는 구문
//컨트롤러에서 업로드 경로와 상태코드 (200)을 리턴해서 이쪽으로 보낸다.
            success: function(data){ //콜백 함수
                //console.log(data);
                //data : 업로드한 파일 정보와 Http 상태 코드
                var fileInfo=getFileInfo(data); //첨부파일의 정보
                //console.log(fileInfo);
                var html="<a href='"+fileInfo.getLink+"'>"+
                    fileInfo.fileName+"</a><br>";
                html += "<input type='hidden' class='file' value='"
                    +fileInfo.fullName+"'>"; //hidden 태그를 추가
                $("#uploadedList").append(html); //div에 추가
            }
        });
    });
cs




AjaxUploadController.java

1
2
3
4
5
6
7
8
9
10
    // 업로드한 파일은 MultipartFile 변수에 저장됨
    @ResponseBody // json 형식으로 리턴
    @RequestMapping(value = "/upload/uploadAjax"
    method = RequestMethod.POST, produces = "text/plain;charset=utf-8")
    public ResponseEntity<String> uploadAjax(MultipartFile file) throws Exception {
       //파일의 정보를 로그에 출력
logger.info("originaName:"
+file.getOriginalfilename());
logger.info("size:" +file.getSize());
logger.info("contentType:" +file.getContentType());
//new ResponseEntity (데이터, 상태코드)
//new ResponseEntity (업로드된 파일이름, 상태코드)

        return new ResponseEntity<String>(
                UploadFileUtils.uploadFile(uploadPath, file.getOriginalFilename(), file.getBytes()), HttpStatus.OK);
    }
 
cs



view.jsp 중 일부

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//목록 버튼
    $("#btnList").click(function(){
        location.href="${path}/board/list.do";
    });
    
    //수정 버튼
    $("#btnUpdate").click(function(){
        //첨부파일 이름들을 폼에 추가
        var str="";
        //id가 uploadList인것들 (div)에 클래스에 file인것 각각 (each) 
        $("#uploadedList .file").each(function(i){
            
            str+="<input type='hidden' name='files["+i+"]' value='"
                +$(this).val()+"'>";
                //파일이름에다 인덱스 번호를 하나씩 붙인다.
        });
        
        //폼에 hidden 태그들을 추가함
        $("#form1").append(str);
        
        document.form1.action="${path}/board/update.do"//위에서 만든 폼을 가지고 update.do로 보낸다.
        document.form1.submit();
    });
cs


 

지금까지 보낸 내용들이 dto안에 다 쌓인다.


BoardServiceImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package com.example.spring02.service.board;
 
import java.util.List;
 
import javax.inject.Inject;
import javax.servlet.http.HttpSession;
 
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import com.example.spring02.model.board.dao.BoardDAO;
import com.example.spring02.model.board.dto.BoardDTO;
 
@Service // service bean
public class BoardServiceImpl implements BoardService {
 
    @Inject //dao를 호출하기 때문에 의존성을 주입
    BoardDAO boardDao; 
 
    //첨부파일 레코드 삭제
    @Override
    public void deleteFile(String fullName) {
        boardDao.deleteFile(fullName); 
    }
 
    @Override
    public List<String> getAttach(int bno) {
        return boardDao.getAttach(bno);  
    }
    
    // 1.글쓰기 - 게시물 번호 생성
    
    // 2.첨부파일 등록-게시물 번호 사용
    
    @Transactional
    @Override
    public void create(BoardDTO dto) throws Exception {
        //board 테이블에 레코드 추가
        boardDao.create(dto); 
        //attach 테이블에 레코드 추가
        String[] files=dto.getFiles(); //첨부파일 이름 배열
        if(files==nullreturn;  //첨부파일이 없으면 skip
        for(String name : files) {
            boardDao.addAttach(name);  //attach 테이블에 insert
        }
    }
 
    @Override
    public BoardDTO read(int bno) throws Exception {
        return boardDao.read(bno);
    }
 
    @Transactional //트랜잭션 처리 method
    //코드 수정과 첨부파일을 첨부하는 기능이 동시에 같이 들어가야하기 때문에
//일관성을 유지하기 위해서 트랜잭션 처리를 실시한다.
//만약 두개중에 하나라도 되지않으면 작업을 취소시키기고, 롤백을 한다.
    @Override
    public void update(BoardDTO dto) throws Exception {
        boardDao.update(dto); //board 테이블 수정
        //attach 테이블 수정
        String[] files=dto.getFiles();
        if(files==nullreturn;
        for(String name : files) {
            System.out.println("첨부파일 이름:"+name);
            boardDao.updateAttach(name, dto.getBno()); 
        }
    }
 
    @Transactional
    @Override
    public void delete(int bno) throws Exception {
        //reply 레코드 삭제
        //attach 레코드 삭제
        //첨부파일 삭제
        //board 레코드 삭제
        boardDao.delete(bno); 
    }
 
    @Override
    public List<BoardDTO> listAll(
            //매개변수는 시작 레코드번호, 끝번호, 옵션과 키워드가 들어간다
String search_option, String keyword,int start, int end)
            throws Exception {
        return boardDao.listAll(search_option,keyword,start,end); 
    }
    
//조회수 증가 처리
    @Override
    public void increaseViewcnt(int bno, HttpSession session) 
            throws Exception {
        long update_time=0;
        if(session.getAttribute("update_time_"+bno)!=null) {
            //최근에 조회수를 올린 시간
            update_time=
                    (long)session.getAttribute("update_time_"+bno);
        }
        long current_time=System.currentTimeMillis();
        //일정 시간이 경과한 후 조회수 증가 처리
        if(current_time - update_time > 5*1000) {
            //조회수 증가 처리
            boardDao.increateViewcnt(bno);
            //조회수를 올린 시간 저장
            session.setAttribute("update_time_"+bno, current_time);
        }
    }
 
    @Override
    public int countArticle(
            String search_option, String keyword) throws Exception {
        return boardDao.countArticle(search_option,keyword); 
    }
cs



BoardDAOImpl.java

1
2
3
4
5
6
7
8
9
//첨부파일 정보 수정
    @Override
    public void updateAttach(String fullName, int bno) {
        Map<String,Object> map=new HashMap<>(); //값을 여러개 담을때는 haspmap를 사용한다.
        map.put("fullName", fullName); //첨부파일 이름
        map.put("bno", bno); //게시물 번호
        sqlSession.insert("board.updateAttach"map); //updateAttach mapper을 호출
    }
 
cs



boardMapper.xml

1
2
3
4
5
6
7
<!-- 다른 mapper와 중복되지 않도록 네임스페이스 기재 -->
<mapper namespace="board">
<!-- 새로운 첨부파일 추가 -->    
    <insert id="updateAttach">
//attach테이블에 입력받은 파일이름과 게시글 번호를 삽입한다
        insert into attach (fullName, bno) values
        ( #{fullName}, #{bno} )
    </insert>
cs



BoardDAOImpl.java

1
2
3
4
5
    //레코드 수정    
    @Override
    public void update(BoardDTO dto) throws Exception {
        sqlSession.update("board.update"dto); 
    }
cs



boardMapper.xml                                                                                                                                                                            

1
2
3
4
5
6
<mapper namespace="board">
<!-- 게시물 내용 수정 -->
    <update id="update">
//게시글의 내용 수정, 게시글 번호가 맞으면 제목과 내용을 입력한 대로 수정해서 갱신함
        update board
        set title=#{title}, content=#{content}
        where bno=#{bno}
    </update>
cs



view.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
listAttach();
 
//첨부파일 리스트를 출력하는 함수
function listAttach(){
    $.ajax({
        type: "post",
        url: "${path}/board/getAttach/${dto.bno}",
        success: function(list){
            // list : json
            //console.log(list);
            $(list).each(function(){
                var fileInfo=getFileInfo(this);
                //console.log(fileInfo);
                var html="<div><a href='"+fileInfo.getLink+"'>"
                    +fileInfo.fileName+"</a>&nbsp;&nbsp;";
                <c:if test="${sessionScope.userid == dto.writer}">    
                    html+="<a href='#' class='file_del' data-src='"
                        +this+"'>[삭제]</a></div>";
                </c:if>
                $("#uploadedList").append(html);
            });
        }
    });
}
cs



BoardController.java 중 일부

1
2
3
4
5
6
7
8
9
    
    //첨부파일 목록을 리턴
    //ArrayList를 json 배열로 변환하여 리턴
    //view에서 넘긴 bon를 경로값 (url에 포함된 변수)로 받아서 맵핑한다.
    @RequestMapping("getAttach/{bno}")
    @ResponseBody //view가 아닌 데이터 자체를 리턴할 때 사용하는 어노테이션
//(즉, 화면이 바뀌는게 아니라 데이터가 넘어간다는 의미.. 리턴한 값)
    public List<String> getAttach(@PathVariable("bno") int bno){
        return boardService.getAttach(bno);
    }


cs



BoardServiceImpl.java 중 일부

1
2
3
4
    @Override
    public List<String> getAttach(int bno) {
        return boardDao.getAttach(bno);  
    }
cs



BoardDAOImpl.java 중 일부

1
2
3
4
5
    //첨부파일 리스트
    @Override
    public List<String> getAttach(int bno) {
        return sqlSession.selectList("board.getAttach", bno); 
    }
cs



boardMapper.xml 중 일부

1
2
3
4
5
6
7
8
<!-- 다른 mapper와 중복되지 않도록 네임스페이스 기재 -->    
<mapper namespace="board">

<!-- 첨부파일 목록 -->
    <select id="getAttach"  resultType="String"> //결과타입은 필드가 1개이므로 String이다.
        select fullName //attach 테이블에서 첨부파일이름을 검색 (단, 글번호가 내가 선택한 글번호여야됨)
//그리고 날짜의 내림차순으로 정렬시킨다.
        from attach
        where bno=#{bno}
        order by regdate desc    
    </select>
 
cs



여기서 검색한 결과값이 컨트롤러로 넘어간다.




============================첨부 파일 삭제=============================================



view.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//첨부파일 리스트를 출력하는 함수
function listAttach(){
    $.ajax({
        type: "post",
        url: "${path}/board/getAttach/${dto.bno}"
        //getAttach(파일얻을때) 게시글 번호를 보냄
        //컨트롤러로 이동
        //위의 구문이 처리가 정상적으로 처리되었을때 실행되는 구문 (success)
        //list는 배열
BoardController.java
1
2
3
4
5
6
7
8
    //첨부파일 목록을 리턴
    //ArrayList를 json 배열로 변환하여 리턴
    //view에서 넘긴 bon를 경로값 (url에 포함된 변수)로 받아서 맵핑한다.
    @RequestMapping("getAttach/{bno}")
    @ResponseBody // view가 아닌 데이터 자체를 리턴 
    public List<String> getAttach(@PathVariable int bno){
        return boardService.getAttach(bno);
    }
cs


BoardServiceImpl.java

1
2
3
4
    @Override
    public List<String> getAttach(int bno) {
        return boardDao.getAttach(bno);  
    }
cs



BoardDAOImpl.java

1
2
3
4
5
//첨부파일 리스트
    @Override
    public List<String> getAttach(int bno) {
        return sqlSession.selectList("board.getAttach", bno); 
    }
cs



boardMapper.xml

1
2
3
4
5
6
7
8
9
10
<!-- 다른 mapper와 중복되지 않도록 네임스페이스 기재 -->
<mapper namespace="board">
 
<!-- 첨부파일 목록 -->
    <select id="getAttach"     resultType="String">
//attach테이블로부터 파일이름을 검색, (내가 원하는 글번호로), 작성날짜의 내림차순으로 검색
        select fullName 
        from attach
        where bno=#{bno}
        order by regdate desc    
    </select>
cs
        


success: function(list){
            // list : json
            //console.log(list);
            $(list).each(function(){
                //list 변수 각각에 대하여
                
                //현재 파일의 파일 정보
                var fileInfo=getFileInfo(this);
                //console.log(fileInfo);
                //파일정보를 보는 하이퍼링크를 만듦 (div에 하이퍼링크를 만듦)
                var html="<div><a href='"+fileInfo.getLink+"'>"
                    +fileInfo.fileName+"</a>&nbsp;&nbsp;";
                    
                    
                    
                    //------------파일 삭제-------------
                    //세션에 담긴 userid와 dto에 담긴 작성자가 같으면
                    //담아놓은 파일을 삭제하기 위해서 링크를 건다.
                <c:if test="${sessionScope.userid == dto.writer}">    
                    html+="<a href='#' class='file_del' data-src='"
                        +this+"'>[삭제]</a></div>";
                </c:if>
                //추가
                $("#uploadedList").append(html);
            });
        }
    });
}
cs



view.jsp (위쪽의 #uploadedList)와 연결되는 코드)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//첨부파일 삭제
    //id가 uploadedList인 태그의 class가 file_del인 태그 클릭
    $("#uploadedList").on("click",".file_del",function(e){
        var that=$(this); //클릭한 태그
//data: {fileName: $(this).attr("data-src") },        
        $.ajax({
            type: "post",
            url: "${path}/upload/deleteFile",

AjaxUploadController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@ResponseBody //뷰가 아닌 데이터를 리턴
    @RequestMapping(value="/upload/deleteFile"
        ,method=RequestMethod.POST)
    public ResponseEntity<String> deleteFile(String fileName){
        logger.info("fileName:"+fileName); 
        
        //fileName에는 이미지 파일의 경우 썸네일 파일 이름이 넘어옴
        String formatName=fileName.substring(
                fileName.lastIndexOf(".")+1); //확장자 검사
        
        
        MediaType mType=MediaUtils.getMediaType(formatName);
        if(mType != null) { //이미지 파일이면 원본이미지 삭제
            
            //파일이름의 앞부분과 확장자명을 분리하기 위한 코드
            String front=fileName.substring(012);
            String end=fileName.substring(14);
            
//         File.separatorChar : 유닉스 / 윈도우즈\    
            new File(uploadPath+(front+end).replace(
                    '/',File.separatorChar)).delete();  //썸네일 삭제
        }
        
        //원본 파일 삭제(이미지이면 썸네일 삭제)
        new File(uploadPath+fileName.replace(
                '/',File.separatorChar)).delete(); //파일 삭제
 
        //레코드 삭제
        boardService.deleteFile(fileName);


BoardService.java

1
2
3
4
5
//첨부파일 레코드 삭제
    @Override
    public void deleteFile(String fullName) {
        boardDao.deleteFile(fullName); 
    }
cs



BoardDAOImpl.java

1
2
3
4
5
//첨부파일 레코드 삭제    
    @Override
    public void deleteFile(String fullName) {
        sqlSession.delete("board.deleteAttach", fullName); 
    }
cs



boardMapper.xml

1
2
3
4
5
<!-- 첨부파일 레코드 삭제 -->
    <delete id="deleteAttach">
        delete from attach
        where fullName=#{fullName}
    </delete>
cs




        return new ResponseEntity<String>("deleted"
                ,HttpStatus.OK);
        //잘 삭제가 되었으면 deleted가 view로 넘어가고 상태메시지200을 리턴시킨다.
    }
}
cs




            
data: "fileName="+    $(this).attr("data-src"),        
            dataType: "text",
            
            //컨트롤러에서 삭제가 성공하면 결과값이 result로 넘어오고
            //result의 값이 deleted와 같으면 화면에서 div 태그를 제거한다.
            
            success: function(result){
                if(result=="deleted"){
//컨트롤러에서 넘어온 리턴값이 deleted면 첨부파일이 정상적으로 삭제되었다는 뜻이므로 밑의 구문을 생성
                    
                    //화면에서 태그 제거
                    
                    that.parent("div").remove();  
                    //that(this를 의미)의 클릭한 태그의 parent의 div를 삭제
                    //div태그를 삭제해야 파일에 관한 링크와 정보들이 삭제된다.
                }
            }
        });
    });
cs



첨부파일이 올라간 상태에서 글을 쓰고 확인을 누르면 mapper에서 id가 addAttach인 쿼리를 호출


파일업로드를 하게되면 트랜잭션 처리를 해야 된다.


왜냐하면 게시글이 올라가고, 파일도 등록되어야 하는데 (board 테이블에도 insert되어야 하고, attach테이블에도 insert되어야 한다)


그렇게 되어야 문제가 발생되지 않기 때문에, 둘 중에 하나만 된다면 롤백시켜야 한다.




===게시글을 작성시, 파일이 첨부되어야 하기 때문에 게시물 쓰기 코드에 트랜잭션을 처리하는 코드를 추가=====================



write.jsp 중 일부

1
2
3
<h2>글쓰기</h2>
<form id="form1" name="form1" method="post"
action="${path}/board/insert.do">

BoardController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// write.jsp에서 입력한 내용들이 BoardDTO에 저장됨    
    @RequestMapping("insert.do")
    public String insert(@ModelAttribute BoardDTO dto
            , HttpSession session) //세션은 아이디를 확인하기위해서 필요하므로 세션을 가져온다.
        throws Exception {
        
        // 로그인한 사용자의 아이디
        String writer=(String)session.getAttribute("userid");
        dto.setWriter(writer); //로그인한 아이디를 dto에 저장
 
        //레코드 저장
        boardService.create(dto); //서비스와 dao를 통해서 레코드에 추가가된다.
        
        //게시물 목록으로 이동
        return "redirect:/board/list.do";
    }
cs



BoardService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    // 1.글쓰기 - 게시물 번호 생성
    
    // 2.첨부파일 등록-게시물 번호 사용
    
    @Transactional //게시물 작성과 파일업로드가 둘다 완료가 된 상태에서만 글을 
                   //써야하기 때문에 트랜잭션 처리를 해주어야 한다.
    @Override
    public void create(BoardDTO dto) throws Exception {
        //board 테이블에 레코드 추가
        boardDao.create(dto); 
        //attach 테이블에 레코드 추가
        String[] files=dto.getFiles(); //첨부파일 이름 배열
        if(files==nullreturn;  //첨부파일이 없으면 skip
        for(String name : files) {
            boardDao.addAttach(name);  //attach 테이블에 insert
            //아직 글번호가 확정되지 않은 상태이기 때문에 (글번호는 작성을 해야 생기기때문) 글번호를 넣는
            //파일업로드는 게시글이 작성이 되지 않으면 업로드가 되지 않게 해야 에러가 발생되지 않는다.
        }
    }
cs



boardMapper.xml

1
2
3
4
5
    <!-- 첨부파일 정보 저장 -->    
    <insert id="addAttach">
//attach테이블에 파일이름 (입력받은 파일이름) 과, 게시글번호(게시판 테이블에 추가된 번호-방금추가된것)를 추가한다,
        insert into attach (fullName, bno) values
        ( #{fullName}, seq_board.currval ) //board.currval은 board의 시퀀스의 최종발급된 번호..
    </insert>
cs


cs



view.jsp에 삭제버튼을 추가하는 코드 추가

1
2
3
4
5
6
$("#btnDelete").click(function(){
    if(confirm("삭제하시겠습니까?")){
        document.form1.action = "${path}/board/delete.do";
        document.form1.submit();

BoardController.java

1
2
3
4
5
    @RequestMapping("delete.do")
    public String delete(int bno) throws Exception {
        boardService.delete(bno); //삭제 처리
        return "redirect:/board/list.do"; //목록으로 이동
    }
cs



BoardServiceImpl.java

1
2
3
4
5
6
7
8
9
10
11
@Transactional 
    //게시글 작성과 마찬가지로 게시글이 삭제될때 첨부파일도 같이 삭제되어야 하기 때문에 트랜잭션 처리를 해준다.
    @Override
    public void delete(int bno) throws Exception {
        //reply 레코드 삭제
        //attach 레코드 삭제
        //첨부파일 삭제
        //board 레코드 삭제
        boardDao.delete(bno); 
    }
 
cs



BoardDAOImpl.java

1
2
3
4
    @Override
    public void delete(int bno) throws Exception {
        sqlSession.delete("board.deleteArticle", bno); //mapper로 게시글 번호를 넘긴다. 
    }
cs



boardMapper.xml

1
2
3
4
<delete id="deleteArticle">
  delete from board where bno=#{bno} 
     </delete>
cs


    }
});
cs


728x90
반응형
:

상품관리 (장바구니 기능구현 - 삭제, 비우기, 수정)

Back-End/Spring 2019. 6. 14. 23:11
728x90
반응형

-장바구니 기능 구현-

 

 

데이터베이스에서 cart 테이블을 생성

1
2
3
4
5
6
create table cart(
cart_id number not null primary key, //cart_id를 null값이 오지못하게 하고 기본키로 설정함
userid varchar2(50not null, //userid를 null값이 오지못하게 설정
product_id number not null, //product_id를 null값이 오지못하게 설정
amount number default 0 //amount속성을 기본값을 0으로 설정
);
cs

 

 

cart테이블에 제약조건을 추가한다.

 

(cart테이블에 cart_userid_fk라는 이름의 제약조건을 cart테이블에 있는 userid에 추가하고,

 

userid를 다른 테이블의 기본키를 참조하는 외래키로 설정하고, member테이블의 userid를 참조하도록 설정한다.)

 

(즉, member테이블의 userid가 변경되면 cart테이블에 있는 userid도 같이 변경된다는 뜻이다.)

 

만약에 cart테이블에 "insert into cart values (2,'kim',2,10)" 쿼리를 실행시켰을 때, 

 

member테이블에 id (kim)이라는 id값이 없기 때문에 자료를 넣을 수 없어 오류가 발생한다.

 

즉, member 테이블에 존재하는 id값만 cart 테이블에 넣을 수 있다는 뜻이다.

 

(이렇게 하는 이유는 id값이 서로 일치하지 않아서 오류가 발생할 수 있기 때문에 제약조건을 설정하는 것이다.)

 

1
2
alter table cart add constraint cart_userid_fk
foreign key(userid) references member(userid);
cs
 
 
  
   아래 3개의 테이블을 참조해서 서로 join한다.


  select name, product_name,price,amount,price*amount money


  //회원의 이름과, 상품의 이름,물건 한개의 가격, 장바구니에 담은 개수, 총 물건의 가격을 검색한다.
 
  from member m, product p, cart c
 
  //member테이블과, product테이블과, cart테이블로부터 검색
 
  where m.userid=c.userid and p.product_id=c.product_id;
 
  //member의 userid와 cart의 userid가 같고, product의 product_id와 cart의 product_id가 같을때
  //즉, 회원의 아이디와 상품을 사려는 회원이 같고, 상품의 번호와 카트의 번호가 같을때 
 

 

 

 

장바구니 테이블을 만들었으므로 테이블에 있는 데이터를 저장할 클래스가 필요하다.

DTO 클래스를 생성

 

CartDTO.java (테이블 3개를 join할 것을 대비해서 필드와 getter, setter을 생성한다)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package com.example.spring02.model.shop.dto;
 
public class CartDTO {
    
    private int cart_id;
    private String userid;
    private String name;
    private int product_id;
    private String product_name;
    private int price;
    private int money;
    private int amount;
    
    public int getCart_id() {
        return cart_id;
    }
    public void setCart_id(int cart_id) {
        this.cart_id = cart_id;
    }
    public String getUserid() {
        return userid;
    }
    public void setUserid(String userid) {
        this.userid = userid;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getProduct_id() {
        return product_id;
    }
    public void setProduct_id(int product_id) {
        this.product_id = product_id;
    }
    public String getProduct_name() {
        return product_name;
    }
    public void setProduct_name(String product_name) {
        this.product_name = product_name;
    }
    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }
    public int getMoney() {
        return money;
    }
    public void setMoney(int money) {
        this.money = money;
    }
    public int getAmount() {
        return amount;
    }
    public void setAmount(int amount) {
        this.amount = amount;
    }
    
    @Override
    public String toString() {
        return "CartDTO [cart_id=" + cart_id + ", userid=" + userid + ", name=" + name + ", product_id=" + product_id
                + ", product_name=" + product_name + ", price=" + price + ", money=" + money + ", amount=" + amount + "]";
    }
    
}
 
cs

 

 

 

CartDAO 인터페이스를 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.example.spring02.model.shop.dao;
 
import java.util.List;
 
import com.example.spring02.model.shop.dto.CartDTO;
 
public interface CartDAO {
    List<CartDTO> cartMoney();
    void insert(CartDTO dto); //장바구니 추가
    List<CartDTO> listCart(String userid); //장바구니 목록
    void delete(int cart_id); //장바구니 개별 삭제
    void deleteAll(String userid); //장바구니 비우기
    void update(int cart_id); 
    int sumMoney(String userid); //장바구니 금액 합계
    int countCart(String userid, int product_id); //장바구니 상품 갯수
    void updateCart(CartDTO dto); //장바구니 수정 
    void modifyCart(CartDTO dto);
}
cs

 

 

 

CartDAOImpl.java (DAO 인터페이스 구현 클래스)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package com.example.spring02.model.shop.dao;
 
import java.util.List;
 
import javax.inject.Inject;
 
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
 
import com.example.spring02.model.shop.dto.CartDTO;
 
@Repository
public class CartDAOImpl implements CartDAO {
 
//MyBatis를 호출하므로 sqlsession에 의존성을 주입해야한다.
 
    @Inject
    SqlSession sqlSession;
    
    @Override
    public List<CartDTO> cartMoney() {
        // TODO Auto-generated method stub
        return null;
    }
    //장바구니에 담기
    @Override
    public void insert(CartDTO dto) {
//dto에 저장된 값을 받아서 sql세션에 저장하고 cart.insert로 넘어감 mapper로.
        sqlSession.insert("cart.insert", dto); 
    }
 
    @Override
    public List<CartDTO> listCart(String userid) {
        return sqlSession.selectList("cart.listCart", userid);
    }
 
    @Override
    public void delete(int cart_id) {
        sqlSession.delete("cart.delete", cart_id);
    }
 
    @Override
    public void deleteAll(String userid) {
        sqlSession.delete("cart.deleteAll", userid);
    }
 
    @Override
    public void update(int cart_id) {
        // TODO Auto-generated method stub
 
    }
 
    @Override
    public int sumMoney(String userid) {
        return sqlSession.selectOne("cart.sumMoney", userid); 
    }
 
    @Override
    public int countCart(String userid, int product_id) {
        // TODO Auto-generated method stub
        return 0;
    }
 
    @Override
    public void updateCart(CartDTO dto) {
        // TODO Auto-generated method stub
 
    }
 
    @Override
    public void modifyCart(CartDTO dto) {
        sqlSession.update("cart.modify", dto);
    }
 
}
 
cs

 

 

sql세션에 dto에서 받은 값을 저장한 다음 mapper로 넘어간다.

 

cartMapper.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
<!-- 다른 mapper와 중복되지 않도록 네임스페이스 기재 -->
<mapper namespace="cart">
<!-- 장바구니에 담기 -->
    <insert id="insert">
        insert into cart (cart_id, userid, product_id, amount)
        values 
          (seq_cart.nextval, #{userid}, #{product_id}, #{amount} )
 
//장바구니 담기 버튼을 누를때 실행되는 쿼리문
//cart_id와 userid, product_id, amount 값을 저장한다.
//cart_id는 하나씩 증가되어야하기때문에 시퀀스값으로 지정한다.
    </insert>
cs

 

 

CART 테이블에 시퀀스를 생성

 

(시퀀스를 생성하고 그 시퀀스의 시작값은 1로 하고 1씩 증가한다.)

1
2
3
create sequence seq_cart
start with 1
increment by 1;
cs

 

 

Service 생성

 

CartService.java (서비스 인터페이스 생성)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.example.spring02.service.shop;
 
import java.util.List;
 
import com.example.spring02.model.shop.dto.CartDTO;
 
public interface CartService {
    List<CartDTO> cartMoney();
    void insert(CartDTO dto);
    List<CartDTO> listCart(String userid);
    void delete(int cart_id);
    void deleteAll(String userid);
    void update(int cart_id);
    int sumMoney(String userid);
    int countCart(String userid, int product_id);
    void updateCart(CartDTO dto);
    void modifyCart(CartDTO dto);
}
cs

 

 

CartServiceImpl.java (서비스 인터페이스 구현 클래스 생성)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package com.example.spring02.service.shop;
 
import java.util.List;
 
import javax.inject.Inject;
 
import org.springframework.stereotype.Service;
 
import com.example.spring02.model.shop.dao.CartDAO;
import com.example.spring02.model.shop.dto.CartDTO;
 
@Service //Service 단이라는 것을 표시
public class CartServiceImpl implements CartService {
    
    @Inject //dao를 사용해야하기 때문에 @Inject로 의존성 부여
    CartDAO cartDao;
    
    @Override
    public List<CartDTO> cartMoney() {
        return null;
    }
    @Override
    public void insert(CartDTO dto) {
        cartDao.insert(dto);
    }
 
    @Override
    public List<CartDTO> listCart(String userid) {
        return cartDao.listCart(userid);
    }
 
    @Override
    public void delete(int cart_id) {
        cartDao.delete(cart_id);
    }
 
    @Override
    public void deleteAll(String userid) {
        cartDao.deleteAll(userid);
    }
 
    @Override
    public void update(int cart_id) {
        // TODO Auto-generated method stub
 
    }
 
    @Override
    public int sumMoney(String userid) {
        return cartDao.sumMoney(userid);
    }
 
    @Override
    public int countCart(String userid, int product_id) {
        // TODO Auto-generated method stub
        return 0;
    }
 
    @Override
    public void updateCart(CartDTO dto) {
        // TODO Auto-generated method stub
 
    }
 
    @Override
    public void modifyCart(CartDTO dto) {
        cartDao.modifyCart(dto);
    }
 
}
 
cs

 

 

 

CartController.java (장바구니 컨트롤러)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//컨트롤러에서 메소드의 파라미터들은 갯수제한이 없고, 순서가 상관이 없다.
    
    
    @RequestMapping("insert.do"//세부적인 url mapping
 
    public String insert(@ModelAttribute CartDTO dto, 
            HttpSession session) {
 
        //@ModelAttribute는 sumit된 form의 내용을 저장해서 전달받거나, 다시 뷰로 넘겨서 출력하기 위해 사용되는 오브젝트 이다.
 
        //도메인 오브젝트나 DTO의 프로퍼티에 요청 파라미터를 바인딩해서 한번에 받으면 @ModelAttribute 라고 볼 수 있다.
 
        //@ModelAttribute는 컨트롤러가 리턴하는 모델에 파라미터로 전달한 오브젝트를 자동으로 추가해준다.
        
        
        //로그인 여부를 체크하기 위해 세션에 저장된 아이디 확인
 
        String userid=(String)session.getAttribute("userid");
        if(userid==null) { 
 
//로그인하지 않은 상태이면 로그인 화면으로 이동
 
            return "redirect:/member/login.do";
        }
        dto.setUserid(userid);
        cartService.insert(dto); //장바구니 테이블에 저장됨
        return "redirect:/shop/cart/list.do"//장바구니 목록으로 이동
    }
cs

 

 

CartController.java 중 일부 (장바구니 리스트 관련 메소드)

cartlist.jsp 페이지와 맵핑됨

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
//cart_list페이지와 맵핑되는 메소드
 
    @RequestMapping("list.do")
    public ModelAndView list(HttpSession session, ModelAndView mav) {
        Map<String, Object> map=new HashMap<>();
 
//hashmap은 map(key,value)로 이뤄져 있고,
//key값은 중복이 불가능 하고 value는 중복이 가능하다.
//value에 null값도 사용이 가능하다.
//전달할 정보가 많을 경우에는 HashMap<>을 사용하는 것이 좋다.
//장바구니에 담을 값들이 많기 때문에 여기선 HashMap<>를 사용한다.
 
 
        String userid=(String)session.getAttribute("userid");
 
//session에 저장된 userid를 getAttribute()메소드를 사용해서 얻어오고 오브젝트 타입이기 때문에
//String 타입으로 타입변환한다.
 
        if(userid!=null) { 
//로그인한 상태이면 실행
            List<CartDTO> list=cartService.listCart(userid);//장바구니 목록
            int sumMoney=cartService.sumMoney(userid);//금액 합계
            int fee=sumMoney >= 30000 ? 0 : 2500
 
//배송료 계산
//30000원이 넘으면 배송료가 0원, 안넘으면 2500원
 
//hasp map에 장바구니에 넣을 각종 값들을 저장함
            map.put("sumMoney", sumMoney);
            map.put("fee", fee); //배송료
            map.put("sum", sumMoney+fee); //전체 금액
            map.put("list", list); //장바구니 목록
            map.put("count", list.size()); //레코드 갯수
 
//ModelAndView mav에 이동할 페이지의 이름과 데이터를 저장한다.
 
            mav.setViewName("shop/cart_list"); //이동할 페이지의 이름
            mav.addObject("map", map); //데이터 저장
 
            return mav; //화면 이동
 
        }else { //로그인하지 않은 상태
 
            return new ModelAndView("member/login"""null);
//로그인을 하지 않았으면 로그인 페이지로 이동시킨다.
        }
    }
 
cs

 

 

컨트롤러에서 로그인 여부를 알아야하고, 로그인한 상태이면 서비스와 DAO를 경유해서 mapper에서 "ListCart" id에 대한 쿼리를 실행시킨다.

 

 

CartServiceImpl.java (장바구니 서비스 구현 클래스) 중 일부

1
2
3
4
@Override
    public List<CartDTO> listCart(String userid) {
        return cartDao.listCart(userid);
    }
cs

 

 

CartDAOImpl.java (장바구니 DAO 구현 클래스) 중 일부

(ListCart태그가 호출된다)

1
2
3
4
@Override
    public List<CartDTO> listCart(String userid) {
        return sqlSession.selectList("cart.listCart", userid);
    }
cs

 

 

cartMapper.xml 중 일부

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    <select id="listCart" resultType="com.example.spring02.model.shop.dto.CartDTO">
    <!-- DAO에서 listCart라는 태그로 인해 실행되고 결과타입은 DTO타입으로 한다. (다른계층으로 보내기 위해서) -->
    
        select cart_id, p.product_id, c.userid, name, product_name, amount, price, (price*amount) money
        <!-- 장바구니의 번호, 상품 번호, 회원번호, 회원이름, 상품이름, 상품의양, 상품1개의 가격, 상품의 전체가격을 검색한다.-->
<!--양쪽 테이블에 다 있는 속성이면 어떤 테이블의 속성인지 정확히 표기해주어야 한다.--!>
        
        from member m, cart c, product p
        <!-- 회원테이블과, 장바구니 테이블과, 상품테이블로 부터 -->
        
        where m.userid=c.userid and c.product_id=p.product_id and c.userid=#{userid} order by cart_id
        <!--회원테이블의 회원id와 장바구니테이블의 회원id가 같고, 장바구니의 상품id와 상품테이블의 상품id가 같고, 장바구니테이블의 회원id가  장바구니에 저장되있는 회원id와 같을때-->
        <!-- 장바구니에 관한 정보를 담은 sql문이다. -->
                    
    </select>
cs

 

Mapper에서 SQL을 사용해서 검색한 목록을 list로 받아서 컨트롤러로 전달을 하고, 그 데이터를 바탕으로

sumMoney(총금액, 서비스와 DAO를 거쳐서 받고, 다시 Mapper을 거쳐서 컨트롤러로 받게됨)

 

 

CartServiceImpl.java (서비스 인터페이스 구현 클래스) 중 일부

1
2
3
4
    @Override
    public int sumMoney(String userid) {
        return cartDao.sumMoney(userid);
    }
cs

 

 

CartDAOImpl.java (DAO 인터페이스 구현 클래스) 중 일부

1
2
3
4
    @Override
    public int sumMoney(String userid) {
        return sqlSession.selectOne("cart.sumMoney"userid); 
    }
cs

 

 

cartMapper.xml 중 일부

(조인을 하는 이유는 장바구니 테이블에는 가격이 없기때문에 가격이 있는 다른 테이블과 join을 해야한다.)

1
2
3
4
5
    <select id="sumMoney" resultType="int">
 
        select nvl(sum(price*amount),0)
<!--금액과 상품갯수를 곱한값과 0을더해서 0이 나오는 것을 검색한다. -->
<!--그러니까 아무것도 담지 않았을때를 확인하는 것이다. -->
<!--빈값이 null이면 안되기 때문에 대체값으로 0이 출력되게끔 만들었다--!>
 
        from cart c,product p
<!-- 장바구니 테이블과 상품 테이블로 부터 -->
 
        where c.product_id=p.product_id and userid=#{userid}
<!--조건 : 장바구니테이블의 상품 id가 상품테이블의 상품 id와 같고, 요청하는 회원의 id와 같은 경우 -->
 
    </select>
cs

 

 

cart_list.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<%@ include file="../include/header.jsp" %>
<script>
$(function(){
 
    $("#btnList").click(function(){
        location.href="${path}/shop/product/list.do";
    });
 
// 아래쪽에서 btnlist를 호출해서 실행되는 function() 함수 구문.
// list로 가는 링크를 만든다.
 
    $("#btnDelete").click(function(){
        if(confirm("장바구니를 비우시겠습니까?")){
            location.href="${path}/shop/cart/deleteAll.do";
        }
    });
});
</script>
</head>
<body>
<%@ include file="../include/menu.jsp" %>
<h2>장바구니</h2>
<c:choose>
    <c:when test="${map.count == 0 }">
    <!-- when은 ~~일때 라는 뜻 그러니까 map의 count가 0일때... -->
    <!-- xml파일에서 hashmap에 list를 넣어놓았기 때문에 현재 map에 자료가 들어있다.  -->
    <!-- map에 자료가 아무것도 없다면 -->
        장바구니가 비었습니다.
    </c:when>
    
    <c:otherwise>
    <!-- map.count가 0이 아닐때, 즉 자료가 있을때 -->
    <!-- form을 실행한다.  -->
    <!-- form의 id를 form1로 하고, method 방식을 post로 한다. 그리고 update.do페이지로 이동시킨다. -->
        <form id="form1" name="form1" method="post"
        action="${path}/shop/cart/update.do">
            <table border="1" width="400px">
                <tr>
                    <th>상품명</th>
                    <th>단가</th>
                    <th>수량</th>
                    <th>금액</th>
                    <th>&nbsp;</th>
                </tr>
                <!-- map에 있는 list출력하기 위해 forEach문을 사용해 row라는 변수에 넣는다. -->
            <c:forEach var="row" items="${map.list}">
                <tr align="center">
                    <td>${row.product_name}</td>
                    
                    <td><fmt:formatNumber value="${row.price}"
                            pattern="#,###,###" /></td>
                            <!-- fmt:formatNumber 태그는 숫자를 양식에 맞춰서 문자열로 변환해주는 태그이다 -->
                            <!-- 여기서는 금액을 표현할 때 사용 -->
                            <!-- ex) 5,000 / 10,000 등등등-->
                            
                    <td><input type="number" name="amount" 
                        style="width:30px;"
                        value="<fmt:formatNumber value="${row.amount}"
                            pattern="#,###,###" />">
                    <!-- 물건의 개수 (amount)를 fmt태그를 사용해서 패턴의 형식에 맞춰서 문자열로 변환함 -->
                    <!--1,000 / 5,000 등등~  -->
                    
                            <input type="hidden" name="cart_id"
                            value="${row.cart_id}">
                            
                                
                    </td>
                    <td><fmt:formatNumber value="${row.money}"
                            pattern="#,###,###" /></td>
                    <td><a href=
"${path}/shop/cart/delete.do?cart_id=${row.cart_id}">[삭제]</a>
<!-- 삭제 버튼을 누르면 delete.do로 장바구니 개별 id (삭제하길원하는 장바구니 id)를 보내서 삭제한다. -->
                    </td>
                </tr>
            </c:forEach>
                <tr>
                    <td colspan="5" align="right">
                        장바구니 금액 합계 :
                        <fmt:formatNumber value="${map.sumMoney}"
                            pattern="#,###,###" /><br>
                        배송료 : ${map.fee}<br>
                        총합계 : <fmt:formatNumber value="${map.sum}"
                            pattern="#,###,###" />
                    </td>
                </tr>
            </table>
            <button id="btnUpdate">수정</button>
            <button type="button" id="btnDelete">장바구니 비우기</button>
//btnUpdate와 btnDelete id는 위쪽에 있는 자바스크립트가 처리한다.
        </form>
    </c:otherwise>
</c:choose>
<button type="button" id="btnList">상품목록</button>
</body>
</html>
cs

 

 

-장바구니 삭제-

 



  ( 뷰 => 컨트롤러 => 서비스 => 모델(DAO) => mapper => 컨트롤러 => 뷰)
  
  
  cart_list.jsp에 있는 delete을 호출하면


  컨트롤러로 이동해 delete.do와 맵핑하고 서비스에 장바구니 id를 넘겨준다.


  서비스에서는 넘겨받은 id를 DAO에 저장하고, DAO에서는 태그 아이디가 delete인 태그를 mapper에 전달하고, id도 전달한다.


  mapper에서는 userid가 특정 id (사용자가 선택한 id)를 다 지우게끔 한다.


  그리고 장바구니를 삭제한 후에 다시 컨트롤러로 돌아와 list.jsp 파일로 이동한다.

 

 

 

 

cart_list.jsp (View) 중 일부

1
2
3
 <td>
 <a href= "${path}/shop/cart/delete.do?cart_id=${row.cart_id}">[삭제]</a>
 </td>
cs

 

 

cartController.java 중 일부

1
2
3
4
5
@RequestMapping("delete.do")
    public String delete(@RequestParam int cart_id) {
        cartService.delete(cart_id);
        return "redirect:/shop/cart/list.do";
    }
cs

 

 

cartServiceImpl.java 중 일부

1
2
3
4
@Override
    public void delete(int cart_id) {
        cartDao.delete(cart_id);
    }
cs

 

 

cartDAOImpl.java 중 일부

1
2
3
4
@Override
    public void delete(int cart_id) {
        sqlSession.delete("cart.delete", cart_id);
    }
cs

 

 

cartMapper.xml 중 일부

1
2
3
4
    <!-- 장바구니 개별 상품 삭제 -->
    <delete id="delete">
        delete from cart where cart_id=#{cart_id}
    </delete>
cs

 

 

 

-장바구니 비우기-

 



  ( 뷰 => 컨트롤러 => 서비스 => 모델(DAO) => mapper => 컨트롤러 => 뷰 )




  cart_list.jsp에 있는 javascript구문에서 deleteAll을 호출하면


  컨트롤러로 이동해 deleteAll.do와 맵핑하고 세션에서 유저의아이디를 가져와서 null이 아닐경우에 서비스로 아이디를 넘긴다.


  서비스에서는 넘겨받은 id로 DAO를 호출하고, DAO에서는 태그 아이디가 deleteAll인 태그를 mapper에 전달하고, id도 전달한다.


  mapper에서는 userid가 특정 id (사용자가 선택한 id)를 다 지우게끔 한다.


  그리고 장바구니를 전부다 비운 후에 다시 컨트롤러로 돌아와 list.jsp 파일로 이동한다.

 

cart_list.jsp (view)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
$(function(){
    $("#btnList").click(function(){
        location.href="${path}/shop/product/list.do";
    });
    
    $("#btnDelete").click(function(){
        if(confirm("장바구니를 비우시겠습니까?")){
            location.href="${path}/shop/cart/deleteAll.do";
        }
    });
});
 
</script>
 
======================================================================
 
<button type="button" id="btnDelete">장바구니 비우기</button>
cs

 

 

CartController.java (controller)

1
2
3
4
5
6
7
8
@RequestMapping("deleteAll.do")
    public String deleteAll(HttpSession session) {
        String userid=(String)session.getAttribute("userid");
        if(userid!=null) {
            cartService.deleteAll(userid);
        }
        return "redirect:/shop/cart/list.do";
    }
cs

 

 

CartServiceImpl.java (Service)

1
2
3
4
@Override
    public void deleteAll(String userid) {
        cartDao.deleteAll(userid);
    }
cs

 

 

CartDAOImpl.java (model-DAO)

1
2
3
4
@Override
    public void deleteAll(String userid) {
        cartDao.deleteAll(userid);
    }
cs

 

 

cartMapper.xml

1
2
3
4
5
<!-- 장바구니 비우기 -->
    <delete id="deleteAll">
        delete from cart where userid=#{userid}
        <!-- 장바구니테이블로부터 회원의 아이디와 삭제하고자하는 회원의 아이디가 같으면 장바구니에 있는 자료를 전부다 삭제 -->
    </delete>
cs

아래 책은 제가 공부할때 활용했던 책으로 추천드리는 책이니 한번씩 읽어보시는것을 추천드립니다!! ㅎㅎ

토비의 스프링 3.1 세트:스프링의 이해와 원리 + 스프링의 기술과, 에이콘출판

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

 

 

 

-장바구니 수정-

 

위의 삭제나 비우기와 구조가 거의 동일

728x90
반응형
: