관리 메뉴

개발 노트

9/14 데이터베이스 커넥션 풀(Database Connection pool), 모듈화, exERD 설치 및 사용, 순공학, 역공학 본문

프로젝트 기반 JAVA 응용 SW개발 : 22.07.19~23.01.20/JDBC

9/14 데이터베이스 커넥션 풀(Database Connection pool), 모듈화, exERD 설치 및 사용, 순공학, 역공학

hayoung.dev 2022. 9. 19. 11:48

professor 테이블 생성, 데이터 삽입

CREATE TABLE PROFESSOR
        (PROFNO int(4)    PRIMARY KEY,
         NAME VARCHAR(10),
         USERID VARCHAR(10),
         POSITION VARCHAR(20),
         SAL int(10),
         HIREDATE DATE,
         COMM int(2),
         DEPTNO int(4));

INSERT INTO PROFESSOR VALUES
        (9901, '김도훈', 'capool', '교수', 500,
       '1982-01-24', 20, 101);

INSERT INTO PROFESSOR VALUES
        (9902, '이재우', 'sweat413', '조교수', 320,
        '1992-04-23', NULL, 201);

INSERT INTO PROFESSOR VALUES
        (9903, '성연희', 'Pascal', '조교수', 360,
        '1982-04-23', 15, 101);

INSERT INTO PROFESSOR VALUES
        (9904, '염일웅', 'Blue77', '전임강사', 240,
        '1980-09-23', NULL, 102);

INSERT INTO PROFESSOR VALUES
        (9905, '권혁일', 'refresh', '교수', 450,
        '1986-08-01', 25, 102);

INSERT INTO PROFESSOR VALUES
        (9906, '이만식', 'Pocari', '부교수', 420,
        '1988-08-01', NULL, 101);

INSERT INTO PROFESSOR VALUES
        (9907, '전은지', 'totoro', '전임강사', 210,
        '2001-10-13', NULL, 101);

INSERT INTO PROFESSOR VALUES
        (9908, '남은혁', 'Bird13', '부교수', 400,
        '1990-12-11', 17, 202);

Professor.java

package och10;

import java.util.Date;

public class Professor {
	private int profno;
	private String name;
	private String userid;
	private String position;
	private int sal;
	private Date hiredate;
	private int comm;
	private int deptno;
	
	public int getProfno() {
		return profno;
	}
	public void setProfno(int profno) {
		this.profno = profno;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getUserid() {
		return userid;
	}
	public void setUserid(String userid) {
		this.userid = userid;
	}
	public String getPosition() {
		return position;
	}
	public void setPosition(String position) {
		this.position = position;
	}
	public int getSal() {
		return sal;
	}
	public void setSal(int sal) {
		this.sal = sal;
	}
	public Date getHiredate() {
		return hiredate;
	}
	public void setHiredate(Date hiredate) {
		this.hiredate = hiredate;
	}
	public int getComm() {
		return comm;
	}
	public void setComm(int comm) {
		this.comm = comm;
	}
	public int getDeptno() {
		return deptno;
	}
	public void setDeptno(int deptno) {
		this.deptno = deptno;
	}
	
	

}

mySql > my05.jsp

<%@page import="java.sql.ResultSet"%>
<%@page import="java.util.ArrayList"%>
<%@page import="och10.Professor"%>
<%@page import="java.sql.Statement"%>
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.Connection"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
	String driver = "com.mysql.cj.jdbc.Driver";
	String url = "jdbc:mysql://localhost:3306/scottdb?serverTimezone=UTC";
	String sql = "select profno, name, position, sal from Professor";
	ArrayList<Professor> al = new ArrayList<Professor>();

	Class.forName(driver);
	Connection conn = DriverManager.getConnection(url, "root", "mysql80");
	Statement stmt = conn.createStatement();
	ResultSet rs = stmt.executeQuery(sql);

