오늘의 코딩순서
(폴더:och10_META-INF)
- context.xml
(폴더:och10_dbcp)
- oraInEmp.html + oraSelect.jsp + oraResult.jsp + oraSelectIn2.jsp + oraCallEmpInfo.jsp
(폴더:och10_dbcp_mySql)
- mySelectIn.jsp (현장 HW) + mySelect.jsp (현장 HW)
(폴더:och11) >> och10폴더의 자카르타 파일 4개, context.xml를 lib 폴더에 복붙함
- cookie2.jsp + cookView2.jsp
- person.jsp + agree.jsp + MemberDto.class + MemberDao.class + error.jsp + subscribe.jsp
오늘의 코딩 포인트
(폴더:och10_META-INF)
- context.xml
Tip)- context?:
<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="mysql84"
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>
(폴더:och10_dbcp)
- 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
Tip)- sql where 조건이 primary키일때는 single row(while 문 혹은 if문 사용), where 조건이 없을때 혹은 primary key가 아닐때는 multi row(do-while 혹은 try catch 혹은 if-else문)
- 오류체크방법: System.out.println("setSal->"+rs.getInt(3));
System.out.println("hiredate->"+rs.getDate(4)); - InitialContext():
- lookup
<%@page import="och10.Emp"%>
<%@page import="java.sql.Statement"%>
<%@page import="org.apache.tomcat.dbcp.dbcp2.PoolingConnection.StatementType"%>
<%@page import="java.sql.ResultSet"%>
<%@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>
<%
Context ctx = new InitialContext();
//InitialContext: Context.xml을 읽어와서 ctx에 자원화 시켜줌
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/OracleDB");
//context.xml에서 jdbc/OracleDB라는 이름의 환경(env)자원(comp)을 가져와 ds에 넘겨주기
Connection conn = ds.getConnection();
String empno = request.getParameter("empno");
String sql = "select empno, ename, sal, hiredate from emp where empno=" + empno;
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 (현장 HW)
<%@page import="och10.Emp"%>
<%@ 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"/><p>
</body>
</html>
- oraSelectIn2.jsp (현장 HW)
<%@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>
<%
//현장 HW: al 만들기
//1. DBCP를 이용하여 Arraylist 만들기
ArrayList<Emp> al = new ArrayList<Emp>();
//2. EMP테이블의 모든 empno, ename 다 al에 넣기
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>
- oraCallEmpInfo.jsp
<%@page import="java.sql.CallableStatement"%>
<%@page import="java.sql.Types"%>
<%@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"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/OracleDB");
Connection conn = ds.getConnection();
//Procedure Call
String sql = "{Call Emp_Info3(?,?)}";
CallableStatement cs = conn.prepareCall(sql);
//Parameter 받기
int empno = Integer.parseInt(request.getParameter("empno"));
System.out.println("empno->"+empno);
cs.registerOutParameter(2, Types.DOUBLE); //급여
cs.setInt(1, empno); //사번
cs.execute();
out.println("급여 : " + cs.getDouble(2));
cs.close();
conn.close();
%>
</body>
</html>
- scott_0718>> EMP_INFO(프로시저) (현장 HW)
create or replace PROCEDURE Emp_info3
-- 현장 HW p_empno IN , p_sal OUT
(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 );
--DBMS_OUTPUT.PUT_LINE('급 여:'||p_sal );
END Emp_info3;
(폴더:och10_dbcp_mySql)
- mySelectIn.jsp (현장 HW)
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@page import="och10.Professor"%>
<%@page import="java.util.ArrayList"%>
<%@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"%>
<%@ 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>
<%
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/MySql");
Connection conn = ds.getConnection();
//현장 HW
ArrayList<Professor> al = new ArrayList<Professor>();
String sql = "select profno, name from professor";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
Professor professor = new Professor();
professor.setProfno(rs.getInt(1));
professor.setName(rs.getString(2));
al.add(professor);
}
request.setAttribute("al", al);
rs.close();
stmt.close();
conn.close();
%>
<h2>보고 싶은 교수 번호를 선택하세요</h2>
<form action="mySelect.jsp">
<select name="pno">
<c:forEach var="professor" items="${al }">
<option value="${professor.profno }">${professor.profno} ${professor.name}</option>
</c:forEach>
</select><p>
<input type="submit" value="선택완료">
</form>
</body>
</html>
- mySelect.jsp (현장 HW)
<%@page import="java.util.ArrayList"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@page import="och10.Professor"%>
<%@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"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/MySql");
Connection conn = ds.getConnection();
String profno = request.getParameter("pno");
String sql = "select profno, name, sal, hiredate from professor where profno="+profno;
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
System.out.println("Professor list sql->" +sql);
//현장 HW
//1. pno Get
//2. pno에 맞는 profnr, name, sal, hiredate
//3. Professor DTO ==> p
Professor p = new Professor();
if (rs.next()){
System.out.println("Professor profno->" +rs.getInt(1));
System.out.println("Professor name->" +rs.getString(2));
System.out.println("Professor Sal->" +rs.getString(3));
System.out.println("Professor hiredate->" +rs.getDate(4));
p.setProfno(rs.getInt(1));
p.setName(rs.getString(2));
p.setSal(rs.getInt(3));
p.setHiredate(rs.getDate(4));
//4. setAttribute("professor", p);
request.setAttribute("professor", p);
}
rs.close();
stmt.close();
conn.close();
// 5. myResult.jsp 이동
RequestDispatcher rd = request.getRequestDispatcher("myResult.jsp");
rd.forward(request, response);
%>
</body>
</html>
- myResult.jsp (현장 HW)
<%@ 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>
</head>
<body>
<h2>professor 정보</h2>
사번 : ${professor.profno }<p>
이름 : ${professor.name }<p>
급여 : ${professor.sal }<p>
입사일 : ${professor.hiredate }<p>
</body>
</html>
(폴더:och11)
- cookie2.jsp
Tip)- Encoder
- a href
- 웹 문서가 너무 길 경우 필요한 곳마다 문서 안에 이름을 붙여놓고 그 위치로 한번에 이동하는 링크를 만들 수 있는데, 이 기능을 앵커(anchor)라고 함
- <a> 태그의 href 속성은 링크된 페이지의 URL을 명시함
<%@page import="java.net.URLEncoder"%>
<%@ 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>
<%
Cookie cook2 = new Cookie("name",URLEncoder.encode("중앙정보","utf-8"));
response.addCookie(cook2);
%>
쿠키저장 성공<p>
<a href="cookView2.jsp">쿠키보기</a>
</body>
</html>
- cookView2.jsp
Tip)- Decoder
<%@page import="java.net.URLDecoder"%>
<%@ 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>
<%
Cookie cooks[] = request.getCookies();
if (cooks != null) {
for (int i = 0; i < cooks.length; i++) {
if (cooks[i].getName().equals("name")) {
out.println("쿠키값 : " + URLDecoder.decode(cooks[i].getValue(),"utf-8"));
}
}
}
%>
</body>
</html>
- person.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>
<style type="text/css">
table { background-color: pink;}
tr:hover { background-color: yellow;}
</style>
</head>
<body>
<h2>회원가입</h2>
<form action="agree.jsp">
<table border="1">
<tr>
<td>아이디</td><td><input type="text" name="id"
required="required">
</td>
</tr>
<tr>
<td>패스워드</td><td><input type="password" name="password"
required="required">
</td>
</tr>
<tr>
<td>이름</td><td><input type="text" name="name"
required="required">
</td>
</tr>
<tr>
<td><input type="submit" value="확인"></td>
<td><input type="reset" value="취소"></td>
</tr>
</table>
</form>
</body>
</html>
- agree.jsp >>약관 동의 창 만들기
Tip)- request가 아닌 session.attribute로 하면 좋은 점: session을 끊지 않는 한 공유하며 함께 쓰기 좋음
<%@ 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 id = request.getParameter("id");
String password = request.getParameter("password");
String name = request.getParameter("name");
session.setAttribute("id", id);
session.setAttribute("password", password);
session.setAttribute("name", name);
%>
<h2>약관 동의</h2>
-----------------------------------------------------------<br>
1. 회원 정보는 웹 사이트의 운영을 위해서만 사용됩니다. <br>
2. 웹 사이트의 정상 운영을 방해하는 회원은 탈퇴 처리합니다.<br>
-----------------------------------------------------------<br>
<form action="subscribe.jsp">
동의 <input type="radio" name="agree" value="y"><p>
거부 <input type="radio" name="agree" value="n"><p>
<input type="submit" value="확인">
</form>
</body>
</html>
- MemberDto.class
package och11;
import java.util.Date;
public class MemberDto {
private String id;
private String password;
private String name;
private Date reg_date;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getReg_date() {
return reg_date;
}
public void setReg_date(Date reg_date) {
this.reg_date = reg_date;
}
}
- MemberDao.class>> 밑에 로직 추가하는 것이 숙제
package och11;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class MemberDao {
private Connection getConnection() throws SQLException {
Connection conn = null;
try {
Context ctx = new InitialContext(); //surround try catch로 감싸주기
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/OracleDB");
conn = ds.getConnection();
} catch (NamingException e) {
// TODO Auto-generated catch block
System.out.println("e.getMessage()->"+e.getMessage());
}
return conn;
}
public int insert(MemberDto member) throws SQLException {
Connection conn = null;
int result = 0;
PreparedStatement pstmt = null;
String sql = "insert into member1 values(?,?,?,sysdate)";
try {
conn = getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, member.getId());
pstmt.setString(2, member.getPassword());
pstmt.setString(3, member.getName());
result = pstmt.executeUpdate();
}catch(Exception e) { System.out.println(e.getMessage());
}finally {
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
}
return result;
}
}
- error.jsp >> 에러났을때 페이지 만들기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isErrorPage="true"%>
<% response.setStatus(200); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>공지사항</h2>
공사중입니다<p>
<%=exception.getMessage() %>
</body>
</html>
- subscribe.jsp >>DTO, DAO 사용
Tip)- Member Dao
<%@page import="och11.MemberDto"%>
<%@page import="och11.MemberDao"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" errorPage="../error.jsp"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String chk = "";
String agree = request.getParameter("agree");
if (agree.equals("y")){
String id = (String)session.getAttribute("id"); //setAttribute기능과 같음
String password = (String)session.getAttribute("password");
String name = (String)session.getAttribute("name");
MemberDao md = new MemberDao();
MemberDto member = new MemberDto();
member.setId(id);
member.setPassword(password);
member.setName(name);
int result = md.insert(member); //HW. insert를 MemberDao 다음에 만들어줌
if (result > 0) chk = "success";
else chk = "fail";
} else chk = "fail";
session.invalidate();
out.print("invalidate() 적용 후에도 "+session.getId()+"<br>");
response.sendRedirect("result.jsp?chk="+chk);
%>
</body>
</html>
- ORACL의 MEMBER1 TBL 생성 >> 회원정보 DB저장용
CREATE TABLE MEMBER1
(id varchar2(10)
CONSTRAINT PK_MEMBER1_ID PRIMARY KEY, --ID
password VARCHAR2(20), --비밀번호
name VARCHAR2(100), --이름
reg_date Date --일자
) TABLESPACE "SYSTEM";
insert into SCOTT.MEMBER1 (ID,password,NAME,REG_DATE)
values ('aa','1234','김유신',sysdate);
- result.jsp
질문목록
1. person부터 result의 흐름 (특히 memberDao의 역할과 흐름)
수업교재
10. Database
1. 데이터베이스의 정의
- 파일과 마찬가지로 보조기억장치에 데이터를 저장하는 수단
- 자바 프로그램에서 데이터베이스를 사용하려며 JDBC 드라이버가 필요함
2. 데이터베이스의 사용방법
1. JDBC 드라이버 로드
Class.forName('oracle.jdbc.driver.OracleDriver');
Mysql : com.mysql.cj.jdbc.Driver
- 위의 로직을 통해 JDBC 드라이버를 로드함
2. DB와 연결
- 연결을 하기 위해서는 먼저 프로토콜, 서브프로토콜, 서브네임으로 이루어진 데이터베이스 URL을 알아두어야 함
- Oracle: “jdbc:oracle:thin:@127.0.0.1:1521:orcl";
- Mysql : jdbc:mysql://localhost:3306/db명?characterEncoding=UTF-8&serverTimezone=UTC
- 서브네임의 작성방법은 DBMS의 종류마다 다르므로 다른 DBMS를 사용할 때는 관련 매뉴얼을 찾아보아야 함
- 데이터베이스로 연결을 맺기 위해서는 java.sql.DriverManager클래스의 getConnection메서드를 호출해야 함
아래 메서드로 데이터베이스와 연결에 성공하면 java.sql.Connection 인터페이스 타입의 객체를 만들어서 리턴
conn = DriverManager.getConnection(url,“scott“,”tiger" );
3. DB에 데이터를 읽거나 씀(반복 가능)
- 1. 데이터베이스에 있는 데이터를 읽어오려면 우선 Connection 객체에 대해 createStatement 메서드를 호출해서 java.sql.Statement 타입 객체를 구해야 함
Statement stmt = conn.createStatement();
- 2. Statement 객체에 대해 executeQuery 메서드를 호출하면 데이터베이스에 있는 데이터를 읽어올 수 있다
ResultSet rs = stmt.excuteQuery("select*from goodsinfo where code = '10002'");
- 3. executeQuery 메서드가 리턴한 ResultSet 객체에 대해 next 메서드를 호출하면 데이터베이스로부터 읽은 데이터를 순서대로 가져올 수 있다, 레코드 단위로 이동하는 next() 메서드를 사용한다
boolean exists = rs.nest();
- 4. next 메서드를 호출한 다음에 ResultSet 객체에 대해 getInt, getString, getFloat 등의 메서드를 호출하면 특정 데이터 항목 값을 가져올 수 있다
String code = rs.getString("code");
//getString: 문자 데이터를 가져오는 메서드
int price = rs.getInt("price");
//getInt: 정수 데이터를 가져오는 메서드
4. DB와 연결을 끊음
- Connection 객체에 대해 close 메서드를 호출
conn.close();
5. 데이터를 수정하고 삭제하는 방법
- 데이터베이스에 있는 데이터를 수정할 때는 executeUpdate 메서드에 uptdate 문을 파라미터로 넘겨줘야 한다
- 데이터베이스에 있는 데이터 삭제할 때는 executeUpdate 메서드에 delete 문을 파라미터로 넘겨줘야 한다
int rowNum = stmt.executeUpdate("update userinfo set password :="비밀번호" where id = "아이디");
3. JDBC 드라이버와 DBMS
1. JDBC 드라이버
- DBMS와 통신을 담당하는 자바 클래스
- DBMS와 통신하기 위해서는 먼저 로딩해 주어야 함
로딩 코드: Class.forName("JDBC 드라이버 클래스의 완전한 이름");
2.DBMS
- DBMS별로 알맞은 JDBC 드라이버가 필요함, 보통 jar 파일로 제공됨, JDBC 드라이버에 따라 형식이 다름
- MySQL: com.mysql.cj.jdbc.Driver
- Oracle: oracle.jdbc.driver.OracleDriver
- MS SQL 서버: com.microsoft.sqlserver.jdbc.SQLServerDriver
- DBMS URL이란?: DBMS와의 연결을 위한 식별 값
- MySQL: jdbc:mysql://HOST[:PORT]/DBNAME
- Oracle: jdbc:oracle:thin:@HOST:PORT:SID
- MSSQL: jdbc:sqlserver://HOST[:PORT];databaseName=DB
- 일반적인 구성: jdbc:[DBMS]:[데이터베이스식별자]
4. 커넥션 풀(DBCP)⭐
1. DBCP 커넥션 풀이란?
- 데이터베이스 연결을 효율적으로 관리하기 위한 기술
- 데이터 베이스에 동시에 접속할 수 있는 사용자 수는 한정되어 있는데, 웹서버에는 동시에 수백, 수천의 사용자들이 접속할 수 있음. 웹 애플리케이션이 실행될 때마다 데이터베이스로 새로운 접속을 맺는 것은 현실적으로 불가능하므로, 데이터베이스 몇 개의 접속을 맺어서 데이터베이스 커넥션 풀(Database Connection Pool)에 저장해놓고, 필요한 웹 애플리케이션이 빌려쓰고 반환하는 방식을 사용해야 함
2. DBCP의 기능 및 장점
- 연결 풀링 Connection Pooling (우리말로 풀어쓰자면 연결 선별 취합 검사 정도?)
: 데이터베이스 연결을 미리 여러 개 만들어두고, 애플리케이션이 필요할 때 이 연결들을 재사용함 - 자원 관리 Resource Management: 연결을 효율적으로 관리하여 자원의 낭비를 줄이고, 필요시 자동으로 연결을 닫거나 재사용함
- 성능 향상 Performance Improvement: 연결 생성 및 종료에 드는 시간을 절약하여 애플리케이션의 응답 속도를 향상시킴
3. 적용 방법
- 필요한 라이브러리 추가: Apache Commons DBCP와 Commons Pool 라이브러리를 프로젝트에 추가하기
- 'context.xml' 설정: context.xml. 파일에 데이터베이스 연결과 관련된 코드를 resource로 작성하고 web.xml 파일에서 불러들인 후 사용 가능, Context.xml - WebContent 폴더의 META-INF 폴더에 작성
- JNDI를 사용한 데이터베이스 연결: JSP 파일이나 서블릿에서 JNDI를 사용하여 데이터베이스 연결을 획득함
- 연결 사용 및 반납: JSP 파일이나 서블릿에서 DatabaseUtils.getConnection() 메소드를 사용하여 연결을 획득하고 사용한 후 반납함
4. 작동 방식
- 초기화: 애플리케이션이 시작될 때 일정 수의 데이터베이스 연결을 생성하여 풀pool(선별함?)에 보관함
- 대여 및 반납: 클라이언트 요청이 들어오면 풀에서 연결을 대여하고, 사용이 끝나면 반납함
- 동적 조정: 사용량에 따라 연결의 수를 동적으로 조정하여 효율성을 극대화함
5. JNDI
- 분산환경에 서비스하고자 하는 자원을 이 Naming & Directory 서버에 이름값과 실제 자원을 연결하여 등록하면 해당 자원을 이용하고자 하는 다른 애플리케이션에서 Naming & Directory 서버에 접근하여 이름값만을 가지고 자원을 연결하여 이용할 수있게 하는 개념
- Java Naming Directory interface: 이름을 통해서 Database Pooling Resource에 접근하는 방식
- 디렉터리 서비스에서 제공하는 데이터 및 객체를 발견하고 참고(lookup)하기 위한 자바 API
11. Cookie와 Session
1. Cookie
1. 정의
- 쿠키 기술은 웹서버가 웹 브라우저로 데이터를 보냈다가 웹 서버 쪽으로 다시 되돌려 받는 방법을 사용함
- 첫 번째 웹 컴포넌트는 웹 브라우저로 HTML 문서를 보낼 때 보낼 때 전달한 데이터를 함께 보내며, 웹 브라우저는 그 데이터를 저장해 두었다가 두 번째 웹 컴포넌트를 호출할 때 URL과 함께 웹 서버로 보낸다
2. 특징
- 웹 서버가 웹 브라우저와 정보를 주고받는 방법 중의 하나
- 쿠키는 웹 브라우저가 보관하고 있는 데이터로 웹 서버에 요청을 보낼 때 함께 전송
- 웹 브라우저가 전송한 쿠키를 사용하여 필요한 데이터를 읽을 수 있음
- 쿠키의 동작 방식
- 쿠키 생성 단계: 웹 서버 측에서 생성
- 쿠키 저장 단계: 웹 브라우저는 응답 데이터에 포함된 쿠키를 쿠키 저장소에 보관하는데 종류에 따라 메모리나 파일로 저장
- 쿠키 전송 단계: 서버 측에서 요청할 때마다 웹 서버에 전송
- 쿠키의 구성
- 이름: 쿠키를 구별하는데 사용하는 이름
- 값: 쿠키의 이름과 관련된 값
- 유효 시간: 쿠키의 유지 시간
- 도메인: 쿠키를 전송할 도메인
- 경로: 쿠키를 전송할 요청 경로
3. 쿠키 생성 및 읽기
- 쿠키 생성 및 추가 메서드
- new Cookie("쿠키 이름", "쿠키의 값");
- response.addCookie(쿠키 객체)
- Cookie 클래스가 제공하는 메서드
- String getName()
- String getvalue()
- void setValue(String value)
- void setDomain(String pattern): 쿠키가 전송될 도메인을 설정
- String getDomain()
- void setPath(String url): 쿠카가 전송할 경로를 지정
- String getPath()
- void setMaxAge(int expiry): 유효 시간을 초 단위로 설정(음수일 경우 웹 브라우저가 닫힐 떄 쿠키가 삭제됨)
- int getMaxAge()
- 쿠키 가져오기 메서드
- Cookie[] request.getCookies()
2. Session⭐
1. 정의
- 세션 기술은 웹 브라우저를 거치지 않고 웹 서버에 있는 데이터 영역을 통해 데이터를 전달하는 방법
- 첫 번째 웹 컴포넌트는 웹 서버 쪽에 데이터를 저장해 놓고, 그 데이터를 읽기 위해 필요한 세션 아이디만 웹 브라우저로 보낸다. 웹 브라우저는 아이디를 저장해 두었다가 두 번째 웹 컴포넌트를 호출할 때 웹 서버로 보내며, 그 아이디를 이용하면 저장된 데이터를 찾을 수 있다
2. 생성 방법
- 코드에서 생성하기: <%@ page session = "true" %>
- request 객체로부터 생성하기: HttpSession 변수 = request.getSession() ==> session을 시작하는 메서드
- 서블릿 클래스에서 세션을 시작하기 위해서는 doGet, doPost 메서드의 HttpServletRequest 파라미터에 대해 getSession 이라는 메서드를 호출해야 함
- getSession 메서드는 세션 성보를 포함하는 javax.servlet.http.HttpSession 타입의 객체를 리턴함
getSession 메서드가 리턴한 HttpSession 객체에 대해setAttribute라는 메서드를 호출하면 세션 데이터 영역에 데이터를 저장할 수 있음 - 세션이 있으면 그 세션을 리턴하고 없으면 새로 생성해서 리턴
- 생성된 경우에만 리턴받고자 하는 경우에는 getSession에 매개변수로 false를 전달
session.setAttribute("ID", "lee77");
// 데이터이름 데이터값
3. 메서드
- Session에서 속성 사용
- session.setAttribute("속성명", "값")
- session.getAttribute("속성명")
객체 메소드 | 설명 |
setAttribute(String name, Object value) | 세션 객체에 속성을 저장한다 |
removeAttribute(String name) | 저장된 속성을 제거한다 |
getAttribute(String name) | 저장된 속성을 반환한다 |
getId() | 클라이언트의 세션 ID값을 반환한다 |
setMaxInactiveInterval(int seconds) | 세션의 유지 시간을 설정한다 |
getMaxInactiveInterval() | 세션의 유지 시간을 반환한다 |
invalidate() | 현재 세션의 정보들을 모두 제거한다 |
4. JSP 페이지에서 세션 기술을 사용하는 방법
- Servlet 클래스에서는 새로운 세션을 시작하거나, 진행 중인 세션을 계속하기 위해서는 getSession 메서드를 호출해야 함
- JSP 페이지에서는 JSP 페이지가 Servlet 클래스로 변환되는 과정에서 이 메서드를 호출하는 코드가 자동으로 추가되기 때문에 getSession 메서드를 호출할 필요가 없음
- session 내장 변수를 사용하면 세션 데이터 영역에 데이터를 저장할 수도 있고, 그 영역에 있는 데이터를 읽어오거나 삭제할 수도 있음
오늘의 숙제
- memberDao.jsp
package och11;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class MemberDao {
private Connection getConnection() throws SQLException {
Connection conn = null;
try {
Context ctx = new InitialContext(); //surround try catch로 감싸주기
DataSource ds = (DataSource)ctx.lookup("java.comp/env/jdbc/OracleDB");
conn = ds.getConnection(); //throws 하기
} catch (NamingException e) {
// TODO Auto-generated catch block
System.out.println("+e.getMessage()->"+e.getMessage());
}
return conn;
}
public int insert(MemberDto member) throws SQLException {
Connection conn = null;
int result = 0;
PreparedStatement pstmt = null;
String sql = "insert into member1 values(?,?,?,sysdate)";
try {
conn = getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, member.getId());
pstmt.setString(2, member.getPassword());
pstmt.setString(3, member.getName());
result = pstmt.executeUpdate();
}catch(Exception e) { System.out.println(e.getMessage());
}finally {
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
}
return result;
}
}
- result.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>
EL chk : ${chk } <p>
${param.chk } <p>
<%
String chk = request.getParameter("chk");
if (chk.equals("success"))
out.println("축하합니다 회원가입");
else
out.println("이미 존재하는 아이디입니다");
%>
</body>
</html>
'JSP > Java Script' 카테고리의 다른 글
2024_07_22_월 (0) | 2024.07.22 |
---|---|
2024_07_19_금 ⭐⭐⭐ (0) | 2024.07.19 |
2024_07_17_수 (0) | 2024.07.17 |
2024_07_16_화 (0) | 2024.07.16 |
2024_07_15_월 (0) | 2024.07.15 |