CRUD 준비과정

  • 프로젝트 생성
  • 자바 리소스 라이브러리 변경
    • Java Resources > Libraries > JRE System Library > Properties > Workspace default JRE(jdk 1.8.0_251)

오라클 데이터 컬럼 선언

  • 경로 : [com.sist.dao] - BoardVO

BoardVO

  • 데이터형, 변수명 선언
package com.sist.dao;

import java.util.Date;

public class BoardVO {
	private int no;
	private String name;
	private String subject;
	private String content;
	private String pwd;
	private Date regdate;
	private int hit;
}
  • 캡슐화
package com.sist.dao;

import java.util.Date;

public class BoardVO {
	private int no;
	private String name;
	private String subject;
	private String content;
	private String pwd;
	private Date regdate;
	private int hit;
	public int getNo() {
		return no;
	}
	public void setNo(int no) {
		this.no = no;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSubject() {
		return subject;
	}
	public void setSubject(String subject) {
		this.subject = subject;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	public Date getRegdate() {
		return regdate;
	}
	public void setRegdate(Date regdate) {
		this.regdate = regdate;
	}
	public int getHit() {
		return hit;
	}
	public void setHit(int hit) {
		this.hit = hit;
	}
	
}

오라클 연결

  • 경로 : [com.sist.dao] - [BoardDAO] - BoardDAO() , getConnection() , disConnection()

BoardDAO()

package com.sist.dao;

import java.util.*;
import java.sql.*;

public class BoardDAO {
         // 연결 
	private Connection conn; // 오라클 연결 클래스

	 // SQL문장을 전송 
	private PreparedStatement ps; 

	 // 오라클 주소 첨부 
	private final String URL="jdbc:oracle:thin:@localhost:1521:XE";

	 // 연결 준비 
	 // 드라이버 등록 
	public BoardDAO()
	{
		try
		{
			Class.forName("oracle.jdbc.driver.OracleDriver");
		}catch(Exception ex)
		{
			System.out.println(ex.getMessage());
		}
	}

}

getConnection()

package com.sist.dao;

import java.util.*;
import java.sql.*;

public class BoardDAO {

	public BoardDAO()
	{
	    // 생략
	}

	// 연결/닫기 반복 => 기능이 반복일 경우 => 메소드로 처리
	public void getConnection()
	{
		try
		{
			conn=DriverManager.getConnection(URL,"hr","happy");
		}catch(Exception ex) {}
	}
	
}

disConnection()

package com.sist.dao;

import java.util.*;
import java.sql.*;

public class BoardDAO {

	public BoardDAO()
	{

	}
	// 연결/닫기 반복 => 기능이 반복일 경우 => 메소드로 처리
	public void getConnection()
	{

	}
	public void disConnection()
	{
		try
		{
			if(ps!=null) ps.close();
			if(conn!=null) conn.close();
		}catch(Exception ex) {}
	}
}

게시물 목록

1. 오라클 데이터와 게시글 목록 연결

  • 경로 : [com.sist.dao] - [BoardDAO] - boardListData()
package com.sist.dao;

import java.util.*;
import java.sql.*;

public class BoardDAO {

	public BoardDAO()
	{

	}
	// 연결/닫기 반복 => 기능이 반복일 경우 => 메소드로 처리
	public void getConnection()
	{

	}
	public void disConnection()
	{

	}

	// 기능 
	// 1. 목록 (게시판) => SELECT
	public ArrayList<BoardVO> boardListData()  // 리턴형이 ArrayList이고 <BoardVO>클래스를 받는 메서드
	{
		ArrayList<BoardVO> list=
				new ArrayList<BoardVO>();
		try
		{
			// 연결
			getConnection();
			// SQL문장 전송 
			String sql="SELECT no,subject,name,regdate,hit FROM freeboard ORDER BY no DESC";
			          // 최신 등록된 게시물 먼저 출력
			          // ORDER BY => 단점 (속도가 늦다) => INDEX를 사용권장
			ps=conn.prepareStatement(sql);

			// SQL실행후에 결과값 받기
			/* <executeQuery()> 
			   1. 수행결과로 ResultSet 객체의 값을 반환합니다.
			   2. SELECT 구문을 수행할 때 사용되는 함수입니다.
			*/

			/* <resultset> 은 원래 recordset이었음
			   근데 ms에서 먼저써서 클래스 이름 바뀜
			*/

			ResultSet rs=ps.executeQuery();

			// 결과값을 => ArrayList에 첨부
			/* next() : sql record 한줄씩 읽어오는 클래스임
			   - rs.next() : 출력한 첫번쨰줄부터 마지막줄까지 읽어온다
			*/
			while(rs.next()) // 출력한 첫번째줄부터 마지막줄까지 읽어 온다
			{
				BoardVO vo=new BoardVO();
				vo.setNo(rs.getInt(1));
				vo.setSubject(rs.getString(2));
				vo.setName(rs.getString(3));
				vo.setRegdate(rs.getDate(4));
				vo.setHit(rs.getInt(5));
				
				list.add(vo);
			}
			rs.close();
		}catch(Exception ex)
		{
			System.out.println(ex.getMessage());
		}
		finally
		{
			disConnection();
		}
		return list;
	}
}

2. 오라클 연결된 목록 웹으로 출력

  • 경로 : [com.sist.board] - [BoardList] - doget()

게시글 목록 컬럼까지만 출력

  • table-hover css활용
    (https://www.w3schools.com/bootstrap/tryit.asp?filename=trybs_table_contextual&stacked=h)
package com.sist.board;

import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;//ArrayList
import com.sist.dao.*;

@WebServlet("/BoardList")
public class BoardList extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		// 브라우저에서 실행하는 화면 => HTML
		// 브라우저에 알림 => HTML문서를 전송할 것이다 
		response.setContentType("text/html;charset=EUC-KR");

		// HTML을 브라우저로 전송 시작 
		PrintWriter out=response.getWriter();

		out.println("<html>");
		out.println("<head>");
		out.println("<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css\">");
		out.println("<style type=text/css>");
		out.println(".row {margin:0px auto;width:700px}");
		out.println("h2 {text-align:center}");
		out.println("</style>");
		out.println("</head>");

		out.println("<body>");
		out.println("<div class=container>");
		out.println("<h2>자유게시판</h2>");
		out.println("<div class=row>");
		
		// 새글 작성하는 버튼
		out.println("<table class=\"table\">");
		out.println("<tr>");
		out.println("<td>");
		out.println("<a href=BoardInsert class=\"btn btn-sm btn-success\">새글</a>");
		out.println("</td>");
		out.println("</tr>");
		out.println("</table>");
		
		out.println("<table class=\"table table-hover\">");
		out.println("<tr class=danger>");
		out.println("<th class=text-center width=10%>번호</th>");
		out.println("<th class=text-center width=45%>제목</th>");
		out.println("<th class=text-center width=15%>이름</th>");
		out.println("<th class=text-center width=20%>작성일</th>");
		out.println("<th class=text-center width=10%>조회수</th>");
		out.println("</tr>");
		out.println("</table>");
		
		out.println("</div>");
		out.println("</div>");
		out.println("</body>");
		out.println("</html>");
		
	}

}

게시글 목록 데이터까지 출력

package com.sist.board;

import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;//ArrayList
import com.sist.dao.*;

@WebServlet("/BoardList")
public class BoardList extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		// 출력 
		BoardDAO dao=new BoardDAO(); // 출력할 데이터가 있는 클래스 객체 생성