	if (rs.next()) {
		do {
			Professor p = new Professor();
			p.setProfno(rs.getInt(1));
			p.setName(rs.getString(2));
			p.setPosition(rs.getString(3));
			p.setSal(rs.getInt(4));
			al.add(p);
		} while (rs.next());
		request.setAttribute("al", al);
		rs.close();
		stmt.close();
		conn.close();
		//RequestDispatcher rd = request.getRequestDispatcher("my05Result.jsp");
		RequestDispatcher rd = request.getRequestDispatcher("my05Result2.jsp");
		rd.forward(request, response);
	} else {
		out.println("데이터가 없습니다.");
		stmt.close();
		conn.close();
	}
	%>
</body>
</html>

my05Result.jsp

<%@page import="och10.Professor"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<style type="text/css">
	tr:HOVER {background-color: red;}
</style>
<body>
<%
	ArrayList<Professor> al = (ArrayList<Professor>)request.getAttribute("al");
%>
<table width="100%" bgcolor="yellow" border="1">
<tr><th>사번</th><th>이름</th><th>업무</th><th>급여</th></tr>
<%
	for(int i = 0; i<al.size(); i++) {
		out.println("<tr><td>"+al.get(i).getProfno()+"</td>");
		out.println("<td>"+al.get(i).getName()+"</td>");
		out.println("<td>"+al.get(i).getPosition()+"</td>");
		out.println("<td>"+al.get(i).getSal()+"</td></tr>");
	}
%>
</table>
</body>
</html>

출력 결과 : 마우스를 위에 올리면 빨간색이 된다.

 

my05Result2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
	tr:HOVER {background-color: red;}
</style>
</head>
<body>
<h2>사원 명단 Model2 View</h2>
<table width="100%" bgcolor="yellow" border="1">
<tr bgcolor="pink">
	<th>사번</th><th>이름</th><th>업무</th><th>급여</th></tr>
<c:forEach var="professor" items="${al }">
	<tr><td>${professor.profno }</td><td>${professor.name }</td>
		<td>${professor.position }</td><td>${professor.sal }</td></tr>
</c:forEach>

</table>

</body>
</html>

출력 결과

 

myUpdate.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>수정할 부서코드 입력</h2>
<form action="myRetrieve.jsp">
	부서코드 : <input type="number" name="dno" required="required"><p>
	<input type="submit" value="확인">
</form>
</body>
</html>

myRetrieve.jsp

<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.Connection"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
	String dno = request.getParameter("dno");
	String driver = "com.mysql.cj.jdbc.Driver";
	String url = "jdbc:mysql://localhost:3306/scottdb?serverTimezone=UTC";
	String sql = "select * from division where dno="+dno;
	Class.forName(driver);
	Connection conn = DriverManager.getConnection(url, "root", "mysql80");
	Statement stmt = conn.createStatement();
	ResultSet rs = stmt.executeQuery(sql);
	if (rs.next()) {
		request.setAttribute("dno", dno);
		request.setAttribute("dname", rs.getString(2));
		request.setAttribute("dname", rs.getString(3));
		request.setAttribute("dname", rs.getString(4));
		rs.close();
		stmt.close();
		conn.close();
		RequestDispatcher rd = request.getRequestDispatcher("myResult.jsp");
		rd.forward(request, response);
	}
	stmt.close();
	conn.close();
%>
<script type="text/javascript">
	alert("없는 부서야");
	locationl.href = "myUpdate.html";
</script>

</body>
</html>

myResult.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>부서 정보 수정</h2>
<form action="myUpdate.jsp">
	<!-- update할 때 pk는 수정하지 않는다. -->
	부서코드 : ${dno }<p>
	<input type="hidden" name="dno"	value="${dno }">
	부서명 : <input type="text" name="dname" value="${dname }"><p>
	전화번호 : <input type="text" name="phone" value="${phone }"><p>
	근무지 : <input type="text" name="position" value="${position }"><p>
	<input type = "submit" value="수정완료">
	</form>
</body>
</html>

myUpdate.jsp

<%@page import="java.sql.PreparedStatement"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.Connection"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h2>스크릿틀릿 + PreparedStatement</h2>
<%
	int dno = Integer.parseInt(request.getParameter("dno"));
	String dname = request.getParameter("dname");
	String phone = request.getParameter("phone");
	String position = request.getParameter("position");
	String driver = "com.mysql.cj.jdbc.Driver";
	String url = "jdbc:mysql://localhost:3306/scottdb?serverTimezone=UTC";
	String sql = "update division set dname=?, phone=?, position=? where dno=?";
	Class.forName(driver);
	Connection conn = DriverManager.getConnection(url, "root", "mysql80");
	PreparedStatement pstmt = conn.prepareStatement(sql);
	pstmt.setString(1, dname);
	pstmt.setString(2, phone);
	pstmt.setString(3, position);
	pstmt.setInt(4, dno);
	int result = pstmt.executeUpdate(sql);
	
	if (result > 0 ) out.println("수정 성공");
	else out.println("수정 실패");
	pstmt.close();
	conn.close();
%>
</body>
</html>

출력 결과

 

[DBCP (중요 : 면접에 나올 수 있음)]

데이터베이스 커넥션 풀(Database Connection pool) 사용

context.xml 작성 

 

 

webapp > dbcp 폴더 생성

webapp > META-INF > context.xml

<context>
	<Resource
		name="jdbc/OracleDB"
		auth="Container"
		type="javax.sql.DataSource"
		username="scott"
		password="tiger"
		driverClassName="oracle.jdbc.driver.OracleDriver"
		factory="org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory"
		url = "jdbc:oracle:thin:@127.0.0.1:1521:xe"
		maxActive="50"
		maxIdle="10"
	/>
	
