Simplify JDBC of OracleSQL to JSON

OracleSQL Process

create table shop(num number(3) primary key,
sangpum varchar2(30),
color varchar2(20),
price number(5),imgname varchar2(50));
insert into shop values(seq_1.nextval,'빨간가방','red',78000,'../image/logoImg/bag04.png');
--insert 생략
  • oracle 통해 DB에 테이블(shop) 생성
  • 아래는 생성된 테이블의 결과
  • DBConnect를 위한 클래스와 메서드 가져오기(생략/0801에서 찾기)

JSP Process

<%@page import="org.json.simple.JSONArray"%>
<%@page import="org.json.simple.JSONObject"%>
<%@page import="java.sql.SQLException"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@page import="java.sql.Connection"%>
<%@page import="oracle_db.DBConnect"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
  • import 받은 java 클래스
<%
DBConnect db=new DBConnect();
Connection conn=db.getConnection();
Statement stmt=null;
ResultSet rs=null;

String sql="select * from shop order by num";
%>
  • DB의 모든 데이터를 json의 배열에 담아야 하므로 select * 명령문 사용
  • 이를 위해 ResultSet 클래스 필요
try{
stmt=conn.createStatement();
rs=stmt.executeQuery(sql);

	JSONArray arr=new JSONArray();

	while(rs.next())
	{
		String num=rs.getString("num");
		String sangpum=rs.getString("sangpum");
		String color=rs.getString("color");
		String price=rs.getString("price");
		String imgname=rs.getString("imgname");
		
		JSONObject ob=new JSONObject();
		
		ob.put("num", num);
		ob.put("sangpum", sangpum);
		ob.put("color", color);
		ob.put("price", price);
		ob.put("imgname", imgname);
		
		//array에 추가
		arr.add(ob);
	}%>
	<%=arr.toString() %> //try~catch내에 JSONObject선언했으므로 해당지역 내에서만 호출가능
	
<%}catch(SQLException e){
	
}
%>
  • Statement와 ResultSet 클래스 생성
  • 기존 방식(0801)으로 DB의 데이터를 json의 배열로 변환하기 위해서는 “”(따옴표)와 \”(escape 문자)를 이용해 배열의 구성을 수작업으로 구현해야 함
  • 이를 간단히 처리해주는 메서드인 JSONObject()와 JSONArray() 생성
  • JSONObject()는 인자 값으로 (배열의 원소 내 속성, 속성 값)을 받으며, 코드는 (참조 변수).put();
  • JSONArray()는 인자 값으로 JSONObject()(ob)를 받으며, 코드는 (참조 변수).add();
  • toString() 함수로, 생성된 배열 형식을 문자열로 변환
  • 결과적으로 json 형식에 맞는 배열과 원소를 문자열로 구현

Call Date Type from OracleSQL to JSON

