티스토리 뷰


-- oracle를 사용하여 데이터 베이스를 만듬

-- ibatis를 import해서 사용


< 프로젝트의 기본 틀 >

--Java Resources --> src -->

1) kr.koreait.ibatis

-db.properties (oracle 사용시 필요)

-guestbook.xml

-SqlMapConfig.xml

-MyAppSqlCofig.java

2) kr.koreait.DAO

-GuestbookDAO

3) kr.koreait.VO

-GuestbookList

-GuestbookVO

-param

4) kr.koreait.Service

-DeleteSevice

-InsertService

-SelectService

-UpdateService

--WebContent (jsp파일) -->   

      list

listView

listView1

selectByldx

insert

insertOK

update

updateOK

delete

deleteOK


-- WebContent --> WEB-INF

--> lib

--> ibatis-sqlmap-2.3.4.726

  jstl-1.2

  ojbc6-11.1.0.7.0


-- 오라클 설치



>>오라클 계정 만들기


SQL> connect system 엔터
※ 실제로 비밀번호를 입력할 때는 문자가 화면에 표시되지 않는다.
Enter Password : 0000 엔터
SQL> create user (계정명) identified by (비밀번호); 엔터
SQL> grant connect(접속), resource(데이터 관리) to (계정명); 엔터


오라클 계정 지우기
SQL> drop user (계정명) cascade;


>>sqldevedloper 설치 (직접사용한느 프로그램)

 

 

 

 

CREATE TABLE "GUESTBOOK"
( "IDX" NUMBER(5,0) NOT NULL ENABLE,
 "NAME" CHAR(30 BYTE) NOT NULL ENABLE,
 "PASSWORD" CHAR(50 BYTE) NOT NULL ENABLE,
 "CONTENT" VARCHAR2(500 BYTE) NOT NULL ENABLE,
 "WRITEDATE" TIMESTAMP (6) DEFAULT sysdate,
 "IP" CHAR(15 BYTE),
  CONSTRAINT "GUESTBOOK_PK" PRIMARY KEY ("IDX")
);

 

-- idx가 자동증가(시퀀스)하게 만들기


delete from guestbook;
drop sequence guestbook_idx_seq;
create sequence guestbook_idx_seq;

insert into guestbook (idx, name, password, content, ip)
values (guestbook_idx_seq.nextval, '어피치', '1111', '안녕하세요 저는 어피치입니다~', '192.168.1.100');
insert into guestbook (idx, name, password, content, ip)
values (guestbook_idx_seq.nextval, '네오', '2222', '안녕하세요 저는 네오입니다~', '192.168.2.200');
insert into guestbook (idx, name, password, content, ip)
values (guestbook_idx_seq.nextval, '프로도', '3333', '안녕하세요 저는 프로도입니다~', '192.168.3.300');
insert into guestbook (idx, name, password, content, ip)
values (guestbook_idx_seq.nextval, '라이언', '4444', '안녕하세요 저는 라이언입니다~', '192.168.4.400');

-- developer에서 삽입한 내용이 적용되게 하려면 commit 명령을 실행한다.
commit;

select * from guestbook order by idx desc;
select count(*) from guestbook;


-- 캐시 사이즈 0으로 조정
alter sequence guestbook_idx_seq nocache;

select count(*) from guestbook where content like '%네오%';

 



 


< GuestBook 프로젝트 코드 >


# kr.koreait.VO

>>GuestbookVO.java


package kr.koreait.VO;

import java.util.Date;

// 한 건의 데이터를 기억하는 VO클래스 (Value Object)
public class GuestbookVO {
 
// private으로 멤버 변수를 선언한다.
// 멤버 변수의 이름은 테이블의 필드 이름과 동일하게 만든다.
// (HTML form 태그의 name 속성의 이름과도 같아야 한다.)


 private int idx;      // 글번호
 private String name;     // 작성자 이름
 private String password;    // 비밀번호
 private String content;     // 내용
 private Date writeDate;     // 작성일
 private String ip;      // IP 주소


// getter/setter 메소드를 만든다.
 public int getIdx() {
  return idx;
 }
 public void setIdx(int idx) {
  this.idx = idx;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getPassword() {
  return password;
 }
 public void setPassword(String password) {
  this.password = password;
 }
 public String getContent() {
  return content;
 }
 public void setContent(String content) {
  this.content = content;
 }
 public Date getWriteDate() {
  return writeDate;
 }
 public void setWriteDate(Date writeDate) {
  this.writeDate = writeDate;
 }
 public String getIp() {
  return ip;
 }
 public void setIp(String ip) {
  this.ip = ip;
 }


// toString() 메소드를 오버라이드한다.
 @Override
 public String toString() {
  return "GuestbookVO [idx=" + idx + ", name=" + name + ", password=" + password + ", content=" + content
    + ", writeDate=" + writeDate + ", ip=" + ip + "]";
 }
}


>>GustbookList.java


package kr.koreait.VO;

import java.util.ArrayList;

// 화면에 표시할 한 페이지 분량의 데이터와 페이지 작업에 사용할 8개의 변수를 기억하는 클래스
public class GuestbookList {

// 한 페이지 분량의 글을 기억할 ArrayList
 private ArrayList<GuestbookVO> list = new ArrayList<>();


// 페이지 작업에 사용할 변수
 private int pageSize;     // 한 페이지에 표시할 글의 개수
 private int totalCount;     // 테이블에 저장된 전체 글의 개수
 private int totalPage;     // 전체 페이지 개수
 private int currentPage;    // 현재 화면에 표시할 페이지 번호
 private int startNo;     // 화면에 표시할 글의 시작 인덱스
 private int endNo;      // 화면에 표시할 글의 마지막 인덱스
 private int startPage;     // 화면에 표시할 페이지 이동 하이퍼링크의 시작 번호
 private int endPage;     // 화면에 표시할 페이지 이동 하이퍼링크의 끝 번호
 
 public GuestbookList() { }

// pageSize, totalCount, currentPage를 받아서 초기화하고 나머지 변수는 계산해서 초기화하는 생성자
 public GuestbookList(int pageSize, int totalCount, int currentPage) {
  this.pageSize = pageSize;
  this.totalCount = totalCount;
  this.currentPage = currentPage;
  calculation();
 }

