대부분의 페이지가 DB와 연동 (이메일 등)
매번 매개변수를 초기화 해야하는 부담 → 생성자를 오버로딩 하는 방식으로 해결할 수 있다
가장 모듈화가 잘 된 방식이 이 방식.
코딩을 할 때는 모듈화가 중요하다. 잘 만들어진 모듈 하나는 열 개발자 안 부럽다.
→ 리팩토링이라고도 한다. 좀 더 코드를 최적화할 수 있는 형태를 생각, 모듈화 하듯
❗️앞으로 두고두고 중요한 개념이다
jsp의 내장객체인 application 을 읽을 수 있다면 매개변수는 한번에 읽어올 수 있다.
application 타입 → ServletContext application
JDBConnect.java
public JDBConnect(ServletContext application) {
String driver = application.getInitParameter("OracleDriver");
try {
Class.forName(driver);
String url = application.getInitParameter("OracleURL");
String id = application.getInitParameter("OracleId");
String pwd = application.getInitParameter("OraclePwd");
con = DriverManager.getConnection(url, id, pwd);
System.out.println("DB 연결 성공(인수 생성자 2)");
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
JDBCTest2.jsp
<%
JDBConnect jdbc3 = new JDBConnect(application);
jdbc3.close();
%>
테스트할 페이지에서는 매개변수인 application을 한번 더 호출해주면 된다.
전체코드)
JDBConnect.java
package common;
import java.sql.Statement;
import jakarta.servlet.ServletContext;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBConnect {
// Connection,
// statement (쿼리문 쓸 때 필요한 객체, 많이 안쓴다.),
// PreparedStatement (쿼리문 사용할 떄 필요한 객체 많이쓴다. 쿼리문을 쓸 때 융통성이 좋다.),
// ResultSet (실행된 쿼리문의 결과를 받아올 떄 필요한 객체)
public Connection con;
public Statement stmt;
public PreparedStatement psmt;
public ResultSet rs;
public JDBConnect() {
String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@localhost:1521:XE";
try {
Class.forName(driver);
con = DriverManager.getConnection(url, "musthave", "1234");
System.out.println("DB 연결 성공 (기본 생성자)");
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 두번째 생성자 방식 - 매개변수로 개인 정보를 숨김
public JDBConnect(String driver, String url, String id, String pwd) {
try {
// JDBC 드라이버 로드
Class.forName(driver);
// DB에 연결
con = DriverManager.getConnection(url, id, pwd);
System.out.println("DB 연결 성공(인수 생성자 1)");
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public JDBConnect(ServletContext application) {
String driver = application.getInitParameter("OracleDriver");
try {
Class.forName(driver);
String url = application.getInitParameter("OracleURL");
String id = application.getInitParameter("OracleId");
String pwd = application.getInitParameter("OraclePwd");
con = DriverManager.getConnection(url, id, pwd);
System.out.println("DB 연결 성공(인수 생성자 2)");
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public void close() {
try {
if (con != null) {
con.close();
}
} catch (Exception e) {
}
}
}
JDBCTest2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="common.JDBConnect"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>JDBCTest1</h2>
<%
JDBConnect jdbc1 = new JDBConnect();
jdbc1.close();
%>
<h2>JDBCTest2</h2>
<%
String driver = application.getInitParameter("OracleDriver");
String url = application.getInitParameter("OracleURL");
String id = application.getInitParameter("OracleId");
String pwd = application.getInitParameter("OraclePwd");
JDBConnect jdbc2 = new JDBConnect(driver,url,id,pwd);
jdbc2.close();
%>
<h2>JDBCTest3</h2>
<%
JDBConnect jdbc3 = new JDBConnect(application);
jdbc3.close();
%>
</body>
</html>
기존 방식은 접속할때마다 접속할 수 있는 입구를 만들고, 접속을 끊으면 입구를 없애는 방식이었다.
요청이 있을 때마다 입구를 만드는 방식.
🍀 커넥션 풀 방식
미리 입구를 만들어 놓는다. 용량 낭비가 조금 있지만 바로 들어와서 이용할 수 있다.
커넥션 풀 방식에서는 web.xml 역할을 하는 것이 server.xml (서술배포자로의 역할을 한다)
server.xml 수정 - 구문 추가
<Resource auth="Container"
driverClassName="oracle.jdbc.OracleDriver"
type="javax.sql.DataSource"
initialSize="0" // 초기 사이즈 (몇개 만들건지)
minIdle="5"
maxTotal="20" // 최대 개수
maxIdle="20"
maxWaitMillis="5000" // 대기시간 5초
url="jdbc:oracle:thin:@localhost:1521:xe"
name="dbcp_myoracle" // 이름 속성에 들어간 값이 정해진 건 아니지만 프로그램에서 이름을 가져다 쓴다.
username="musthave"
password="1234" />
이 정보가 Pull 방식을 쓸 수 있게 해주는 매개변수같이 동작한다.
❗️필수 구성 항목
- driverClassName="oracle.jdbc.OracleDriver"
- type="javax.sql.DataSource"
- url="jdbc:oracle:thin:@localhost:1521:xe"
- name="dbcp_myoracle" // 이름 속성에 들어간 값이 정해진 건 아니지만 프로그램에서 이름을 가져다 쓴다.
- username="musthave"
- password="1234"
name="dbcp_myoracle" // 이름 속성에 들어간 값이 정해진 건 아니지만 프로그램에서 이름을 가져다 쓰기 때문에 어떤 값이 있는지는 알아야한다. 떄문에 의미있는 이름을 짓는 것이 좋다.
context.xml 수정 - 구문 추가
<ResourceLink global="dbcp_myoracle" name="dbcp_myoracle"
type="javax.sql.DataSource"/>
여기까지하고 톰켓서버 restart
DBConnPool.java
package common;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class DBConnPool {
public Connection con;
public Statement stmt;
public PreparedStatement psmt;
public ResultSet rs;
public DBConnPool() {
// 커넥션 풀 방식
try {
// 기본 세팅
Context initCtx = new InitialContext();
Context ctx = (Context) initCtx.lookup("java:comp/env");
DataSource source = (DataSource) ctx.lookup("dbcp_myoracle");
con = source.getConnection(); // DB를 연결해주는 메서드
System.out.println("DB 커넥션 풀 연결 성공");
} catch (Exception e) {
}
}
public void close() {
try {
if (con != null) {
con.close();
}
} catch (Exception e) {
}
}
}
JDBCTest2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="common.JDBConnect"%>
<%@ page import= "common.DBConnPool" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>JDBCTest1</h2>
<%
JDBConnect jdbc1 = new JDBConnect();
jdbc1.close();
%>
<h2>JDBCTest2</h2>
<%
String driver = application.getInitParameter("OracleDriver");
String url = application.getInitParameter("OracleURL");
String id = application.getInitParameter("OracleId");
String pwd = application.getInitParameter("OraclePwd");
JDBConnect jdbc2 = new JDBConnect(driver,url,id,pwd);
jdbc2.close();
%>
<h2>JDBCTest3</h2>
<%
JDBConnect jdbc3 = new JDBConnect(application);
jdbc3.close();
%>
<h2>JDBCTest4</h2>
<%
DBConnPool pool = new DBConnPool();
pool.close();
%>
</body>
</html>
연결 테스트를 해보면 연결이 된 것을 확인할 수 있다.
🍀 DB 데이터를 서버에서 집어넣어보기
ExeUpdate.jsp
<%@page import="java.sql.PreparedStatement"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="common.JDBConnect"%>
<%@ page import="java.sql.PreparedStatement"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 회원추가 -->
<h2>회원 추가 테스트</h2>
<%
JDBConnect jdbc = new JDBConnect();
String id = "test1";
String pass = "1111";
String name = "테스트1회원";
// varchar2 타입 문자 처리 -> '"내용"' 코드가 까다로워 이렇게 쓰지 않는다
// String sql = "insert into member (id, pass, name) values ('" + id + "', '" + pass + "', '" + name + "')";
// PreparedStatement 방식 -> 컬럼의 개수에 맞게 ? 를 넣어준다.
// PreparedStatement 쿼리문을 실행하게 하는 메소드, 유연성이 있다.
String sql = "insert into member (id, pass, name) values (?, ?, ?)";
PreparedStatement psmt = jdbc.con.prepareStatement(sql);
// psmt.setString(순서, 정해주고 싶은 값);
psmt.setString(1, id);
psmt.setString(2, pass);
psmt.setString(3, name);
// PreparedStatement 로 쿼리문 실행
// executeQuery() -> select
// executeUpdate() -> Insert, update, delete
// -> 반환값을 가진다. 0 or 0 보다 큰 값
int result = psmt.executeUpdate();
if (result > 0) {
out.print(result + "행이 입력되었습니다.");
} else {
out.print("입력 실패");
}
jdbc.close(); // 사용중인 객체 close()
%>
</body>
</html>
JDBConnect.java
package common;
import java.sql.Statement;
import jakarta.servlet.ServletContext;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBConnect {
// Connection,
// statement (쿼리문 쓸 때 필요한 객체, 많이 안쓴다.),
// PreparedStatement (쿼리문 사용할 떄 필요한 객체 많이쓴다. 쿼리문을 쓸 때 융통성이 좋다.),
// ResultSet (실행된 쿼리문의 결과를 받아올 떄 필요한 객체)
public Connection con;
public Statement stmt;
public PreparedStatement psmt;
public ResultSet rs;
public JDBConnect() {
String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@localhost:1521:XE";
try {
Class.forName(driver);
con = DriverManager.getConnection(url, "musthave", "1234");
System.out.println("DB 연결 성공 (기본 생성자)");
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 두번째 생성자 방식 - 매개변수로 개인 정보를 숨김
public JDBConnect(String driver, String url, String id, String pwd) {
try {
// JDBC 드라이버 로드
Class.forName(driver);
// DB에 연결
con = DriverManager.getConnection(url, id, pwd);
System.out.println("DB 연결 성공(인수 생성자 1)");
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public JDBConnect(ServletContext application) {
String driver = application.getInitParameter("OracleDriver");
try {
Class.forName(driver);
String url = application.getInitParameter("OracleURL");
String id = application.getInitParameter("OracleId");
String pwd = application.getInitParameter("OraclePwd");
con = DriverManager.getConnection(url, id, pwd);
System.out.println("DB 연결 성공(인수 생성자 2)");
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public void close() {
try {
if (stmt != null) {
stmt.close();
}
if (rs != null) {
rs.close();
}
if (psmt != null) {
psmt.close();
}
if (con != null) {
con.close();
}
} catch (Exception e) {
}
}
}
다른 객체들을 사용할때도 다 null 이 아니면 close() 될 수 있도록 수정했다.
DB에도 데이터가 잘 들어간 것을 확인할 수 있다.
Insert, update, delete 비슷한 방식 처리
PreparedStatement 사용
select는 다른 방식
PreparedStatement 사용이 일반적이지만,
여기 예시에서는 Statement를 사용해보겠다.
🌀 select 해보기
ExeQuery.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="common.JDBConnect"%>
<%@ page import="java.sql.Statement"%>
<%@ page import="java.sql.ResultSet"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>회원 목록 조회 테스트</h2>
<%
JDBConnect jdbc = new JDBConnect();
String sql = "select * from member";
Statement stmt = jdbc.con.createStatement();
// Statement 로 쿼리문 실행
// executeQuery() -> select
// executeUpdate() -> Insert, update, delete
// -> 반환값을 가진다. 0 or 0 보다 큰 값
// 실행할 때 쿼리실행문을 넣는다.
// ResultSet 래코드의 개수만큼 참조 -> 그 안에는 컬럼 단위
// next() 메서드가 주소값을 참조하며 이동해 레코드를 읽어주는 역할
// 참조 가능한 레코드가 있을 땐 next() -> true 반환
// 없다면 flase 반환
// 그렇다면 false를 반환할때까지 while 문으로 돌리기
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
String id = rs.getString("id");
String pw = rs.getString("pass");
String name = rs.getString("name");
// java.sql.Date regidate = rs.getDate("regidate");
String regidate = rs.getString("regidate");
out.print(String.format("%s %s %s %s", id, pw, name, regidate) + "</br>");
}
jdbc.close();
%>
</body>
</html>
- executeQuery() -> select
- → ResultSet : 조회된 결과
- executeUpdate() -> Insert, update, delete
- -> 반환값을 가진다. 0 or 0 보다 큰 값
- getInt(), getFloat(), getString(), getDate() 로 데이터를 받는다.
날짜 데이터 가져오는 방식)
날짜 연산이 필요할 땐 아래와 같이,
java.sql.Date regidate = rs.getDate("regidate");
그냥 날짜 데이터만 가지고 올 땐 아래와 같은 형식으로 사용한다.
String regidate = rs.getString("regidate");
🍀 회원가입 폼을 만들어서 실제 테이블에 저장해보기
🌀 회원가입 → 브라우저 화면에서 값을 입력해서 집어넣기
Member.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>
<form action="MemberProcess.jsp" method = "post">
<label>아이디 : </label>
<input type = "text" name = "id">
<br>
<label>비밀번호 : </label>
<input type = "password" name = "pwd">
<br>
<label>이름 : </label>
<input type = "text" name = "name">
<br>
<input type = "submit" value = "회원가입">
</form>
</body>
</html>
MemberProcess.jsp - 회원가입된 정보 DB에 집어 넣기
<%@page import="utils.JSFunction"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="common.JDBConnect"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String id = request.getParameter("id");
String pass = request.getParameter("pwd");
String name = request.getParameter("name");
JDBConnect jdbc = new JDBConnect();
String sql = "insert into member (id, pass, name) values (?, ?, ?)";
PreparedStatement psmt = jdbc.con.prepareStatement(sql);
psmt.setString(1, id);
psmt.setString(2, pass);
psmt.setString(3, name);
int result = psmt.executeUpdate();
if (result > 0){
JSFunction.alertLocation("데이터 삽입 성공", "MemberList.jsp", out);
}
%>
회원가입이 완료되어 데이터가 DB에 들어가고, MemberList.jsp 페이지로 넘어간 모습이다.
🌀 회원 목록 보기
MemberList.jsp
<%@page import="java.sql.ResultSet"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="common.JDBConnect"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>회원 목록 보기</h2>
<%
JDBConnect jdbc = new JDBConnect();
String sql = "select * from member";
PreparedStatement psmt = jdbc.con.prepareStatement(sql);
ResultSet rs = psmt.executeQuery();
while (rs.next()){
String id = rs.getString("id");
String pass = rs.getString("pass");
String name = rs.getString("name");
String regidate = rs.getString("regidate");
out.print(String.format("%s %s %s %s", id, pass, name, regidate) + "</br>");
}
%>
</body>
</html>
데이터가 들어간 것을 확인할 수 있다.
'2024_UIUX 국비 TIL' 카테고리의 다른 글
UIUX _국비과정 0625 ~ 27 [게시판] (0) | 2024.07.10 |
---|---|
UIUX _국비과정 0624 [JSP 세션의 역할, 액션태그] (0) | 2024.07.10 |
UIUX _국비과정 0620 [JSP 쿠키, 오라클DB 연결] (0) | 2024.07.08 |
UIUX _국비과정 0619 [JSP 문법] (0) | 2024.07.08 |
UIUX _국비과정 0618 [톰캣 설치와 JSP 앞으로 배울 구문 맛보기] (0) | 2024.07.08 |