		ArrayList<BoardVO> list=dao.boardListData(); // 출력할 데이터가 담긴 배열 배열 객체 생성

		for(BoardVO vo:list) // list 배열에 담긴 데이터 출력하는 for-each문
		{
			// 1. 게시글 번호
			out.println("<tr>");
			out.println("<td class=text-center width=10%>"+vo.getNo()+"</td>");

			// 2. 게시글 제목 : 제목을 클릭하면 게시글 상세 링크로 넘어감
			out.println("<td class=text-left width=45%>"
			+"<a href=BoardDetail?no="+vo.getNo()+">"
			/* a 태그 역할 : no라는 매개변수를 주겠다... 웹주소 끝에 글번호 삽입
			   실행결과 : http://localhost/20200814-CURDProject/BoardDetail?no=12
			*/
			+vo.getSubject()+"</a></td>");

			// 3. 게시글 작성자 
			out.println("<td class=text-center width=15%>"+vo.getName()+"</td>");

			// 4. 게시글 작성일 : Date 형식이라서 String으로 형변환 
			out.println("<td class=text-center width=20%>"+vo.getRegdate().toString()+"</td>");

			// 5. 게시글 조회수 
			out.println("<td class=text-center width=10%>"+vo.getHit()+"</td>");
			out.println("</tr>");
		}
		out.println("</table>");
		out.println("<hr>"); // 가로 경계선
		
	}

}