 private void calculation() {
  totalPage = (totalCount - 1) / pageSize + 1;
  currentPage = currentPage > totalPage ? totalPage : currentPage;

 // 수식 : currentPage가 totalPage 보다 크면 totalPage 아니면 currentPage로 출력
//  OracleDB의 시작인덱스는 0이 아니라 1이다. (mysql은 0부터 시작)
  startNo = (currentPage - 1) * pageSize + 1;
  endNo = startNo + pageSize - 1;
  endNo = endNo > totalCount ? totalCount : endNo;
  startPage = (currentPage - 1) / 10 * 10 + 1;
  endPage = startPage + 9;
  endPage = endPage > totalPage ? totalPage : endPage;
 }

 public ArrayList<GuestbookVO> getList() {
  return list;
 }

 public void setList(ArrayList<GuestbookVO> list) {
  this.list = list;
 }

 public int getPageSize() {
  return pageSize;
 }

 public void setPageSize(int pageSize) {
  this.pageSize = pageSize;
 }

 public int getTotalCount() {
  return totalCount;
 }

 public void setTotalCount(int totalCount) {
  this.totalCount = totalCount;
 }

 public int getTotalPage() {
  return totalPage;
 }

 public void setTotalPage(int totalPage) {
  this.totalPage = totalPage;
 }

 public int getCurrentPage() {
  return currentPage;
 }

 public void setCurrentPage(int currentPage) {
  this.currentPage = currentPage;
 }

 public int getStartNo() {
  return startNo;
 }

 public void setStartNo(int startNo) {
  this.startNo = startNo;
 }

 public int getEndNo() {
  return endNo;
 }

 public void setEndNo(int endNo) {
  this.endNo = endNo;
 }

 public int getStartPage() {
  return startPage;
 }

 public void setStartPage(int startPage) {
  this.startPage = startPage;
 }

 public int getEndPage() {
  return endPage;
 }

 public void setEndPage(int endPage) {
  this.endPage = endPage;
 }

 @Override
 public String toString() {
  return "GuestbookList [list=" + list + "]";
 }
 
}


>> Param


package kr.koreait.VO;

public class Param {

 private int startNo;
 private int endNo;
 private String item;
 
 public int getStartNo() {
  return startNo;
 }
 public void setStartNo(int startNo) {
  this.startNo = startNo;
 }
 public int getEndNo() {
  return endNo;
 }
 public void setEndNo(int endNo) {
  this.endNo = endNo;
 }
 public String getItem() {
  return item;
 }
 public void setItem(String item) {
  this.item = item;
 }
 
}



#kr.koreait.DAO

>>GuestbookDAO.java


package kr.koreait.DAO;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;

import com.ibatis.sqlmap.client.SqlMapClient;

import kr.koreait.VO.GuestbookVO;
import kr.koreait.VO.Param;

// DAO (Data Access Object) 클래스 : 실제 SQL 명령을 실행하는 클래스
// jdbc나 dbcp 방식을 사용하면 이 클래스에서 SQL 명령을 실행하지만
// ibatis나 mybatis를 사용하면 실행할 SQL 명령은 xml파일에 적어주고
// DAO 클래스에서 xml 파일의 실행할 명령을 호출한다.


public class GuestbookDAO {

 private static GuestbookDAO instance = new GuestbookDAO();
 private GuestbookDAO() { }
 public static GuestbookDAO getInstance() { return instance; }
// InsertService.java에서 mapper와 테이블에 저장할 내용이 담긴 객체를 넘겨받고,
// 테이블에 저장하는 xml 파일의 insert SQL 명령을 실행하는 메소드


 public void insert(SqlMapClient mapper, GuestbookVO vo) throws SQLException {
  mapper.insert("insert", vo);
 }
// SelectService.java에서 mapper를 넘겨받고, 테이블에 저장된 전체 글의 개수를
// 얻어오는 xml 파일의 select SQL 명령을 실행하는 메소드


 public int selectCount(SqlMapClient mapper) throws SQLException {
//  queryForList() : select 명령의 실행 결과가 여러 건일 경우 사용 (mybatis의 selectList())
//  queryForObject() : select 명령의 실행 결과가 한 건일 경우 사용 (mybatis의 selectOne())
//  queryForList()의 실행결과는 무조건 List 인터페이스 타입이고,
//  queryForObject()의 실행결과는 무조건 Object 클래스 타입이므로 반드시 형변환을 해야한다.
  return (int) mapper.queryForObject("selectCount");
 }
// SelectService.java에서 mapper와 검색어를 넘겨받고, 테이블에 저장된 글 중에서
// 검색어를 포함하는 글의 개수를 얻어오는 xml 파일의 select SQL 명령을 실행하는 메소드


 public int selectCount(SqlMapClient mapper, String item) throws SQLException {
  return (int) mapper.queryForObject("selectItemCount", item);
 }
// SelectService.java에서 mapper와 시작 인덱스, 끝 인덱스가 저장된 HashMap 객체를 넘겨받고,
// 테이블에서 한 페이지 분량의 글을 얻어오는 xml 파일의 select SQL 명령을 실행하는 메소드


 public ArrayList<GuestbookVO> selectList(SqlMapClient mapper, HashMap<String, Integer> hmap) throws SQLException {
  return (ArrayList<GuestbookVO>) mapper.queryForList("selectList", hmap);
 }
// SelectService.java에서 mapper와 시작 인덱스, 끝 인덱스, 검색어가 저장된 Param 객체를 넘겨받고,
// 테이블에서 한 페이지 분량의 글을 얻어오는 xml 파일의 select SQL 명령을 실행하는 메소드


 public ArrayList<GuestbookVO> selectList(SqlMapClient mapper, Param param) throws SQLException {
  return (ArrayList<GuestbookVO>) mapper.queryForList("selectItemList", param);
 }
// SelectService.java에서 mapper와 수정 또는 삭제할 글 번호를 넘겨받고,
// 테이블에서 글 한 건을 얻어오는 xml 파일의 select SQL 명령을 실행하는 메소드


