Day46

2020. 12. 4. 14:21교육과정/KOSMO

키워드 : 방명록 만들기 (입력 / 목록보기 / 삭제 / 페이징)

 

 

****

 

 

View단으로 지칭 (Front-end) jsp / js / jquery / css / images
Model단로 지칭 (Back-end) java / JDBC

 

0. 시작 화면은 insertMessage.jsp

※ 전체적인 흐름

 : 화면에 데이터 입력 ------- (table)---------> DB에 저장

※ table의 구조

pk(seq) name password message

 

1. 화면의 내용이 들어갈 DB를 구성한다. 

CREATE table GuestTB (
    message_id	number,                     // 메세지번호 PK 자동증가수
    guest_name	varchar2(10) NOT NULL,      // 손님이름
    password	varchar2(10) NOT NULL,      // 비밀번호
    message	varchar2(1024) NOT NULL,    // 메세지
    CONSTRAINT pk_GuestTB_message_id PRIMARY KEY (message_id)
);
CREATE SEQUENCE seq_guestTb_messageId;

 

2. src - guest.model 패키지 내에 Message.java 클래스 생성 (오류가 모두 사라짐)

 

 

3. insertMessage.jsp의 <form>에서 input의 name을 참고하여 Message.java에 접근지정자를 private으로 하여 변수를 만든다.

public class Message {
	
    private int id;             // 글번호
    private String guestName;   // 사용자명
    private String password;    // 사용자암호
    private String message;     // 사용자메세지
}

 

4. 상단 메뉴 - Source - Generate Getters and Setters - 변수 모두에 대해 setter getter 생성
   상단 메뉴 - Source - Generate Constructors from Superclass - 기본 생성자 생성
   상단 메뉴 - Source - Generate Constructor using Fields - 변수 모두를 인자로 갖는 생성자함수 생성

public Message() {
    super();
}

public Message(int id, String guestName, String password, String message) {
    super();
    this.id = id;
    this.guestName = guestName;
    this.password = password;
    this.message = message;
}

public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
....
....

 


<<<<<<<<<< [메세지 남기기] 와 관련된 작업 시작!! >>>>>>>>>>

 

 

 

5. 화면에서 버튼을 클릭해도 데이터가 넘어가지 않으므로 submit()을 적용시켜준다. 

$('#btn').click(function(){
    $('#frm').submit();
});

→ 데이터 입력 후 클릭하면 화면 넘어가짐

 데이터 넘어가기 전 단계에서 유효성 검사를 추가할 수 있다.  (validate 플러그인 활용)

$('#btn').click(function(){
    $('#frm').validate({
        rules : {
        guestName : { required : true, maxlength : 10 },
        paasword : { required : true, maxlength : 10 },
        message : { required : true, maxlength : 1024 }
        }	
    });
    $('#frm').submit();
});

 

 

6. WriteMessageService.java의 존재 이유

 : 그림에서 위의 3개는 View / 아래 2개는 Model인 상황에서 
   view에는 only 화면과 관련된 코드만 작성하고,

   Dao에는 JDBC를 위한 직접적인 코드만 작성하려면,

   그 외의 다른 코드를 입력하기 위해 만들어둔 별도의 java 파일이 필요하고 (ex : 목록검색)

   그 중 하나가 WriteMessageService.java이다. 

 

 

7. saveMessage.jsp에서는 3가지 스크립트를 작성한다.

   (insertMessage.jsp에서 넘어온 입력값을 model로 전달하기 때문)
  → 한글처리 / 화면의 입력값을 Message.java로 전달

      / WriteMessageService.java의 함수 호출

데이터의 전달 과정 :

insertMessage.jsp 의 <form> →

 ① saveMessage.jsp 의 <jsp:useBean>

     → guest.model.Message.java에 값 저장

 ② saveMessage.jsp 의 WriteMessageService.getInstance().write(m) ;

     → WriteMessageService.java 의 write( ) 호출하며 데이터가 들어있는 m(Message 클래스의 객체) 전달

<% request.setCharacterEncoding("utf-8"); %>

<jsp:useBean id="m" class="guest.model.Message">
    <jsp:setProperty name="m" property="*" />
</jsp:useBean>

<% WriteMessageService.getInstance().write(m); %>

 

8. WriteMessageService.java에서는 넘어온 데이터를 DB와 연동되는 MessageDao.java로 전송한다. 

     → MessageDao.java의 insert( ) 로 데이터가 들어있는 rec(Message 클래스의 객체) 전달

public void write( Message rec ) throws MessageException{
    MessageDao mDao = MessageDao.getInstance();
    mDao.insert(rec);
}