추가 버튼 생성

package com.sist.board;

import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;//ArrayList
import com.sist.dao.*;

@WebServlet("/BoardList")
public class BoardList extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		out.println("<table class=\"table\">");
		out.println("<tr>");

		// 게시글 찾기		
		out.println("<td class=text-left>");
		out.println("Search:");
		out.println("<select class=input-sm>");
		out.println("<option>이름</option>");
		out.println("<option>제목</option>");
		out.println("<option>내용</option>");
		out.println("</select>");
		out.println("<input type=text size=15 class=input-sm>");
		out.println("<input type=button value=찾기 class=\"btn btn-sm btn-danger\">");
		out.println("</td>");
		
		// 페이지 목록
		out.println("<td class=text-right>");
		out.println("<a href=BoardInsert class=\"btn btn-sm btn-primary\">이전</a>");
		out.println("0 page / 0 pages");
		out.println("<a href=BoardInsert class=\"btn btn-sm btn-primary\">다음</a>");
		out.println("</td>");
		
		out.println("</tr>");
		out.println("</table>");
		
		out.println("</div>");
		out.println("</div>");
		out.println("</body>");
		out.println("</html>");
		
	}

}

새글 글쓰기

1. 웹에서 요청받고 처리한 뒤 웹으로 출력

  • 경로 : [com.sist.board] - [BoardInsert] - doGet() , doPost()

    doGet()

  • 화면 출력 폼
package com.sist.board;

import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sist.dao.*;

@WebServlet("/BoardInsert")
public class BoardInsert extends HttpServlet {
	private static final long serialVersionUID = 1L;


	// 폼작업(화면출력)
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
				// 브라우저에서 실행하는 화면 => HTML
				// 브라우저에 알림 => HTML문서를 전송할 것이다 
				response.setContentType("text/html;charset=EUC-KR");
				// HTML을 브라우저로 전송 시작 
				PrintWriter out=response.getWriter();

				out.println("<html>");
				out.println("<head>");
				out.println("<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css\">");
				out.println("<style type=text/css>");
				out.println(".row {margin:0px auto;width:500px}");
				out.println("h2 {text-align:center}");
				out.println("</style>");
				out.println("</head>");
				out.println("<body>");
				out.println("<div class=container>");
				out.println("<h2>글쓰기</h2>");
				out.println("<div class=row>");
				
				/* do post 호출 : dopost에 입력한 값을 보내기 
				 전송방식 (1) 감춰서 post 보안에 조음(2) 노출해서 get */
				out.println("<form method=post action=BoardInsert>");

				out.println("<table class=\"table\">");
				out.println("<tr>");
				out.println("<td width=15% class=text-right>이름</td>");
				out.println("<td width=8% class=text-right>");
				out.println("<input type=text size=15 class=input-sm name=name>");
				out.println("</td>");
				out.println("</tr>");
				
				out.println("<tr>");
				out.println("<td width=15% class=text-right>제목</td>");
				out.println("<td width=85% class=text-right>");
				out.println("<input type=text size=15 class=input-sm name=subject>");
				out.println("</td>");
				out.println("</tr>");
				
				out.println("<tr>");
				out.println("<td width=15% class=text-right>내용</td>");
				out.println("<td width=85%>");
				out.println("<textarea cols=50 rows=10 name=content></textarea>");
				out.println("</td>");
				out.println("</tr>");
				
				out.println("<tr>");
				out.println("<td width=15% class=text-right>비밀번호</td>");
				out.println("<td width=85% class=text-right>");
				out.println("<input type=password size=10 class=input-sm name=pwd>"); // name은 입력 받은 데이터들을 구분할 수 있게 별칭을 준 것임
				out.println("</td>");
				out.println("</tr>");
				
				// 글쓰기, 취소 버튼
				out.println("<tr>");
				out.println("<td colspan=2 class=text-center>");
				out.println("<input type=submit class=\"btn btn-sm dtn-danger\" value=글쓰기>");
				out.println("<input type=submit class=\"btn btn-sm dtn-info\" value=취소  oneclick=\"javascript:history.back()\">");
				out.println("</td>");
				out.println("</tr>");
				