 public GuestbookVO selectByIdx(SqlMapClient mapper, int idx) throws SQLException {
  return (GuestbookVO) mapper.queryForObject("selectByIdx", idx);
 }
// DeleteService.java에서 mapper와 삭제할 글 번호를 넘겨받고,
// 테이블에서 글 한 건을 삭제하는 xml 파일의 delete SQL 명령을 실행하는 메소드


 public void delete(SqlMapClient mapper, int idx) throws SQLException {
  mapper.delete("delete", idx);
 }
// UpdateService.java에서 mapper와 수정할 내용이 담긴 객체를 넘겨받고,
// 테이블에서 글 한 건을 수정하는 xml 파일의 update SQL 명령을 실행하는 메소드


 public void update(SqlMapClient mapper, GuestbookVO vo) throws SQLException {
  mapper.update("update", vo);
 }
}


#kr.koreait.ibatis

>>db.properties ( db와 연결해줌 )


driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:xe
username=korea123
password=0000


>>guestbook


<?xml version="1.0" encoding="UTF-8" ?>
<!-- DOCTYPE이 sqlMap은 처리할 SQL 명령을 기억하는 xml 파일이다. -->
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="Guestbook">
 <!-- id : SQL 명령을 식별한다. -->
 <!-- parameterClass : SQL 명령으로 전달되는 데이터의 타입을 적는다. -->
 <!-- resultClass : SQL 명령문에의해 출력되는 데이터의 타입을 적는다. -->
 