<!--생략-->
try{
stmt=conn.createStatement();
rs=stmt.executeQuery(sql);

	JSONArray arr=new JSONArray();
	SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");

	while(rs.next())
	{
		String day=sdf.format(rs.getTimestamp("gaipday")); //getTimestamp(),getDate() 같은기능
		
		JSONObject ob=new JSONObject();

		ob.put("gaipday", day);
		
		//array에 추가
		arr.add(ob);
<!--생략-->
  • Date 타입의 데이터는 getString으로 호출할 시 문자열로만 인식
  • SimpleDateFormat() 매서드는 인자 값으로 Date 타입의 자료형 요구
  • getTimeStamp() 혹은 getDate()는 전달 값을 Date 타입으로 전송(둘은 거의 같은 기능)

CRUD within JSP

create table sinsang(num number(5) primary key,
name varchar2(20),
addr varchar2(30),
sdate date);
  • num, name, addr, sdate 4개의 속성을 가진 DB 테이블 생성(아직 데이터는 공백)

DTO(Data Transfer Object)

import java.sql.Timestamp;

public class SinsangDto {

	private String num;
	private String name;
	private String addr;
	private Timestamp sdate;
	
	public String getNum() {
		return num;
	}
	public void setNum(String num) {
		this.num = num;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAddr() {
		return addr;
	}
	public void setAddr(String addr) {
		this.addr = addr;
	}
	public Timestamp getSdate() {
		return sdate;
	}
	public void setSdate(Timestamp sdate) {
		this.sdate = sdate;
	}
}
  • SinsangDto는 데이터 교환만을 위한 객체로, 로직 없이 데이터 객체만 존재(setter, getter만)
  • DB 컬럼 값 데이터를 각각 멤버 변수로 선언

DAO(Data Access Object)

  • DB 데이터에 접근하기 위한 객체
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Vector;

import oracle.db.DBConnect;

public class SinsangDao {

	DBConnect db=new DBConnect();

//각각의 메서드 위치
}
  • import 받은 클래스와 전역에 걸쳐 jdbc에 사용할 DBConnect 클래스 생성
//insert
	public void insertSinsang(SinsangDto dto) {
		
		Connection conn=db.getConnection();
		PreparedStatement pstmt=null;
		
		String sql="insert into sinsang values(seq_1.nextval,?,?,sysdate)";
		
		try {
			pstmt=conn.prepareStatement(sql);
			
			pstmt.setString(1, dto.getName());
			pstmt.setString(2, dto.getAddr());
			pstmt.executeUpdate();
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			db.dbClose(pstmt, conn);
		}
	}
  • 초기 DB 값이 공백이므로 insert가 우선 필요
  • DTO 클래스(SinsangDto) 전체 멤버 값(각 컬럼 값)을 받아와 처리하기 위해 클래스 자체를 메서드의 인자 값으로 설정
  • num과 sdate 컬럼은 자동 생성 데이터를 가지므로 insert 필요 없음(name, addr 컬럼만 insert)
  • PrepareStatement 클래스를 이용해 ?로 insert 명령문 작성
  • PrepareStatement의 setString() 함수로 insert 명령문 완성
  • execute() 혹은 executeUpdate() 함수로 OracleSQL에서 명령문 실행
//select
	public Vector<SinsangDto> getAllDatas(){
		
		Vector<SinsangDto> list=new Vector<SinsangDto>();
		
		Connection conn=db.getConnection();
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		
		String sql="select * from sinsang order by num";
		
		try {
			pstmt=conn.prepareStatement(sql);
			rs=pstmt.executeQuery();
			
			//여러개데이터 얻을경우
			while(rs.next())
			{
				//dto선언..반드시 while안에서
				SinsangDto dto=new SinsangDto();
				dto.setNum(rs.getString("num"));
				dto.setName(rs.getString("name"));
				dto.setAddr(rs.getString("addr"));
				dto.setSdate(rs.getTimestamp("sdate"));
				
				//벡터에 추가
				list.add(dto);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			db.dbClose(rs, pstmt, conn);
		}
		
		return list;
	}
  • DB에 insert, delete 받은 전체 데이터를 유동적 크기로 저장하기 위해 List 객체 사용(List는 인터페이스이므로 하위 클래스인 Vector 사용)
  • 클래스의 반환 값이 Vector이며 제네릭 값으로 DTO 클래스(이곳의 멤버 변수를 사용하기 위해) 설정
  • PrepareStatement와 ResultSet 객체를 이용해 sql 명령문을 전달 후 실행 및 데이터 가져옴
  • ResultSet 객체의 getString() 메서드를 이용해 각 컬럼의 데이터 값을 문자열로 호출(date 타입의 sdate는 getTimestamp() 메서드 이용)
  • 문자열로 호출 받은 값을 DTO의 setter를 통해 멤버 변수의 값을 변경
  • List(Vector 클래스)의 add() 메서드를 통해 DTO에 변경한 멤버 변수를 저장 후 이를 반환
//삭제
	public void deleteSinsang(String num) {
		
		Connection conn=db.getConnection();
		PreparedStatement pstmt=null;
		
		String sql="delete from sinsang where num=?";
		
		try {
			pstmt=conn.prepareStatement(sql);
			
			pstmt.setString(1, num);
			pstmt.executeUpdate();
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			db.dbClose(pstmt, conn);
		}
	}
  • DB의 데이터를 삭제하기 위한 메서드
  • 메서드의 인자 값으로 받아온 num 값을 PreparedStatement 객체를 이용해 sql 명령문에 입력 후 execute() 혹은 executeUpdate() 메서드를 통해 Oracle에서 실행

Form(jsp)

<body>
	<form action="insertAction.jsp" method="post">
		<table>
			<tr>
				<th>이름</th>
				<td>
					<input type="text" name="name" placeholder="이름입력" required="required">
				</td>
			</tr>
			<tr>
				<th>주소</th>
				<td>
					<input type="text" name="addr" placeholder="주소입력" required="required">
				</td>
			</tr>
			<tr>
				<td colspan="2" align="center">
					<input type="submit" value="전송">
					<input type="button" value="목록" onclick="location.href='list.jsp'">
				</td>
			</tr>
		</table>
	</form>
</body>
  • insert에 필요한 2가지 컬럼 값(name, addr)을 입력하기 위한 text 타입의 툴과 이를 DB에 전송할 submit 타입의 <input> 버튼 생성
  • 입력 받은 데이터를 전송하기 위해 전체 태그를 감싸는 <form>태그
  • <form>에서, 보안이 필요한 정보이므로 method는 post로 설정하며, 데이터를 전송하여 처리할 파일의 경로를 action 속성의 url로 작성

Insert Action(jsp)

  • <form>에서 전달 받은 insert 요청을 처리하기 위한 메서드
<%
	String name=request.getParameter("name");
	String addr=request.getParameter("addr");
	
	//입력데이터를 dto로 묶어서
	SinsangDto dto=new SinsangDto();
	
	dto.setName(name);
	dto.setAddr(addr);
	
	//insert메서드 전달
	SinsangDao dao=new SinsangDao();
	dao.insertSinsang(dto);
	
	//출력 jsp로 이동..url이 바뀜
	response.sendRedirect("list.jsp");
	
	%>
  • DAO(SinsangDao)에서 <form>의 action 속성으로 넘겨준 입력 데이터를 request.getParameter() 함수로 받아옴
  • 이를 DTO의 멤버 변수에 대입하기 위해 setter, getter 메서드 사용(이를 위해 DTO 클래스 생성)
  • DTO의 전체 멤버 변수를 포함하는 DTO 클래스 자체를 insertSinsang() 메서드에 인자 값으로 보내줌(이를 위해 DAO 클래스 생성)
  • response 객체 : 웹 브라우저의 요청에 응답하는 것을 response라고 하며, 이러한 응답의 정보를 가지고 있는 객체가 response객체
  • sendRedirect(url) 객체 : 지정한 url로 이동하게 하는 객체
  • 즉 response.sendRedirect()는 웹브라우저에서 입력 값을 전송 받으면 이에 대한 응답으로 지정한 url(list.jsp)로 이동하게 하는 객체
  • 요컨대 <form>에서 값을 입력 받아 이를 Vector 리스트에 저장 후 list.jsp 파일로 이동
<%@page import="model.sinsang.SinsangDto"%>
<%@page import="java.util.Vector"%>
<%@page import="model.sinsang.SinsangDao"%>
  • import 받은 java 클래스
<%
	SinsangDao dao=new SinsangDao();
	Vector<SinsangDto> list=dao.getAllDatas();
%>
  • DAO의 getAllDatas() 메서드를 통해 저장된 모든 데이터를 호출
<body>
	<button type="button" onclick="location.href='insertForm.jsp'">데이터추가</button>
	 <br>
	 <table>
		 <tr>
		 	<th>번호</th>
		 	<th>이름</th>
		 	<th>주소</th>
		 	<th>날짜</th>
		 	<th>편집</th>
		 </tr>
		 <%
			for(int i=0;i<list.size();i++)
			{
				SinsangDto dto=list.get(i);
				%>
				<tr>
					<td><%=i+1 %></td>
					<td><%=dto.getName() %></td>
					<td><%=dto.getAddr() %></td>
					<td><%=dto.getSdate() %></td>
					<!--<td><button type="button"	onclick="location.href=''">수정</button>-->
					<button type="button"
					onclick="location.href='delete.jsp?num=<%=dto.getNum()%>'">삭제</button></td>
				</tr>
			<%}
		%>
	 </table>
</body>
  • <form>에서 데이터를 입력하면 이를 Vector 리스트에 저장 후 본 파일로 이동
  • onclick 속성에서 지정한 url로 이동하는 속성 값은 location.href=’url’
  • 다시 데이터를 입력하기 위해서 Form 파일(insertForm)로 이동하는 버튼 생성
  • size() : List 인터페이스 및 하위 클래스의 원소 갯수를 호출하는 메서드
  • get() : 인자의 인덱스 값에 해당하는 List의 원소 값을 호출하는 메서드
  • List(Vector<SinsangDto>)에 저장된 각 원소 데이터(DTO의 멤버 변수 전체)를 DTO의 getter를 통해 <td>에 호출
  • 삭제 버튼 클릭 시 delete.jsp 파일로 이동하며 인자 값으로 DTO의 num 변수 값을 입력(? 이후의 값을 인자 값으로 넘겨줌)

Delete Action(jsp)

<body>
	<%
	//삭제메서드 호출
	String num=request.getParameter("num");
	
	SinsangDao dao=new SinsangDao();
	dao.deleteSinsang(num);
	//리스트로 이동
	response.sendRedirect("list.jsp");
	%>
</body>
  • Print List에서 인자 값으로 받아온 num의 변수 값을 request.getParameter() 객체로 호출
  • DAO의 deleteSinsang() 메서드를 통해 Oracle DB에 delete 명령문을 전달 및 실행
  • respose.sendRedirect() 객체를 통해 DB 데이터 삭제를 완료 후 list.jsp로 재이동
  • DB 데이터가 삭제되면 Vector<SinsangDto> 값과 size가 변하므로 list.jsp의 <table>에 출력되는 값도 변경
profile
초보개발자

0개의 댓글