				out.println("</table>");
				out.println("</form>");
				
				out.println("</div>");
				out.println("</div>");
				out.println("</body>");
				out.println("</html>");
	}
}

doPost()

package com.sist.board;

import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sist.dao.BoardDAO;
import com.sist.dao.BoardVO;


@WebServlet("/BoardInsert")
public class BoardInsert extends HttpServlet {
	private static final long serialVersionUID = 1L;

	// 데이터베이스 연결 => 요청처리
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		/* request에 사용자가 요청한 값이 담겨 있는데, 
		   여기서 값을 가져와야함
		   반대로 HTML 보낼떄는 response에 담아서 보내면됨~!
		*/
		
		// 한글은 디코딩해야함
		try {
			request.setCharacterEncoding("EUC-KR");
		} catch (Exception e) {
			// TODO: handle exception
		}

		// 사용자가 입력한 값을 String으로 받기		
		String name=request.getParameter("name");
		String subject=request.getParameter("subject");
		String content=request.getParameter("content");
		String pwd=request.getParameter("pwd");

		// 받아둔 값을 vo에 담기
		BoardVO vo= new BoardVO();
		vo.setName(name);
		vo.setSubject(subject);
		vo.setContent(content);
		vo.setPwd(pwd);
		
		/* DAO로 vo에 묶은 값들을 전달하고 
		  => INSERT하라고 SQL문장 전송해서
		  => 오라클 데이터에 쌓으면됨
		*/
		BoardDAO dao=new BoardDAO();
		dao.boardInsert(vo);
		
		// 데이터 쌓고나서 다시 목록 화면으로 이동하도록 처리
		response.sendRedirect("BoardList");

	}

}

2. 오라클 데이터와 새글 데이터 연결

  • 경로 : [com.sist.dao] - [BoardDAO] - boardInsert(BoardVO vo)

boardInsert(BoardVO vo)

package com.sist.dao;

import java.util.*;
import java.sql.*;

public class BoardDAO {
	// 3. 글쓰기    => INSERT
	public void boardInsert(BoardVO vo)
	{
		try {
			getConnection();
			String sql="INSERT INTO freeboard(no,name,subject,content,pwd) "
					+ "VALUES((SELECT NVL(MAX(no)+1,1) FROM freeboard),?,?,?,?)";
				         /* 새글쓰면 no는 자동으로 증가 (최대값에 +1시키기) 
				            null+1=null이 되므로 NVL로 null값을 1로 변환시키기
				         */
			ps=conn.prepareStatement(sql);
			
			ps.setString(1, vo.getName()); // 첫번째 물음표자리에 이름넣기
			ps.setString(2, vo.getSubject()); // 두번째 물음표 자리에 제목넣기
			ps.setString(3, vo.getContent()); // 세번째 물음표 자리에 내용넣기
			ps.setString(4, vo.getPwd());  // 네번째 물음표 자리에 비밀번호 넣기
			
			/* executequery와 차이점 : 
			   executeUpdate()은 autocommit!(insert,update,delete가 사용)
			/=*/
			ps.executeUpdate();
		} catch (Exception e) {
			
		} finally {
			disConnection();
		}
		
	}
}

게시글 상세보기

1. 오라클 데이터와 게시글 상세보기 연결

  • 경로 : [com.sist.dao] - [BoardDAO] - boardDetail(int no)
package com.sist.dao;
import java.util.*;
import java.sql.*;
public class BoardDAO {

	public BoardDAO()
	{

	}
	// 연결/닫기 반복 => 기능이 반복일 경우 => 메소드로 처리
	public void getConnection()
	{

	}
	public void disConnection()
	{

	}