 <!-- 테이블에 글을 한 건 저장한다. -->
 <insert id="insert" parameterClass="kr.koreait.VO.GuestbookVO">
  <!-- nextval : 시퀀스를 1 증가시킨다. currval : 현재 시퀀스의 값을 얻어온다. -->
  insert into guestbook (idx, name, password, content, ip)
  values (guestbook_idx_seq.nextval, #name#, #password#, #content#, #ip#)
 </insert>
 
 <!-- 테이블에 저장된 전체 글의 개수를 얻어온다. -->
 <select id="selectCount" resultClass="int">
  select count(*) from guestbook
 </select>
 
 <!-- 테이블에 저장된 글 중에서 검색어를 포함하는 글의 개수를 얻어온다. -->
 <select id="selectItemCount" parameterClass="String" resultClass="int">
  select count(*) from guestbook where content like '%'||#item#||'%'
 </select>
 
 <!-- 테이블에 저장된 글 중에서 화면에 표시할 한 페이지 분량의 글을 얻어온다. -->
 <select id="selectList" parameterClass="java.util.HashMap" resultClass="kr.koreait.VO.GuestbookVO">
  <!-- <![CDATA[ ~ ]]> 사이에 입력된 내용은 무조건 문자로 취급한다. -->
  <![CDATA[
   select * from (  
    select rownum rnum, T.* from (
     select * from guestbook order by idx desc
    ) T where rownum <= #endNo#
   ) where rnum >= #startNo#
  ]]>
 </select>
 
 <!-- 테이블에 저장된 글 중에서 검색어가 포함된 한 페이지 분량의 글을 얻어온다. -->
 <select id="selectItemList" parameterClass="kr.koreait.VO.Param" resultClass="kr.koreait.VO.GuestbookVO">
  <![CDATA[
   select * from (  
    select rownum rnum, T.* from (
     select * from guestbook where content like '%'||#item#||'%' order by idx desc
    ) T where rownum <= #endNo#
   ) where rnum >= #startNo#
  ]]>
 </select>
 
 <!-- 테이블에 저장된 수정 또는 삭제할 글 한 건을 얻어온다. -->
 <select id="selectByIdx" parameterClass="int" resultClass="kr.koreait.VO.GuestbookVO">
  select * from guestbook where idx = #idx#
 </select>
 
 <!-- 테이블에서 글 한 건을 삭제한다. -->
 <delete id="delete" parameterClass="int">
  delete from guestbook where idx = #idx#
 </delete>
 
 <!-- 테이블에서 글 한 건을 수정한다. -->
 <update id="update" parameterClass="kr.koreait.VO.GuestbookVO">
  update guestbook set name = #name#, content = #content# where idx = #idx#
 </update>
 
</sqlMap>


>>MyAppSqlConfig


package kr.koreait.ibatis;

import java.io.Reader;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

public class MyAppSqlConfig {
 private static final SqlMapClient sqlMap;
 static { // 초기화 블록
//  final로 선언한 상수는 반드시 초기화를 시켜야 한다.
//  final로 선언한 상수가 초기화하는 데 두 줄 이상이 필요하다면
//  초기화 블록 static { ~ } 사이에 적는다.
  try {
   String resource = "kr/koreait/ibatis/SqlMapConfig.xml";
   Reader reader = Resources.getResourceAsReader(resource);
   sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
  } catch(Exception e) {
   e.printStackTrace();
   throw new RuntimeException ("Error : " + e);
  }
 }
 public static SqlMapClient getSqlMapInstance(){
  return sqlMap;
 }
}


>>SqlMapConfig


<?xml version="1.0" encoding="UTF-8"?>
<!-- DOCTYPE이 sqlMapConfig은 iBATIS의 환경을 설정하는 xml 파일이다. -->
<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
 <properties resource="kr/koreait/ibatis/db.properties" />
 <settings
  cacheModelsEnabled="true"
  enhancementEnabled="true"
  lazyLoadingEnabled="true"
  maxRequests="32"
  maxSessions="10"
  maxTransactions="5"
  useStatementNamespaces="false"
 />
 <typeAlias alias="person" type="my.ibatis.Person" />
 <transactionManager type="JDBC">
  <dataSource type="SIMPLE">
   <property name="JDBC.Driver" value="${driver}" />
   <property name="JDBC.ConnectionURL" value="${url}" />
   <property name="JDBC.Username" value="${username}" />
   <property name="JDBC.Password" value="${password}" />
  </dataSource>
 </transactionManager>
 <sqlMap resource="kr/koreait/ibatis/guestbook.xml" />
</sqlMapConfig>


#kr.koreait.Service

>>DeleteService


package kr.koreait.Service;

import java.sql.SQLException;

import com.ibatis.sqlmap.client.SqlMapClient;

import kr.koreait.DAO.GuestbookDAO;
import kr.koreait.ibatis.MyAppSqlConfig;

public class DeleteService {

 private static DeleteService instance = new DeleteService();
 private DeleteService() { }
 public static DeleteService getInstance() { return instance; }
 
// delete.jsp에서 삭제할 글 번호를 넘겨받고 mapper를 얻어오는 메소드
 public void delete(int idx) {
  SqlMapClient mapper = MyAppSqlConfig.getSqlMapInstance();
  try {
   GuestbookDAO.getInstance().delete(mapper, idx);
  } catch (SQLException e) {
   e.printStackTrace();
  }
 }
}


>>InsertService


package kr.koreait.Service;

import java.sql.SQLException;

import com.ibatis.sqlmap.client.SqlMapClient;

import kr.koreait.DAO.GuestbookDAO;
import kr.koreait.VO.GuestbookVO;
import kr.koreait.ibatis.MyAppSqlConfig;

public class InsertService {

// 하나의 프로그램에 단 한 개의 객체만 있으면 되는 클래스는 singleton 방식으로 코딩한다.
// Singleton 패턴 코딩 방법
// 1. 자기 자신의 객체를 정적 멤버로 만든다.
 private static InsertService instance = new InsertService();
 
// 2. 클래스 외부에서 객체를 생성할 수 없도록 기본 생성자의 접근 권한을 private으로 변경한다.
 private InsertService() { }
 
// 3. 자기 자신의 객체를 리턴시키는 정적 메소드를 만든다.
 public static InsertService getInstance() { return instance; }
 
// insertOK.jsp에서 테이블에 저장할 데이터가 들어있는 객체를 넘겨받고 mapper를 얻어오는 메소드
 public void insert(GuestbookVO vo) {
//  mapper를 얻어온다.
  SqlMapClient mapper = MyAppSqlConfig.getSqlMapInstance();
  try {
   GuestbookDAO.getInstance().insert(mapper, vo);
  } catch (SQLException e) {
   e.printStackTrace();
  }
 }
 
}

>>SelectService


package kr.koreait.Service;

import java.sql.SQLException;
import java.util.HashMap;

import com.ibatis.sqlmap.client.SqlMapClient;

import kr.koreait.DAO.GuestbookDAO;
import kr.koreait.VO.GuestbookList;
import kr.koreait.VO.GuestbookVO;
import kr.koreait.VO.Param;
import kr.koreait.ibatis.MyAppSqlConfig;

public class SelectService {

 private static SelectService instance = new SelectService();
 private SelectService() { }
 public static SelectService getInstance() { return instance; }
 
// list.jsp에서 화면에 표시할 페이지 번호를 넘겨받고 mapper를 얻어오는 메소드
 public GuestbookList selectList(int currentPage) {
  SqlMapClient mapper = MyAppSqlConfig.getSqlMapInstance();
  GuestbookList list = null;
  try {
//   한 페이지에 표시할 글의 개수를 정한다.
   int pageSize = 10;
//   테이블에 저장된 전체 글의 개수를 얻어온다.
   int totalCount = GuestbookDAO.getInstance().selectCount(mapper);
//   System.out.println("전체 글의 개수 : " + totalCount);
//   pageSize, totalCount, currentPage를 생성자의 인수로 넘겨서
//   결과를 저장해 리턴할 GuestbookList 객체를 생성한다.
   list = new GuestbookList(pageSize, totalCount, currentPage);
   
//   OracleDB는 limit를 사용할 수 없으므로 한 페이지의 글을 얻어오기 위해서
//   startNo와 endNo를 SQL명령으로 넘겨줘야 한다.
//   그러나, parameterClass에는 2개 이상의 값을 넘겨줄 수가 없기 때문에
//   startNo와 endNo를 HashMap 객체에 저장해서 보내준다.
   HashMap<String, Integer> hmap = new HashMap<>();
   hmap.put("startNo", list.getStartNo());
   hmap.put("endNo", list.getEndNo());
   
//   한 페이지 분량의 글을 얻어와서 GuestbookList의 ArrayList에 저장한다.
   list.setList(GuestbookDAO.getInstance().selectList(mapper, hmap));
  } catch (SQLException e) {
   e.printStackTrace();
  }
  return list;
 }
 
// list.jsp에서 화면에 표시할 페이지 번호와 검색어를 넘겨받고 mapper를 얻어오는 메소드
 public GuestbookList selectList(int currentPage, String item) {
 
  SqlMapClient mapper = MyAppSqlConfig.getSqlMapInstance();
  GuestbookList list = null;
  
  try {
   int pageSize = 10;
//   검색어를 포함한 글의 개수를 얻어온다.
   int totalCount = GuestbookDAO.getInstance().selectCount(mapper, item);
//   System.out.println(item + "을 포함한 글 : " + totalCount);
   list = new GuestbookList(pageSize, totalCount, currentPage);
   
//   startNo, endNo, item을 함께 넘겨주기 위해서 임의의 클래스의 객체를 만든다.
   Param param = new Param();
   param.setStartNo(list.getStartNo());
   param.setEndNo(list.getEndNo());
   param.setItem(item);
   
   list.setList(GuestbookDAO.getInstance().selectList(mapper, param));
   
  } catch (SQLException e) {
   e.printStackTrace();
  }
  
  return list;
  
 }
 
 
 
// selectByIdx.jsp에서 수정 또는 삭제할 글번호를 넘겨받고 mapper를 얻어오는 메소드
 public GuestbookVO selectByIdx(int idx) {
  SqlMapClient mapper = MyAppSqlConfig.getSqlMapInstance();
  GuestbookVO vo = null;
  try {
   vo = GuestbookDAO.getInstance().selectByIdx(mapper, idx);
  } catch (SQLException e) {
   e.printStackTrace();
  }
  return vo;
 }
 
}



>>UpdateService



package kr.koreait.Service;

import java.sql.SQLException;

import com.ibatis.sqlmap.client.SqlMapClient;

import kr.koreait.DAO.GuestbookDAO;
import kr.koreait.VO.GuestbookVO;
import kr.koreait.ibatis.MyAppSqlConfig;

public class UpdateService {

 private static UpdateService instance = new UpdateService();
 private UpdateService() { }
 public static UpdateService getInstance() { return instance; }
 
// updateOK.jsp에서 수정할 내용이 저장된 객체를 넘겨받고 mapper를 얻어오는 메소드
 public void update(GuestbookVO vo) {
  SqlMapClient mapper = MyAppSqlConfig.getSqlMapInstance();
  try {
   GuestbookDAO.getInstance().update(mapper, vo);
  } catch (SQLException e) {
   e.printStackTrace();
  }
 }
 
 
}


#insert.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>방명록 쓰기</title>
</head>
<body>
<!-- 방명록을 입력하는 폼(테이블) -->
<!-- 이름, 비밀번호, 내용 -->
<form action="insertOK.jsp" method="post">
<table width="600" align="center" border="1">
 <tr><th colspan="2">방명록 작성</th></tr>
 <tr>
  <td width="100" align="center">이름</td>
  <td><input type="text" name="name"/></td>
 </tr>
 <tr>
  <td align="center">비밀번호</td>
  <td><input type="password" name="password"/></td>
 </tr>
 <tr>
  <td align="center">내용</td>
  <td>
   <textarea rows="10" cols="70" name="content"></textarea>
  </td>
 </tr>
 <tr>
  <td colspan="2" align="center">
   <input type="submit" value="저장하기"/>
   <input type="reset" value="다시쓰기"/>
   <input type="button" value="목록보기" onclick="location.href='list.jsp'"/>
  </td>
 </tr>
</table>
</form>
</body>
</html>







# insertOK.jsp


<%@page import="kr.koreait.Service.InsertService"%>
<%@page import="kr.koreait.VO.GuestbookVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
// 한글이 깨지지 않도록 처리하고 insert.jsp에서 넘어오는 데이터를 받는다.
 request.setCharacterEncoding("UTF-8");
 
// String name = request.getParameter("name");
// String password = request.getParameter("password");
// String content = request.getParameter("content");
 
// GuestbookVO vo = new GuestbookVO();
// vo.setName(name);
// vo.setPassword(password);
// vo.setContent(content);
%>


<jsp:useBean id="vo" class="kr.koreait.VO.GuestbookVO">
 <jsp:setProperty property="*" name="vo"/>
</jsp:useBean>


<%


// 접속자 IP 주소를 따로 받아서 setIp로 GuestbookVO 객체에 집어넣는다.
 String ip = request.getRemoteAddr();
 vo.setIp(ip);


// 받아온 글을 테이블에 저장한다.
 InsertService.getInstance().insert(vo);

// 글을 저장했으므로 글 목록을 확인하는 페이지로 이동한다.
 response.sendRedirect("list.jsp");
// out.println(vo);
%>
<%-- ${vo} --%>
</body>
</html>



# list.jsp


<%@page import="kr.koreait.VO.GuestbookList"%>
<%@page import="kr.koreait.Service.SelectService"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
 request.setCharacterEncoding("UTF-8");
// listView1.jsp에서 넘어오는 검색어를 받는다.
 String item = request.getParameter("item");
 if(item == null) {
//  검색어가 없으면 세션에 저장된 검색어가 있는지 확인한다.
  item = (String) session.getAttribute("item");
 } else {
//  검색어가 있으면 세션에 저장한다.
  session.setAttribute("item", item);
 }

// 이전 페이지에서 넘어오는 화면에 표시할 페이지 번호를 받는다.
// 받아온 번호가 없다면 1 페이지를 출력한다.
 int currentPage = 1;
 try {
//  게시판이 처음 실행되었을 경우 또는 글을 저장하고 list.jsp로 왔을 경우에는 넘어오는 내용이 없다. (Exception 발생
  currentPage = Integer.parseInt(request.getParameter("currentPage"));
 } catch(Exception e) { }
 
// 테이블에서 페이지 번호에 해당하는 한 페이지 분량의 글을 얻어온다.
 GuestbookList list = null;
 if(item == null || item.trim().length() == 0) {
  list = SelectService.getInstance().selectList(currentPage);
 } else {
  list = SelectService.getInstance().selectList(currentPage, item);
 }
 request.setAttribute("list", list);
 request.setAttribute("rn", "\r\n");
 pageContext.forward("listView1.jsp");
 
%>


</body>
</html>


# listView.jsp


<%@page import="java.text.SimpleDateFormat"%>
<%@page import="kr.koreait.VO.GuestbookVO"%>
<%@page import="kr.koreait.VO.GuestbookList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>방명록</title>
</head>
<body>
<%
// list.jsp에서 request 영역에 저장되어 넘어오는 내용을 받는다.
 GuestbookList list = (GuestbookList)request.getAttribute("list");
%>

<table width="700" align="center" border="1">
 <tr><th>방명록</th></tr>
 <tr>
  <td align="right">
   <%=list.getTotalCount()%>(<%=list.getCurrentPage()%>/<%=list.getTotalPage()%>)pages
  </td>
 </tr>
 <tr>
  <td>
<%
   SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd(E)");
//   화면에 표시할 글이 저장된 ArrayList의 크기만큼 반복해서 글을 출력한다.
   for(int i=0; i<list.getList().size(); i++) {
//    ArrayList에 저장된 글 중에서 화면에 표시할 글을 한 건 얻어온다.
    GuestbookVO vo = list.getList().get(i);
%>
    <table width="100%" align="center" border="1">
     <tr>
      <td bgcolor="#a4b244">
       (<%=vo.getIdx()%>) <%=vo.getName()%>님이 <%=sdf.format(vo.getWriteDate())%>에 남긴 글
      </td>
     </tr>
     <tr>
      <td> 
       <!-- 태그 허용, 줄바꿈 불가능 -->
       <%-- <%=vo.getContent()%> --%>
       <!-- 태그 허용, 줄바꿈 가능 -->       
       <%-- <%=vo.getContent().replace("\r\n", "<br/>")%> --%>
       <!-- 태그 무시, 줄바꿈 불가능 -->
       <%-- <%=vo.getContent().replace("<", "&lt;").replace(">", "&gt;")%> --%>
       <!-- 태그 무시, 줄바꿈 가능 (순서가 중요) -->
       <%-- <%=vo.getContent().replace("<", "&lt;").replace(">", "&gt;").replace("\r\n", "<br/>")%> --%>
       <%=vo.getContent().replace("<", "&lt;").replace(">", "&gt;").replace("\r\n", "<br/>")%>
      </td>
     </tr>
    </table>
<%
   }
%>   
  </td>
 </tr>
 
 <tr>
  <td align="center">
<%
   if(list.getStartPage() > 1) {
     out.println("<input type='button' value='start' onclick='location.href=\"?currentPage=1\"'/>");
     out.println("<input type='button' value='-10' onclick='location.href=\"?currentPage="
         + (list.getStartPage() - 1) + "\"'/>");
   } else {
    out.println("<input type='button' value='start' disabled='disabled'/>");
    out.println("<input type='button' value='-10' disabled='disabled'/>");
   }
 
   if(list.getCurrentPage() > 1) {
     out.println("<input type='button' value='-1' onclick='location.href=\"?currentPage="
         + (list.getCurrentPage() - 1) + "\"'/>");
   } else {
    out.println("<input type='button' value='-1' disabled='disabled'/>");
   }

   for(int i=list.getStartPage(); i<=list.getEndPage(); i++) {
    if(i == list.getCurrentPage()) {
     out.println("<input type='button' value='" + i + "' disabled='disabled'/>");
    } else {
     out.println("<input type='button' value='" + i
         + "' onclick='location.href=\"?currentPage=" + i + "\"'/>");
    }
   }

   if(list.getCurrentPage() < list.getTotalPage()) {
     out.println("<input type='button' value='+1' onclick='location.href=\"?currentPage="
         + (list.getCurrentPage() + 1) + "\"'/>");
   } else {
    out.println("<input type='button' value='+1' disabled='disabled'/>");
   }

   if(list.getEndPage() < list.getTotalPage()) {
    out.println("<input type='button' value='+10' onclick='location.href=\"?currentPage="
        + (list.getEndPage() + 1) + "\"'/>");
    out.println("<input type='button' value='end' onclick='location.href=\"?currentPage="
        + list.getTotalPage() + "\"'/>");
   } else {
    out.println("<input type='button' value='+10' disabled='disabled'/>");
    out.println("<input type='button' value='end' disabled='disabled'/>");
   }
   
%>   
  </td>
 </tr>
 <tr>
  <td align="right">
   <input type="button" value="새글쓰기" onclick="location.href='insert.jsp"/>
  </td>
 </tr>

</table>


</body>
</html>



# listView1.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>   <!-- 제어문 -->
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>  <!-- 날짜, 숫자 서식 -->
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> <!-- 함수 -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>방명록 ver.2</title>
<style type="text/css">
 table {border: 2px solid #a4b244;}
 th {font-size: 22pt; color: #a4b244;}
 tr {height: 30px;}
 td.title {color: #ffffff;}
</style>
</head>
<body>
<table width="700" align="center" border="0">
 <tr><th>방명록</th></tr>
 <tr>
  <td align="right">
   ${list.totalCount}(${list.currentPage}/${list.totalPage})pages
  </td>
 </tr>
 <tr>
  <td>
   <!-- 일반 for -->
   <!-- for(int i=0; i<list.getList().size(); i++) -->
   <%-- <c:forEach var="제어변수" begin="초기치" end="최종치" step="증감치"> --%>
   <%-- <c:forEach var="i" begin="0" end="${list.list.size()-1}" step="1"> --%>

   <!-- 향상된 for -->
   <!-- for(GuestbookVO vo : list.getList()) -->
   <%-- <c:forEach var="변수" items="ArrayList 이름"> --%>
   <c:forEach var="vo" items="${list.list}">
    <table width="100%" align="center" border="0" cellspacing="0">
     <tr>
      <td bgcolor="#a4b244" width="600" class="title">
       (${vo.idx}) ${vo.name}님이
       <fmt:formatDate value="${vo.writeDate}" pattern="yyyy-MM-dd(E) HH:mm"/>에 남긴 글
      </td>
      <td bgcolor="#a4b244" width="100">
       <input type="button" value="수정"
       onclick="location.href='selectByIdx.jsp?idx=${vo.idx}&currentPage=${list.currentPage}&job=update'"/>
       <input type="button" value="삭제"
       onclick="location.href='selectByIdx.jsp?idx=${vo.idx}&currentPage=${list.currentPage}&job=delete'"/>
      </td>
     </tr>
     <tr>
      <td colspan="2">
       <c:set var="content" value="${fn:replace(vo.content, '<', '&lt;')}"/>
       <c:set var="content" value="${fn:replace(content, '>', '&gt;')}"/>
       <c:set var="content" value="${fn:replace(content, rn, '<br/>')}"/>
       ${content}
      </td>
     </tr>
    </table>
   </c:forEach>
  </td>
 </tr>
 
 <tr>
  <td align="center">
  
   <!-- startPage가 1보다 크면 이전 10개 페이지가 있다. -->
   <c:if test="${list.startPage > 1}">
    <input type="button" value="start" onclick="location.href='?currentPage=1'"/>
    <input type="button" value="-10" onclick="location.href='?currentPage=${list.startPage - 1}'"/>
   </c:if>
   <c:if test="${list.startPage == 1}">
    <input type="button" value="start" disabled="disabled"/>
    <input type="button" value="-10" disabled="disabled"/>
   </c:if>
  
   <!-- 현재 페이지가 1보다 크면 이전 페이지가 있다. -->
   <c:if test="${list.currentPage > 1}">
    <input type="button" value="-1" onclick="location.href='?currentPage=${list.currentPage - 1}'"/>
   </c:if>
   <c:if test="${list.currentPage == 1}">
    <input type="button" value="-1" disabled="disabled"/>
   </c:if>
   
   <!-- 페이지 이동 버튼 -->
   <c:forEach var="i" begin="${list.startPage}" end="${list.endPage}" step="1">
    <c:if test="${i == list.currentPage}">
     <input type="button" value="${i}" disabled="disabled"/>
    </c:if>
    <c:if test="${i != list.currentPage}">
     <input type="button" value="${i}" onclick="location.href='?currentPage=${i}'"/>
    </c:if>
   </c:forEach>
   
   <!-- 현재 페이지가 totalPage보다 작으면 다음 페이지가 있다. -->
   <c:if test="${list.currentPage < list.totalPage}">
    <input type="button" value="+1" onclick="location.href='?currentPage=${list.currentPage + 1}'"/>
   </c:if>
   <c:if test="${list.currentPage == list.totalPage}">
    <input type="button" value="+1" disabled="disabled"/>
   </c:if>
   
   <!-- endPage가 totalPage보다 작으면 다음 10개 페이지가 있다. -->
   <c:if test="${list.endPage < list.totalPage}">
    <input type="button" value="+10" onclick="location.href='?currentPage=${list.endPage + 1}'"/>
    <input type="button" value="end" onclick="location.href='?currentPage=${list.totalPage}'"/>
   </c:if>
   <c:if test="${list.endPage == list.totalPage}">
    <input type="button" value="+10" disabled="disabled"/>
    <input type="button" value="end" disabled="disabled"/>
   </c:if>
   
  </td>
 </tr>
 <!-- 검색어 입력받는 폼 -->
 <tr>
  <td align="center">
   <form action="list.jsp" method="post">
    <input type="text" name="item"/>
    <input type="submit" value="찾기"/>
   </form>
  </td> 
 </tr>
 <tr>
  <td align="right">
   <input type="button" value="새글쓰기" onclick="location.href='insert.jsp'"/>
  </td>
 </tr>

</table>
</body>
</html>


# krkoreait.VO >> GuestbookList.java


package kr.koreait.VO;

import java.util.ArrayList;

// 화면에 표시할 한 페이지 분량의 데이터와 페이지 작업에 사용할 8개의 변수를 기억하는 클래스
public class GuestbookList {

// 한 페이지 분량의 글을 기억할 ArrayList
 private ArrayList<GuestbookVO> list = new ArrayList<>();
 
// 페이지 작업에 사용할 변수
 private int pageSize;     // 한 페이지에 표시할 글의 개수
 private int totalCount;     // 테이블에 저장된 전체 글의 개수
 private int totalPage;     // 전체 페이지 개수
 private int currentPage;    // 현재 화면에 표시할 페이지 번호
 private int startNo;     // 화면에 표시할 글의 시작 인덱스
 private int endNo;      // 화면에 표시할 글의 마지막 인덱스
 private int startPage;     // 화면에 표시할 페이지 이동 하이퍼링크의 시작 번호
 private int endPage;     // 화면에 표시할 페이지 이동 하이퍼링크의 끝 번호
 
 public GuestbookList() { }

// pageSize, totalCount, currentPage를 받아서 초기화하고 나머지 변수는 계산해서 초기화하는 생성자
 public GuestbookList(int pageSize, int totalCount, int currentPage) {
  this.pageSize = pageSize;
  this.totalCount = totalCount;
  this.currentPage = currentPage;
  calculation();
 }

 private void calculation() {
  totalPage = (totalCount - 1) / pageSize + 1;
  currentPage = currentPage > totalPage ? totalPage : currentPage;
//  OracleDB의 시작인덱스는 0이 아니라 1이다. (mysql은 0부터 시작)
  startNo = (currentPage - 1) * pageSize + 1;
  endNo = startNo + pageSize - 1;
  endNo = endNo > totalCount ? totalCount : endNo;
  startPage = (currentPage - 1) / 10 * 10 + 1;
  endPage = startPage + 9;
  endPage = endPage > totalPage ? totalPage : endPage;
 }

 public ArrayList<GuestbookVO> getList() {
  return list;
 }

 public void setList(ArrayList<GuestbookVO> list) {
  this.list = list;
 }

 public int getPageSize() {
  return pageSize;
 }

 public void setPageSize(int pageSize) {
  this.pageSize = pageSize;
 }

 public int getTotalCount() {
  return totalCount;
 }

 public void setTotalCount(int totalCount) {
  this.totalCount = totalCount;
 }

 public int getTotalPage() {
  return totalPage;
 }

 public void setTotalPage(int totalPage) {
  this.totalPage = totalPage;
 }

 public int getCurrentPage() {
  return currentPage;
 }

 public void setCurrentPage(int currentPage) {
  this.currentPage = currentPage;
 }

 public int getStartNo() {
  return startNo;
 }

 public void setStartNo(int startNo) {
  this.startNo = startNo;
 }

 public int getEndNo() {
  return endNo;
 }

 public void setEndNo(int endNo) {
  this.endNo = endNo;
 }

 public int getStartPage() {
  return startPage;
 }

 public void setStartPage(int startPage) {
  this.startPage = startPage;
 }

 public int getEndPage() {
  return endPage;
 }

 public void setEndPage(int endPage) {
  this.endPage = endPage;
 }

 @Override
 public String toString() {
  return "GuestbookList [list=" + list + "]";
 }
 
}

#update.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>수정할 글 확인하기</title>
<style type="text/css">
 table {border: 2px solid #a4b244;}
 th {font-size: 22pt; color: #a4b244;}
 tr {height: 30px;}
 td.title {color: #ffffff;}
</style>
</head>
<body>
<%-- ${vo} --%>
<form action="updateOK.jsp" method="post">
 <input type="hidden" name="idx" value="${vo.idx}"/>
 <input type="hidden" name="currentPage" value="${currentPage}"/>
 <table width="600" align="center" border="1">
  <tr><th colspan="4">수정할 글 확인</th></tr>
  <tr>
   <td width="100" align="center">글번호</td>
   <td width="200">${vo.idx}</td>
   <td width="100" align="center">이름</td>
   <td width="200"><input type="text" name="name" value="${vo.name}"/></td>
  </tr>
  <tr>
   <td align="center">내용</td>
   <td colspan="3">
    <textarea rows="10" cols="70" name="content">${vo.content}</textarea>
   </td>
  </tr>
  <tr>
   <td colspan="4" align="center">
    비밀번호 <input type="password" name="password"/>
    <input type="submit" value="수정하기"/>
    <input type="reset" value="다시쓰기"/>
    <input type="button" value="돌아가기" onclick="location.href='list.jsp?currentPage=${currentPage}'"/>
   </td>
  </tr>
 </table>
</form>
</body>
</html>


#updateOK.jsp


<%@page import="kr.koreait.Service.UpdateService"%>
<%@page import="kr.koreait.Service.SelectService"%>
<%@page import="kr.koreait.VO.GuestbookVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
// 넘어오는 데이터에 한글이 포함될 수 있으므로 한글이 깨지지 않도록 한다.
 request.setCharacterEncoding("UTF-8");

// update.jsp에서 넘어오는 데이터를 받는다.
 int currentPage = Integer.parseInt(request.getParameter("currentPage"));
// int idx = Integer.parseInt(request.getParameter("idx"));
// String password = request.getParameter("password");
// String name = request.getParameter("name");
// String content = request.getParameter("content");
%>
<!-- 수정할 내용이 담긴 객체를 만든다. -->
<jsp:useBean id="guest" class="kr.koreait.VO.GuestbookVO">
 <jsp:setProperty property="*" name="guest"/>
</jsp:useBean>

<%
// 비밀번호를 비교하기 위해서 idx에 해당하는 글을 얻어온다.
 GuestbookVO vo = SelectService.getInstance().selectByIdx(guest.getIdx());

// 꺼내온 글의 비밀번호와 입력한 비밀번호를 비교해서 일치하면 수정 처리해준다.
// 일치하지 않으면 목록으로 돌아간다.
 out.println("<script>");
 if(vo.getPassword().trim().equals(guest.getPassword().trim())) {

  UpdateService.getInstance().update(guest);
  
  out.println("alert('" + guest.getIdx() + " 번 글 수정 완료!')");
 } else {
  out.println("alert('비밀번호가 올바르지 않습니다.')");
 }
 out.println("location.href='list.jsp?currentPage=" + currentPage +"'");
 out.println("</script>");

%>
</body>
</html>


#selectByIdx.jsp



<%@page import="kr.koreait.Service.SelectService"%>
<%@page import="kr.koreait.VO.GuestbookVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
// listView1.jsp에서 넘어오는 내용을 받는다.
 String tempIdx = request.getParameter("idx");
 String tempPage = request.getParameter("currentPage");
 String job = request.getParameter("job");
 
// 삭제 또는 수정할 글 번호나 돌아갈 페이지 번호가 null인지 검사한다.
 if(tempIdx != null && tempPage != null) {
//  삭제 또는 수정할 글 번호나 돌아갈 페이지 번호가 숫자인지 검사한다.
  try {
   int idx = Integer.parseInt(tempIdx);
   int currentPage = Integer.parseInt(tempPage);
   
//   삭제 또는 수정할 글 한 건을 테이블에서 얻어온다.   
   GuestbookVO vo = SelectService.getInstance().selectByIdx(idx);
//   out.println(vo + "<br/>");

//   삭제 또는 수정할 글 번호에 해당하는 글이 있는지 검사한다.
   if(vo != null) {
    
//    오류가 발견되지 않았으므로 얻어온 글을 request 영역에 저장해서 다음 페이지로 넘겨준다.
    request.setAttribute("vo", vo);
    request.setAttribute("currentPage", currentPage);
    pageContext.forward(job + ".jsp");
    
   } else {
    out.println("<script>");
    out.println("alert('수정 또는 삭제할 글이 존재하지 않습니다.')");
    out.println("location.href='list.jsp?currentPage=" + currentPage + "'");
    out.println("</script>");
   }
  } catch(Exception e) {
   out.println("<script>");
   out.println("alert('수정 또는 삭제할 글 번호나 돌아갈 페이지가 숫자가 아닙니다.')");
   out.println("location.href='list.jsp'");
   out.println("</script>");
  }
 } else {
  out.println("<script>");
  out.println("alert('수정 또는 삭제할 글 번호나 돌아갈 페이지가 없습니다.')");
  out.println("location.href='list.jsp'");
  out.println("</script>");
 }

%>
</body>
</html>



#delete.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>삭제할 글 확인하기</title>
<style type="text/css">
 table {border: 2px solid #a4b244;}
 th {font-size: 22pt; color: #a4b244;}
 tr {height: 30px;}
 td.title {color: #ffffff;}
</style>
</head>
<body>
<%-- ${vo} --%>
<form action="deleteOK.jsp" method="post">
 <input type="hidden" name="idx" value="${vo.idx}"/>
 <input type="hidden" name="currentPage" value="${currentPage}"/>
 <table width="600" align="center" border="1">
  <tr><th colspan="4">삭제할 글 확인</th></tr>
  <tr>
   <td width="100" align="center">글번호</td>
   <td width="200">${vo.idx}</td>
   <td width="100" align="center">이름</td>
   <td width="200">${vo.name}</td>
  </tr>
  <tr>
   <td align="center">내용</td>
   <td colspan="3">
    <textarea rows="10" cols="70" readonly="readonly">${vo.content}</textarea>
   </td>
  </tr>
  <tr>
   <td colspan="4" align="center">
    비밀번호 <input type="password" name="password"/>
    <input type="submit" value="삭제하기"/>
    <input type="reset" value="다시쓰기"/>
    <input type="button" value="돌아가기" onclick="location.href='list.jsp?currentPage=${currentPage}'"/>
   </td>
  </tr>
 </table>
</form>
</body>
</html>


#deleteOK.jsp



<%@page import="kr.koreait.Service.DeleteService"%>
<%@page import="kr.koreait.Service.SelectService"%>
<%@page import="kr.koreait.VO.GuestbookVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
// delete.jsp에서 넘어오는 데이터를 받는다.
 int idx = Integer.parseInt(request.getParameter("idx"));
 int currentPage = Integer.parseInt(request.getParameter("currentPage"));
 String password = request.getParameter("password");

// 비밀번호를 비교하기 위해서 idx에 해당하는 글을 얻어온다.
 GuestbookVO vo = SelectService.getInstance().selectByIdx(idx);

// 꺼내온 글의 비밀번호와 입력한 비밀번호를 비교해서 일치하면 삭제 처리해준다.
// 일치하지 않으면 목록으로 돌아간다.
 out.println("<script>");
 if(vo.getPassword().trim().equals(password.trim())) {
  DeleteService.getInstance().delete(idx);
  out.println("alert('" + idx + " 번 글 삭제 완료!')");
 } else {
  out.println("alert('비밀번호가 올바르지 않습니다.')");
 }
 out.println("location.href='list.jsp?currentPage=" + currentPage +"'");
 out.println("</script>");

%>
</body>
</html>



공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/04   »
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
글 보관함