	<Resource 
		name="jdbc/MySql" 
		auth="Container" 
		type="javax.sql.DataSource" 
		username="root" 
		password="mysql80" 
		driverClassName="com.mysql.cj.jdbc.Driver" 
		factory="org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory" 
		url="jdbc:mysql://localhost:3306/scottdb?serverTimezone=UTC" 
		maxActive="100" 
		maxIdle="10"/>
	
</context>

webapp  > dbcp > oraDbConnect.jsp

<%@page import="java.sql.Connection"%>
<%@page import="javax.sql.DataSource"%>
<%@page import="javax.naming.InitialContext"%>
<%@page import="javax.naming.Context"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" errorPage="../dbError.jsp"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>DBCP 연결(모듈화)</h2>
<%
	//InitialContext :  meta-inf 밑에 있는 context를 초기화시킨다.
	Context init = new InitialContext();
	//자바의 환경작업(java:comp/env) 안의 jdbc/OracleDB를 찾는다. context의 이름을 jdbc/OracleDB으로 해주었다.
	//DataSource : 물리적인 데이터소스를 연결하기 위한 객체. 
	// ds 안에 username, password, url 등이 멤버변수로 잡혀있기 때문에 값을 넘겨줄 수 있다.
	DataSource ds = (DataSource)init.lookup("java:comp/env/jdbc/OracleDB");
	//context.xml에 모듈화시킨것. 모듈화시키면 성능이 빨라지고 불필요하게 반복되는 작업들을 줄일 수 있음.
	//그러므로 DBCP를 사용해야 한다.
	Connection conn = ds.getConnection();
	if(conn != null) out.println("연결 성공");
	else out.println("연결 실패");
	conn.close();
%>
</body>
</html>

출력 결과

 

oraInEmp.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>사전정보 입력</h2>
<form action="oraSelect.jsp" method="post">
	사번코드 : <input type="number" name="empno" required="required"><p>
	<input type="submit" value="입력완료">
	<input type="reset" value="입력취소">
</form>

</body>
</html>

oraSelect.jsp

<%@page import="och10.Emp"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@page import="javax.sql.DataSource"%>
<%@page import="javax.naming.InitialContext"%>
<%@page import="javax.naming.Context"%>
<%@page import="java.sql.Connection"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" errorPage="../dbError.jsp"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
	String empno = request.getParameter("empno");
	String sql = "select empno, ename, sal, hiredate from emp where empno=" + empno;
	Context ctx = new InitialContext();
	DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/OracleDB");
	Connection conn	= ds.getConnection();
	Statement stmt = conn.createStatement();
	ResultSet rs = stmt.executeQuery(sql);
	Emp emp = new Emp();
	if (rs.next()) {
		emp.setEmpno(rs.getInt(1));
		emp.setEname(rs.getString(2));
		emp.setSal(rs.getInt(3));
		emp.setHiredate(rs.getDate(4));
		request.setAttribute("emp", emp);
	}
	rs.close();
	stmt.close();
	conn.close();
	RequestDispatcher rd = request.getRequestDispatcher("oraResult.jsp");
	rd.forward(request, response);
%>

</body>
</html>

oraResult.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>사원 정보</h2>
사번 : ${emp.empno }<p>
이름 : ${emp.ename }<p>
급여 : <fmt:formatNumber value="${emp.sal }" groupingUsed="true"/><p>
입사일 : <fmt:formatDate value="${emp.hiredate }" pattern="yyyy/MM/dd"/>

</body>
</html>

출력 결과

 

 

oraSelectIn2.jsp

이 코드를 쓰는 이유는 사용자 입장에서는 DB를 못보기 때문에 선택박스를 제공하는 것이다.

<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@page import="java.sql.Connection"%>
<%@page import="javax.sql.DataSource"%>
<%@page import="javax.naming.InitialContext"%>
<%@page import="javax.naming.Context"%>
<%@page import="och10.Emp"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" errorPage="../dBError.jsp"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
    ArrayList<Emp> al = new ArrayList<Emp>();
	Context ctx = new InitialContext();
	DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/OracleDB");
	Connection conn = ds.getConnection();
	String sql = "select empno,ename  from emp";
	Statement stmt = conn.createStatement();
	ResultSet rs = stmt.executeQuery(sql);
	while (rs.next()) {		
		Emp emp = new Emp();
		emp.setEmpno(rs.getInt(1));
		emp.setEname(rs.getString(2));
		al.add(emp);	
		}
	request.setAttribute("al", al);
	rs.close();  
	stmt.close(); 
	conn.close();

%>
<h2>보고싶은 사원 번호를 선택하세요</h2>
<!--  <form action="oraSelect.jsp"> -->
 <form action="oraCallEmpInfo.jsp">
    <select name="empno">
	    <c:forEach var="emp" items="${al }">
			<option value="${emp.empno }">${emp.empno }  ${emp.ename }</option>
		</c:forEach>
	 </select><p>
	<input type="submit" value="선택완료">
</form>



</body>
</html>

 

webapp>dbcp > oraCallEmpInfo.jsp

<%@page import="java.sql.Types"%>
<%@page import="java.sql.CallableStatement"%>
<%@page import="java.sql.Connection"%>
<%@page import="javax.sql.DataSource"%>
<%@page import="javax.naming.InitialContext"%>
<%@page import="javax.naming.Context"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" errorPage="../dBError.jsp"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
	int   empno =Integer.parseInt(request.getParameter("empno"));
	System.out.println("empno->"+empno);
	Context ctx = new InitialContext();
	DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/OracleDB");
	Connection conn = ds.getConnection();
	// Procedure Call
	//프로시저 불러올 때 {call 프로시저명(변수)}
	String sql = "{call Emp_Info3(?,?)}";
	//CallableStatement : 프로시저 호출 객체
	CallableStatement cs = conn.prepareCall(sql);
	// 급여
	//registerOutParameter : 환경값으로 받아들인다.
	cs.registerOutParameter(2, Types.DOUBLE);
	// 사번 
	cs.setInt(1, empno);
	cs.execute();
	out.println("급여 : " + cs.getDouble(2));
	cs.close();	
	conn.close();

%>
</body>
</html>

출력 결과

 

 

 

C : ERD 폴더 생성 > EX-ERD폴더> exERD 설치

C:\ERD\EX-ERD\workspace 폴더 생성 후 workspace를 여기로 설정

 

파일 > 새로작성 > 프로젝트 > 일반,프로젝트 선택 > jspErd 생성

oracle sql developer에서 system 계정으로 로그인 후 

CREATE USER scott2 IDENTIFIED BY tiger;
GRANT  DBA TO scott2;

입력하여 scott2 계정 생성, 권한 부여

 

계정 생성 확인

 

exerd 프로그램에 들어가서 새 테이블 추가 후 테이블 이름 만듦.

ctrl+enter 하면 그 다음 컬럼을 추가할 수 있음.

 

물리 이름, 논리 이름은 테이블 우클릭> 속성에서 설정할 수 있다.

논리이름은 알아보기 쉽게 한글로 작성하는 것이 좋다.

물리이름은 실질적으로 데이터베이스에 들어가는 테이블명, 컬럼명, 제약조건명이다.

.

 

비식별관계

dept2 테이블을 먼저 선택하고 emp2 테이블을 선택하면 dept2 테이블의 pk를 참조하는 emp2의 테이블의 fk가 생긴다.

하단의 그림에서 dept2가 한개일때 emp2의 deptno는 0개, 1개, 여러개가 될 수 있다는 뜻.

 

c: erd 폴더에 ojdbc6.jar 파일 붙여넣는다.

 

exERD > 포워드 엔지니어링을 해보면 상단에서 한 테이블 생성과 데이터 넣는 코드를 확인할 수 있다.

 

이름 앞에 스키마표시 체크 해제

 

연결설정 > 설정관리에서 하단의 오라클scott2 속성과 똑같이 설정해준다.

 

위처럼 설정하면 연결에서 scott2를 선택할 수 있다.

 

 

eXERD > 리버스 엔지니어링

설정관리에서 위처럼 똑같이 하여 scott을 만들고 연결한다.

 

 

scott2는 순공학, scott은 역공학이다.

순공학 : 요구분석 -> 설계 -> 구현으로 추상적 개념에서 물리적 실현으로 구체화를 하는 것이다.

역공학 : 완제품 -> 설계로 물리적인 소프트웨어 정보를 논리적인 소프트웨어 정보로 추출하는 것이다.

 

 

Oracle sql developer에서 scott 계정에서 하단 실행

CREATE OR REPLACE PROCEDURE emp_info3
(p_empno IN emp.empno%TYPE, p_sal OUT emp.sal%TYPE)
IS
-- %TYPE 데이터형 변수 선언
v_empno emp.empno%TYPE;
v_ename emp.ename%TYPE;

BEGIN
    DBMS_OUTPUT.ENABLE;
    --%TYPE 데이터형 변수 사용
    SELECT empno, ename, sal
    INTO v_empno, v_ename, p_sal
    FROM emp
    WHERE empno = p_empno;
    -- 결과값 출력
    DBMS_OUTPUT.PUT_LINE('사원번호 : ' || v_empno);
    DBMS_OUTPUT.PUT_LINE('사원이름 : ' || v_ename);
    
END;

실행 결과

 

 

 

반응형