	// 2. 내용보기  => SELECT (WHERE) ?no=1
	public BoardVO boardDetail(int no)
	{
		BoardVO vo = new BoardVO();
		try {
			getConnection();

			// 1. 조회수 증가
			String sql="UPDATE freeboard SET hit=hit+1 WHERE no=?";
			ps=conn.prepareStatement(sql);

			// 물음표에 값채우기
			ps.setInt(1, no);
			
			// 실행
			ps.executeUpdate();
			
			// 2. 내용볼 데이터를 가지고 온다
			sql="SELECT no,name,subject,content,regdate,hit FROM freeboard WHERE no=?";
			ps=conn.prepareStatement(sql);
			ps.setInt(1, no);
			
			ResultSet rs=ps.executeQuery();

			rs.next();
			vo.setNo(rs.getInt(1));
			vo.setName(rs.getString(2));
			vo.setSubject(rs.getString(3));
			vo.setContent(rs.getString(4));
			vo.setRegdate(rs.getDate(5));
			vo.setHit(rs.getInt(6));
			
			
		} catch (Exception e) {
			System.out.println(e.getMessage());
			
		} finally {
			disConnection();
		}
		
		return vo;
	}

}

2. 오라클 데이터와 게시글 상세보기 연결

  • 경로 : [com.sist.board] - [BoardDetail] - doGet()
package com.sist.board;

import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sist.dao.*;


@WebServlet("/BoardDetail")
public class BoardDetail extends HttpServlet {
	private static final long serialVersionUID = 1L;


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 브라우저에서 실행하는 화면 => HTML
		// 브라우저에 알림 => HTML문서를 전송할 것이다 
		response.setContentType("text/html;charset=EUC-KR");
		// HTML을 브라우저로 전송 시작 
		PrintWriter out=response.getWriter();
		
		// 번호 받아서 boardDetail() vo에 넣어주기
		String no=request.getParameter("no");
		BoardDAO dao= new BoardDAO();
		BoardVO vo=dao.boardDetail(Integer.parseInt(no));
		
		// 화면출력		
		out.println("<html>");
		out.println("<head>");
		out.println("<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css\">");
		out.println("<style type=text/css>");
		out.println(".row {margin:0px auto;width:600px}");
		out.println("h2 {text-align:center}");
		out.println("</style>");
		out.println("</head>");
		out.println("<body>");
		out.println("<div class=container>");
		out.println("<h2>내용보기</h2>");
		out.println("<div class=row>");
		
		out.println("<table class=\"table\">");
		
		out.println("<tr>");
		out.println("<td class=\"success text-center\" width=25%>번호</td>");
		out.println("<td width=25% class=text-center>"+vo.getNo()+"</td>");
		out.println("<td class=\"success text-center\" width=25%>작성일</td>");
		out.println("<td width=25% class=text-center>"+vo.getRegdate()+"</td>");
		out.println("</tr>");
		
		out.println("<tr>");
		out.println("<td class=\"success text-center\" width=25%>이름</td>");
		out.println("<td width=25% class=text-center>"+vo.getName()+"</td>");
		out.println("<td class=\"success text-center\" width=25%>조회수</td>");
		out.println("<td width=25% class=text-center>"+vo.getHit()+"</td>");
		out.println("</tr>");
		
		out.println("<tr>");
		out.println("<td class=\"success text-center\" width=25%>제목</td>");
		out.println("<td colspan=3>"+vo.getSubject()+"</td>");
		out.println("</tr>");

		// 내용작성하기
		out.println("<tr>");
		// valign : top /bottom /middle 중에 어디서 시작할건지 결정
		out.println("<td colspan=4 heigth=200 valign=top></td>");
		out.println("</tr>");
		
		// 하단 버튼
		out.println("<tr>");
		out.println("<td colspan=4 class=text-right>");
		out.println("<a href=# class=\"btn btn-xs btn-success\">수정</a>");
		out.println("<a href=# class=\"btn btn-xs btn-warning\">삭제</a>");
		out.println("<a href=BoardList class=\"btn btn-xs btn-danger\">목록</a>"); // BoardList로 이동?
		out.println("</tr>");
		
		out.println("</table>");
		out.println("</div>");
		out.println("</div>");
		out.println("</body>");
		out.println("</html>");
	}

}

기타

  • 브라우저랑 자바 연결하는 웹서버가 바로 톰캣임
  • 웹서버, 오라클은 서버가 이미 만들어져 있기 때문에 둘을 연결만 시켜주면됨
  • 그 연결을 자바 DAO(Database Access Object)가 함
  • 웹서버와 컴퓨터 화면을 연결하는 것은 html임
    • out.println();은 결과를 브라우저로 보내겠다는 뜻임
    • System.out.println();은 내 시스템 도스창으로 결과를 보내겠다라는 뜻임