MessageDao.java에서는 데이터가 들어있는 rec(Message클래스의 객체)을 인자로 받아 insert()를 수행한다.

     → JDBC 연동 및 DB에 데이터를 전송하는 SQL 수행 

public void insert(Message rec) throws MessageException {
....
try{
    con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
    String sql = "INSERT INTO GuestTB (message_id, guest_name, password, message) "
                   + "VALUES (seq_guestTb_messageId.nextval ,?,?,?)";  
    ps	= con.prepareStatement( sql );
    ps.setString(1, rec.getGuestName());
    ps.setString(2, rec.getPassword());
    ps.setString(3, rec.getMessage());
    int result = ps.executeUpdate();

 

(결과) 버튼 클릭시 DB에 사용자 입력값이 저장됨

 

 

 

< 데이터 입력 도식화 >

 

 


<<<<<<<<<< [목록보기] 과 관련된 작업 시작!! >>>>>>>>>>

 

 

 

9. saveMessage.jsp에서 [목록보기] 클릭시 listMessage.jsp 페이지로 이동하기 위한 하이퍼링크를 만든다. 

<a href='listMessage.jsp'> [ 목록보기 ] </a>

 

 

10. listMessage.jsp 에서 DB에 저장된 데이터를 List에 담아 화면에 출력한다.

        listMessage.jsp → ListMessageService.java → MessageDao.java

          → ListMessageService.java → listMessage.jsp

     데이터의 전달 과정 :

        ① listMessage.jsp → ListMessageService.java의 getMessageList()를 호출

List <Message> mList =  ListMessageService.getInstance().getMessageList();

        ② ListMessageService.java → MessageDao의 selectList()를 호출

public List <Message> getMessageList(int pageNo) throws MessageException{
    List <Message> mList = MessageDao.getInstance().selectList();
    return mList;
}

        ③ MessageDao.java의 selectList() 함수는 수행 결과로 mList (Message 타입의 List)를 리턴한다. 

public List<Message> selectList() throws MessageException {
....
try{
    con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
    String sql = "SELECT * FROM GuestTB";  
    ps = con.prepareStatement( sql );
    rs = ps.executeQuery();
			
    while(rs.next()) {
        Message temp = new Message();
        temp.setId((rs.getInt("message_id")));
        temp.setGuestName(rs.getString("guest_name"));
        temp.setMessage(rs.getString("message"));
        mList.add(temp);
        isEmpty = false; 
    }
			
    if( isEmpty ) return Collections.emptyList();
			
    return mList;

        ④ listMessage.jsp 에서는 리턴받은 mList로 화면을 그리도록 <table> 태그 부분을 작성한다. 

            → 동적 테이블로 생성되기 위해 for 반복문 사용

            → Message 클래스에 저장된 데이터를 가리키는 변수명 m을 사용하여 <td> 태그에 들어갈 데이터를 출력

            (주의!) <textarea>태그 사이에 공백이 들어가는 것을 방지하기 위해 주석이나 띄어쓰기를 완전히 배제

<table border="1">
    <% for(Message m : mList) { %>
    <tr>	
        <td> <%= m.getId() %></td> 
        <td> <%= m.getGuestName() %></td> 
        <td> [삭제] </td>			
    </tr>
    <tr>
        <td colspan='3'> 
        <textarea cols=35 rows=3 style="font-family: '돋움', '돋움체'; font-size: 10pt; font-style: normal; line-height: normal; color: #003399;background-color:#D4EBFF;border:1 solid #00009C;"><%= m.getMessage() %></textarea>
        </td>
    </tr>
        <% } // end of for %>
</table>

 

(결과)

 

 

< 목록보기 도식화 >

 

 


<<<<<<<<<< [삭제] 와 관련된 작업 시작!! >>>>>>>>>>

 

 

 

11. listMessag.jsp의 하이퍼링크 →  deleteMessage.jsp의 <form> → deleteConfirm.jsp 의 delete( ) 메소드 호출

      → deleteMessageService.java 의 delete( ) 메소드 호출 → MessageDao.java 의 delete( ) 메소드 수행

      → 호출시켰던 곳으로 결과값 리턴

        ① listMessage.jsp의 [삭제] 텍스트에 <a>태그로 하이퍼링크 생성하되, 사용자명을 주소로 가지고 가도록 만들기

            → deleteMessage.jsp로 연결됨

<td><a href="deleteMessage.jsp"> [삭제] </a></td>		
<td><a href="deleteMessage.jsp?id=<%= m.getId() %>"> [삭제] </a></td>	

 

 

 

        ② 이전화면에서 넘어오는 글번호(id) 데이터를 deleteMessage.jsp에서도 받아서 변수에 저장한다. 

<% String id = request.getParameter("id"); %>

 

        ③ "메세지 삭제" 버튼을 누르면 <form>의 사용자 입력값을 가지고 다음 화면(deleteConfirm.jsp)로 넘어가게 된다. 

<form action="deleteConfirm.jsp" method="post">
    암호 : <input type="password" name="password" />
    <input type="submit" value="메세지 삭제"/>
</form>

           → 글 번호도 <form>에 포함시켜 가지고 가도록 스크립트를 수정한다. 

               (데이터가 넘어가는지 확인하기 위해 임시로 전송방식을 get으로 바꾼다.)

<form action="deleteConfirm.jsp" method="get">
    <input type='hidden' name='id' value='<%= id %>' />
    암호 : <input type="password" name="password" />
    <input type="submit" value="메세지 삭제"/>
</form>

 

 

        ④ deleteConfirm.jsp에서는 이전 화면에서 넘어오는 id와 password 데이터를 받아 변수에 저장한다. 

String id = request.getParameter("id");
String password = request.getParameter("password");

 

        ⑤ id와 password 데이터를 인자로 하여 DeleteMessageService.java의 의 delete( ) 메소드를 호출한다. 

            이 때, DeleteMessageService.java의 생성자함수는 싱글톤패턴이라서

            public static인 getInstance( ) 메소드를 통해 객체 생성하고 메소드를 호출하게 된다. 

int delCnt = 0;
delCnt = DeleteMessageService.getInstance().delete(id, password);

 

public class DeleteMessageService {

private static DeleteMessageService instance;

public static DeleteMessageService getInstance() throws MessageException {
    if( instance == null ) {
        instance = new DeleteMessageService();
    }
    return instance;
}

            → delete( ) 메소드에서는 인자 2개를 받아 MessageDao.java의 delete( ) 메소드를 수행하고

                그 결과를 리턴받는다.

                (Dao의 메소드로 int값을 넘겨주기 위해,

                 DeleteMessageService.java의 delete( ) 에 첫번째 인자가 존재하면 그 값을 parseInt 시켜준다.)

public int delete( String messageId, String password ) throws MessageException {
    int mId = 0;
    if( messageId != null) mId = Integer.parseInt(messageId);
    MessageDao mDao = MessageDao.getInstance();
    return mDao.delete(mId, password);
}

 

        ⑥ MessageDao.java에서는 2개의 인자를 받아 delete( ) 메소드를 수행하여 DB에서 데이터를 삭제한다. 

            → n행 성공여부를 결과로 받으므로 그 int값을 메소드가 호출된 곳으로 리턴한다. 

public int delete( int messageId, String password ) throws MessageException {
    int result = 0;
    ....
    try{
        ....
        String sql = "DELETE FROM GuestTB WHERE message_id=? AND password=?";  
        ps = con.prepareStatement( sql );
        ps.setInt(1, messageId);
        ps.setString(2, password);
        result = ps.executeUpdate();

        return result;

 

       ⑦ deleteConfirm.jsp에서는 메소드 수행 결과인 int값에 따라 화면에 출력할 메세지를 결정한다. 

<% if( delCnt == 0 ) { %>
    삭제할 메세지가 존재하지 않거나 비밀번호가 올바르지 않습니다.
<% } else { %>
    메세지를 삭제하였습니다.
<% } %>

 

< 삭제 도식화 >

 


<<<<<<<<<< [페이징] 과 관련된 작업 시작!! >>>>>>>>>>

 

 

 

12. 목록보기에 모든 글이 조회되고 있으므로 특정 갯수만 한 화면에 출력되고, 

     나머지는 다음 페이지로 넘어가도록 만들어야 한다. 

     이를 위해, 전체 글 갯수를 구하고, 페이지 버튼이 작동하도록 만든다.

 

13. MessageDao.java 의 getTotalCount( ) → listMessage.jsp 에서 메소드 호출

     → ListMessageService.java 의 getMessageList( )  → MessageDao.java의 selectList( )

     → ListMessageService.java 의 getTotalPage( ) → MessageDao.java의 getTotalCount( )

       ① MessageDao.java에서 전체 글 갯수를 알기 위한 getTotalCount( ) 메소드를 작성한다. 

           → ResultSet은 첫줄보다 앞을 우선적으로 가리키고 있기 때문에 첫 줄로 가리키기 위해 next( )를 한 번 사용

           → count(*)를 통해 얻어온 전체 글 갯수를 변수 count에 담아서 리턴한다. 

public int getTotalCount() throws MessageException{
....
ResultSet rs = null;
int count = 0;

try{
....
String sql = "SELECT count(*) cnt FROM GuestTB";  
ps = con.prepareStatement( sql );
rs = ps.executeQuery();
			
while(rs.next()) {
    count = rs.getInt("cnt");
}

return  count;

 

       ② listMessage.jsp에서 ListMessageService.java 의 getTotalPage( ) 메소드를 호출한다. 

           결과로 리턴되는 값을 변수 totalPageCount에 저장한다. 

           ListMessageService.java의 getTotalPage( ) 메소드를 작성한다. 

int totalPageCount = ListMessageService.getInstance().getTotalPage();

 

public int getTotalPage() throws MessageException {
    totalRecCount = MessageDao.getInstance().getTotalCount();
    int temp = (totalRecCount % countPerPage);
    
    if (temp == 0) {
        pageTotalCount = (totalRecCount/countPerPage);
    } else {
        pageTotalCount = (totalRecCount/countPerPage) + 1;
    }
    return pageTotalCount;
}

         → ListMessageService.java에서 호출해야 할 메소드가 2개가 되는 것이므로 객체 생성과 각각의 함수 호출을 보기 편하도록 수정해준다. 

List <Message> mList = ListMessageService.getInstance().getMessageList()
int totalPageCount = ListMessageService.getInstance().getTotalPage();

 

ListMessageService service = ListMessageService.getInstance();
	
int totalPageCount = service.getTotalPage();
List <Message> mList =  service.getMessageList();

 

       ③ ListMessageService.java의 getTotalPage( ) 메소드를 작성한다.

           getTotalPage( ) 에서는 ①에서 작성한 MessageDao.java의 getTotalCount( ) 메소드를 호출하고

           리턴값(전체 글 갯수)를 변수 totalRecCount에 담는다. 

           글 갯수에 따라 몇 페이지까지 만들지 결정하여 변수 pageTotalCount에 담고 listMessage.jsp로 리턴한다. 

public int getTotalPage() throws MessageException {
    totalRecCount = MessageDao.getInstance().getTotalCount();
    int temp = (totalRecCount % countPerPage);
    
    if (temp == 0) {
        pageTotalCount = (totalRecCount/countPerPage);
    } else {
        pageTotalCount = (totalRecCount/countPerPage) + 1;
    }
    return pageTotalCount;
}

 

       ④ listMessage.jsp 의 body에 페이지가 표시될 곳을 작성한다. 

<% for (int i=1; i<=totalPageCount; i++) { %>
    [ <%= i %>]
<% } %>

 

      페이지를 나타내는 글씨에 <a>태그로 하이퍼링크를 만든다. 

<a href='listMessage.jsp'>[ <%= i %>]</a>

 

      클릭한 숫자에 해당되는 페이지로 넘어가도록 <a>태그를 수정한다. 

<a href='listMessage.jsp?page=<%= i %>'>[ <%= i %>]</a>

 

      주소창을 통해 넘어오는 페이지 값을 받아줄 변수를 만든다. 

String pNum = request.getParameter("page");

 

      페이지를 클릭한 후에야 pNum의 값이 존재하게 되므로 그 이전까지는 pNum = null이다. 

           따라서, 클릭하기 전에 1페이지를 보여주는 것이 기본 설정이 되게 하기 위한 변수 pageNo를 만든다. 

int pageNo = 1;

 

      페이지를 클릭하면 그 값으로 변수 pageNo가 바뀌도록 스크립트를 작성한다. 

if (pNum != null) 
    pageNo = Integer.parseInt(pNum);

 

      ListMessageService.java의 getMessageList( ) 메소드가 페이지값을 인자로 받아가도록 수정한다. 

List <Message> mList =  service.getMessageList(pageNo);

 

      ListMessageService.java의 getMessageList( ) 메소드가 인자를 받고,

          MessageDao.java 의 seletlist( ) 메소드를 호출 할 때 2개의 인자를 넘겨주도록 수정한다. 

pageNo (페이지 번호) firstRow (시작 레코드 번호) endRow (끝 레코드 번호)
1 1 3
2 4 6
3 7 9
4 10 12
private int countPerPage = 3;	// 한페이지당 레코드 수

public List <Message> getMessageList(int pageNo) throws MessageException {
    int firstRow = pageNo * countPerPage - 2;
    int endRow = pageNo * countPerPage;
    
    List <Message> mList = MessageDao.getInstance().selectList(firstRow, endRow);			
    return mList;
}

 

       ⑫ MessageDao.java 의 selectList( ) 메소드에서 조건에 맞는 데이터만 가져오도록 SQL을 수정한다. 

SELECT * FROM GuestTB WHERE message_id IN 
    (SELECT message_id FROM 
         (SELECT rownum as num, message_id FROM 
             (SELECT message_id FROM GuestTB ORDER BY message_id DESC))
    WHERE (num >=4 AND num <=6))
ORDER BY message_id DESC;

  ※ 페이지에 해당하는 데이터만 가져오는 SQL 만드는 과정

-- [1] 일련번호 검색
SELECT message_id FROM GuestTB;

-- [2] 컬럼을 기준으로 정렬
SELECT message_id FROM GuestTB ORDER BY message_id DESC;

-- [3] 기존컬럼을 정렬 후 그 결과에서 rownum 출력 - FROM에 [2] 대입
SELECT rownum as num, message_id FROM 
    (SELECT message_id FROM GuestTB ORDER BY message_id DESC);
    
-- [4] 해당하는 rownum을 이용하여 원하는 순번 출력 - FROM에 [3] 대입 후 WHERE절 작성
SELECT message_id FROM 
    (SELECT rownum as num, message_id FROM 
        (SELECT message_id FROM GuestTB ORDER BY message_id DESC))
WHERE (num >=4 AND num <=6);

-- [5] 해당하는 rownum의 전체 레코르 출력 - IN에 [4] 대입 후 id로 내림차순 정렬
SELECT * FROM GuestTB WHERE message_id IN 
    (SELECT message_id FROM 
         (SELECT rownum as num, message_id FROM 
             (SELECT message_id FROM GuestTB ORDER BY message_id DESC))
    WHERE (num >=4 AND num <=6))
ORDER BY message_id DESC;

 

       ⑬ 페이지를 클릭하면 pageNo의 값이 바뀌고,

           pageNo의 값에 따라 몇 번째 글부터 몇 번째 글까지 화면에 보여줄지 결정된다. 

           결정된 값에 따라 DB에서 데이터를 가져오고 화면을 그린다. 

 

 

< 페이징 도식화 >

 

 


 

14. "글쓰기" 텍스트에 <a>태그로 insertMessage.jsp 페이지로 넘어가도록 스크립트를 작성한다. 

<a href='insertMessage.jsp'>글쓰기</a>

 

 


15. 전체 소스 코드 

 

< 실습 전 전체 압축 파일 >

03_guest_class.zip
0.09MB

< 실습 후 >

 

< Message.java 소스 코드 >

더보기
package guest.model;

public class Message {
	
	private int id;				// 글번호
	private String guestName;	// 사용자명
	private String password;	// 사용자암호
	private String message;		// 사용자메세지
	
	
	
	public Message() {
		super();
	}
	
	
	
	public Message(int id, String guestName, String password, String message) {
		super();
		this.id = id;
		this.guestName = guestName;
		this.password = password;
		this.message = message;
	}



	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getGuestName() {
		return guestName;
	}
	public void setGuestName(String guestName) {
		this.guestName = guestName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
	
}

< MessageDao.java 소스 코드 >

더보기
package guest.model;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MessageDao {

	// Single Pattern 
	private static MessageDao instance;
	
	// DB 연결시  관한 변수 
	private static final String 	dbDriver	=	"oracle.jdbc.driver.OracleDriver";
	private static final String		dbUrl		=	"jdbc:oracle:thin:@192.168.0.17:1521:orcl";
	private static final String		dbUser		=	"hr";
	private static final String		dbPass		=	"hr";
	
	
	
	//--------------------------------------------
	//#####	 객체 생성하는 메소드 
	public static MessageDao	getInstance() throws MessageException
	{
		if( instance == null )
		{
			instance = new MessageDao();
		}
		return instance;
	}
	
	private MessageDao() throws MessageException
	{
	
		try{
			
			/********************************************
				1. 오라클 드라이버를 로딩
					( DBCP 연결하면 삭제할 부분 )
			*/
			Class.forName( dbDriver );
		}catch( Exception ex ){
			throw new MessageException("방명록 ) DB 연결시 오류  : " + ex.toString() );	
		}
		
	}
	
	
	/*
	 * 메세지를 입력하는 함수
	 */
	public void insert(Message rec) throws MessageException
	{
		Connection	 		con = null;
		PreparedStatement ps = null;
		try{
			// 1. 연결객체(Connection) 얻어오기
			con	= DriverManager.getConnection( dbUrl, dbUser, dbPass );
			// 2. sql 문장 만들기
			String sql		= "INSERT INTO GuestTB (message_id, guest_name, password, message) "
					+ "VALUES (seq_guestTb_messageId.nextval ,?,?,?)";  
			// 3. 전송객체 얻어오기
			ps	= con.prepareStatement( sql );
			ps.setString(1, rec.getGuestName());
			ps.setString(2, rec.getPassword());
			ps.setString(3, rec.getMessage());
			// 4. 전송하기
			int result = ps.executeUpdate();
			System.out.println(result + "행 성공");
				
		}catch( Exception ex ){
			throw new MessageException("방명록 ) DB에 입력시 오류  : " + ex.toString() );	
		} finally{
			if( ps   != null ) { try{ ps.close();  } catch(SQLException ex){} }
			if( con  != null ) { try{ con.close(); } catch(SQLException ex){} }
		}
	
	}
	
	/*
	 * 메세지 목록 전체를 얻어올 때
	 */
	public List<Message> selectList() throws MessageException
	{
		Connection	 		con = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<Message> mList = new ArrayList<Message>();
		boolean isEmpty = true;
		
		try{
			// 1. 연결객체(Connection) 얻어오기
			con	= DriverManager.getConnection( dbUrl, dbUser, dbPass );
			// 2. sql 문장 만들기
			String sql		= "SELECT * FROM GuestTB";  
			// 3. 전송객체 얻어오기
			ps	= con.prepareStatement( sql );
			// 4. 전송하기
			rs = ps.executeQuery();
			System.out.println(rs);
			
			while(rs.next()) {
				Message temp = new Message();
				temp.setId((rs.getInt("message_id")));
				temp.setGuestName(rs.getString("guest_name"));
				temp.setMessage(rs.getString("message"));
				mList.add(temp);
				isEmpty = false; 
            }
			
			if( isEmpty ) return Collections.emptyList();
			
			return mList;
		}catch( Exception ex ){
			throw new MessageException("방명록 ) DB에 목록 검색시 오류  : " + ex.toString() );	
		} finally{
			if( rs   != null ) { try{ rs.close();  } catch(SQLException ex){} }
			if( ps   != null ) { try{ ps.close();  } catch(SQLException ex){} }
			if( con  != null ) { try{ con.close(); } catch(SQLException ex){} }
		}		
	}
	

	/* -------------------------------------------------------
	 * 현재 페이지에 보여울 메세지 목록  얻어올 때
	 */
	public List<Message> selectList(int firstRow, int endRow) throws MessageException
	{
		Connection	 		con = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<Message> mList = new ArrayList<Message>();
		boolean isEmpty = true;
		
		try{
			// 1. 연결객체(Connection) 얻어오기
			con	= DriverManager.getConnection( dbUrl, dbUser, dbPass );
			// 2. sql 문장 만들기
			String sql		= "SELECT * FROM GuestTB WHERE message_id " 
								+ "IN (SELECT message_id FROM (SELECT rownum as num, message_id " 
								+ "FROM (SELECT message_id FROM GuestTB ORDER BY message_id DESC))" 
								+ "WHERE (num >=? AND num <=?)) ORDER BY message_id DESC";  
			// 3. 전송객체 얻어오기
			ps	= con.prepareStatement( sql );
			ps.setInt(1, firstRow);
			ps.setInt(2, endRow);
			// 4. 전송하기
			rs = ps.executeQuery();
			System.out.println(rs);
			
			while(rs.next()) {
				Message temp = new Message();
				temp.setId((rs.getInt("message_id")));
				temp.setGuestName(rs.getString("guest_name"));
				temp.setMessage(rs.getString("message"));
				mList.add(temp);
				isEmpty = false; 
            }

			
			if( isEmpty ) return Collections.emptyList();
			
			return mList;
		}catch( Exception ex ){
			throw new MessageException("방명록 ) DB에 목록 검색시 오류  : " + ex.toString() );	
		} finally{
			if( rs   != null ) { try{ rs.close();  } catch(SQLException ex){} }
			if( ps   != null ) { try{ ps.close();  } catch(SQLException ex){} }
			if( con  != null ) { try{ con.close(); } catch(SQLException ex){} }
		}		
	}
	
	
	
	/* -------------------------------------------------------
	 * 메세지 전체 레코드 수를 검색
	 */
	
	public int getTotalCount() throws MessageException{
		Connection	 		con = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		int count = 0;

		try{
			
			// 1. 연결객체(Connection) 얻어오기
			con	= DriverManager.getConnection( dbUrl, dbUser, dbPass );
			// 2. sql 문장 만들기
			String sql		= "SELECT count(*) cnt FROM GuestTB";  
			// 3. 전송객체 얻어오기
			ps	= con.prepareStatement( sql );
			// 4. 전송하기
			rs = ps.executeQuery();
			System.out.println(rs);
			
			while(rs.next()) {
				count = rs.getInt("cnt");
            }

			return  count;
			
		}catch( Exception ex ){
			throw new MessageException("방명록 ) DB에 목록 검색시 오류  : " + ex.toString() );	
		} finally{
			if( rs   != null ) { try{ rs.close();  } catch(SQLException ex){} }
			if( ps   != null ) { try{ ps.close();  } catch(SQLException ex){} }
			if( con  != null ) { try{ con.close(); } catch(SQLException ex){} }
		}			
	}
	
	/*
	 * 메세지 번호와 비밀번호에 의해 메세지 삭제
	 */
	public int delete( int messageId, String password ) throws MessageException
	{
		int result = 0;
		Connection	 		con = null;
		PreparedStatement ps = null;
		try{
			// 1. 연결객체(Connection) 얻어오기
			con	= DriverManager.getConnection( dbUrl, dbUser, dbPass );
			// 2. sql 문장 만들기
			String sql		= "DELETE FROM GuestTB WHERE message_id=? AND password=?";  
			// 3. 전송객체 얻어오기
			ps	= con.prepareStatement( sql );
			ps.setInt(1, messageId);
			ps.setString(2, password);
			// 4. 전송하기
			result = ps.executeUpdate();
			System.out.println(result + "행 삭제 성공");
			
			return result;
		}catch( Exception ex ){
			throw new MessageException("방명록 ) DB에 삭제시 오류  : " + ex.toString() );	
		} finally{
			if( ps   != null ) { try{ ps.close();  } catch(SQLException ex){} }
			if( con  != null ) { try{ con.close(); } catch(SQLException ex){} }
		}		
	}
}

< WriteMessageService.java 소스 코드 >

더보기
package guest.service;

import guest.model.Message;
import guest.model.MessageDao;
import guest.model.MessageException;

public class WriteMessageService {

	private static WriteMessageService instance;
	
	public static WriteMessageService	getInstance() throws MessageException
	{
		if( instance == null )
		{
			instance = new WriteMessageService();
		}
		return instance;
	}
	
	private WriteMessageService()
	{
		
	}
	
	public void write( Message rec ) throws MessageException
	{
		MessageDao mDao = MessageDao.getInstance();
		mDao.insert(rec);
	
	}
}

< ListMessageService.java 소스 코드 >

더보기
package guest.service;

import guest.model.Message;
import guest.model.MessageDao;
import guest.model.MessageException;

import java.util.List;

public class ListMessageService {

	//-------------------------------------------------------------------
	private int totalRecCount;		// 전체 레코드 수	
	private int pageTotalCount;		// 전체 페이지 수
	private int countPerPage = 3;	// 한페이지당 레코드 수
	
	private static ListMessageService instance;
	
	public static ListMessageService	getInstance() throws MessageException
	{
		if( instance == null )
		{
			instance = new ListMessageService();
		}
		return instance;
	}
	
	private ListMessageService()
	{
		
	}
	
	// 전체 메세지(레코드)의 갯수를 얻어오기
	public int getTotalPage() throws MessageException {
		totalRecCount = MessageDao.getInstance().getTotalCount();
		int temp = (totalRecCount % countPerPage);
		if (temp == 0) {
			pageTotalCount = (totalRecCount/countPerPage);
		} else {
			pageTotalCount = (totalRecCount/countPerPage) + 1;
		}
		return pageTotalCount;
		
//		pageTotalCount= (int)Math.ceil(totalRecCount/countPerPage);

	}
	
	public List <Message> getMessageList(int pageNo) throws MessageException
	{
	/*
			페이지번호		시작레코드번호		끝레코드번호
				1			1				3
				2			4				6
				3			7				9
				4			10				12
	 */
		int firstRow = pageNo * countPerPage - 2;
		int endRow = pageNo * countPerPage;
		
		
		// 전체 레코드를 검색해 온다면
		List <Message> mList = MessageDao.getInstance().selectList(firstRow, endRow);			
		return mList;
	}
	
	
}

< DeleteMessageService.java 소스 코드 >

더보기
package guest.service;

import guest.model.Message;
import guest.model.MessageDao;
import guest.model.MessageException;

public class DeleteMessageService {

	private static DeleteMessageService instance;
	
	public static DeleteMessageService	getInstance() throws MessageException
	{
		if( instance == null )
		{
			instance = new DeleteMessageService();
		}
		return instance;
	}
	
	private DeleteMessageService()
	{
		
	}
	
	public int delete( String messageId, String password ) throws MessageException
	{
		int mId = 0;
		if( messageId != null) mId = Integer.parseInt(messageId);
		MessageDao mDao = MessageDao.getInstance();
		return mDao.delete(mId, password);
		
	}
}

< insertMessage.jsp 소스 코드 >

더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title> 방명록 </title>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="./js/jquery.validate.min.js"></script>
<script type="text/javascript">
$(function(){
	$('#btn').click(function(){
		// 유효성 검사
		$('#frm').validate({
			rules : {
				guestName : { required : true, maxlength : 10 },
				paasword : { required : true, maxlength : 10 },
				message : { required : true, maxlength : 1024 }
			}	
		});
		// 버튼 클릭했을 때 데이터 넘어감
		$('#frm').submit();
	});
	
})
</script>

</head>

<body>

	<form action="saveMessage.jsp" name="frm" id="frm" method="post">
		이름 : <input type="text" name="guestName" id="guestName" required /><br/><br/>
		암호 : <input type="password" name="password" id="password" required /><br/><br/>
		메세지 : <textarea name="message" id="message" rows="3" cols="30" required></textarea><br/><br/>
		<input type="button" id="btn" value="메세지 남기기">
	</form>
</body>
</html>

< saveMessage.jsp 소스 코드 >

더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="guest.service.WriteMessageService"%>    

<% request.setCharacterEncoding("utf-8"); %>
<!-- 
	0. 넘겨받는 데이타의 한글처리
	1. 화면의 입력값을 Message 클래스로 전달
	2. Service 클래스의 함수 호출
 -->     

<jsp:useBean id="m" class="guest.model.Message">
	<jsp:setProperty name="m" property="*" />
</jsp:useBean>

<%
	WriteMessageService.getInstance().write(m);
%>
    
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title> 방명록 남김 </title>
</head>
<body>
	<font size="3" color="#bb44cc">
		방명록에 메세지를 남겼습니다. 
	</font><br/><br/><br/>
	<a href='listMessage.jsp'> [ 목록보기 ] </a> 
</body>
</html>

< listMessage.jsp 소스 코드 >

더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="guest.model.*,guest.service.*" %>   
<%@ page import="java.util.List" %>
 
<%
	String pNum = request.getParameter("page");
	int pageNo = 1;
	if (pNum != null) pageNo = Integer.parseInt(pNum);
	
	// 전체 메세지 레코드 검색 
//	List <Message> mList =  ListMessageService.getInstance().getMessageList();
	ListMessageService service = ListMessageService.getInstance();
	
	int totalPageCount = service.getTotalPage();
	List <Message> mList =  service.getMessageList(pageNo);
 	
	
%>    
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title> 방명록 목록 </title>
</head>
<body>

	<% if( mList.isEmpty() ) { %>
		남겨진 메세지가 하나도~~없습니다. <br>
	<% } else { %>
	<table border="1">
	
		<% for(Message m : mList) { %>
		<tr>	
			<td> <%= m.getId() %></td> 
			<td> <%= m.getGuestName() %></td> 
			<td><a href="deleteMessage.jsp?id=<%= m.getId() %>"> [삭제] </a></td>			
		</tr>
		<tr>
			<td colspan='3'> 
			<textarea cols=35 rows=3 style="font-family: '돋움', '돋움체'; font-size: 10pt; font-style: normal; line-height: normal; color: #003399;background-color:#D4EBFF;border:1 solid #00009C;"><%= m.getMessage() %></textarea>
			</td>
		</tr>
		<% } // end of for %>

	</table>
	
	<% } // end if-else %>

	<a href='insertMessage.jsp'>글쓰기</a>
	
	<% for (int i=1; i<=totalPageCount; i++) { %>
		<a href='listMessage.jsp?page=<%= i %>'>[ <%= i %>]</a> 
	<% } // end of for %>

	
</body>
</html>

< deleteMessage.jsp 소스 코드 >

더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<% String id = request.getParameter("id"); %>

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title> 방명록 삭제 </title>
</head>
<body>
	메세지를 삭제하려면 암호를 입력하세요. <br/><br/>
	<form action="deleteConfirm.jsp" method="post">
		<input type='hidden' name='id' value='<%= id %>' />
		암호 : <input type="password" name="password" />
		<input type="submit" value="메세지 삭제"/>
	</form>
</body>
</html>

< deleteConfirm.jsp 소스 코드 >

더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="guest.service.DeleteMessageService" %>    
<%
	int delCnt = 0;
	// 1. 앞의 화면에서 삭제할 번호와 패스워드를 넘겨받는다.
	String id = request.getParameter("id");
	String password = request.getParameter("password");
	// 2. 서비스의 delete() 메소드로 1번의 값을 넘겨주고 삭제된 행 수를 리턴받아 delCnt 변수에 지정
	delCnt = DeleteMessageService.getInstance().delete(id, password);
	
%>    
	
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title> 메세지 삭제 확인 </title>
</head>
<body>
	<% if( delCnt == 0 ) { %>
		삭제할 메세지가 존재하지 않거나 비밀번호가 올바르지 않습니다.
	<% } else { %>
		메세지를 삭제하였습니다.
	<% } %>
	
	<br/><br/>
	<a href="listMessage.jsp"> [ 목록보기 ] </a>
</body>
</html>

 

 

반응형

'교육과정 > KOSMO' 카테고리의 다른 글

Day48  (1) 2020.12.08
Day47  (0) 2020.12.07
Day45  (0) 2020.12.03
Day44  (0) 2020.12.02
Day43  (0) 2020.12.01