서블릿 - DB 연결
1. servletdb 프로젝트 생성
프로젝트 우클릭 - build path - classpath 에 add external jars - servlet-api.jar 추가
2. sqldeveloper 테이블 생성 (member_list)
id,pwd,name,email,joindate
3. 프로젝트 폴더에 오라클 드라이버 넣기
ojdbc8jar webapp/web-inf/lib에 붙여넣기
- 회원가입 (post 방식)
- MemberServlet.java
package servletdb.ex01;
import jakarta.servlet.http.HttpServlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("/member")
public class MemberServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandle(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandle(request, response);
}
private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
MemberDAO dao = new MemberDAO(); //SQL문으로 조회할 MemberDAO 객체
List<MemberVO> list = dao.listMembers(); //회원리스트 불러오기
out.print("<html><body>");
out.print("<table border=1>");
out.print("<tr align='center' bgcolor='azure'>");
out.print("<th>아이디</th><th>비밀번호</th><th>이름</th><th>이메일</th><th>가입일자</th></tr>");
for (int i=0;i<list.size();i++) {
out.print("<tr><td>"+list.get(i).getId()+"</td><td>"+list.get(i).getPwd()+"</td><td>"
+list.get(i).getName()+"</td><td>"+list.get(i).getEmail()
+"</td><td>"+list.get(i).getJoindate()+"</td></tr>");
}
out.print("</table>");
out.print("</body></html>");
}
}
※ sqldeveloper 사용자계정 우클릭 - 속성 - 호스트 이름 확인
- servletdb.ex01/MemberDAO.java
=> Data Access Object : 데이터베이스 연동, 기능(회원리스트 리턴) 수행할 클래스
(서블릿-회원정보 데이터베이스 연결, 쿼리 실행, 각 컬럼값 변수에 담은 후 MemberVO 회원정보 객체에 값 세팅, 회원정보목록에 MemberVO 객체 하나씩 담기)
package servletdb.ex01;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class MemberDAO {
private static final String driver = "oracle.jdbc.driver.OracleDriver";
private static final String url = "jdbc:oracle:thin:@localhost:1521:XE";
private static final String user = "데이터베이스 아이디";
private static final String pwd = "비번";
private Connection con; //db 연동 객체
private Statement stmt; //쿼리문 실행 명령 (=sqldeveloper 실행 버튼)
//회원정보 목록 처리
public List<MemberVO> listMembers(){
List<MemberVO> list = new ArrayList<MemberVO>();
try {
connDB();
String query = "select * from member_list"; //실행할 쿼리문
ResultSet rs = stmt.executeQuery(query); //쿼리문 파라미터를 실행, 결과를 ResultSet 변수에 담음
while(rs.next()) { //rs => 커서 역할 (검색 결과 집합)
String id = rs.getString("id"); //컬럼값 하나 가져옴 (1번째, 2번째, ..) //파라미터로 0도 가능(0번째 컬럼)
String pwd = rs.getString("pwd");
String name = rs.getString("name");
String email = rs.getString("email");
Date joinDate = rs.getDate("joindate");
//데이터타입 숫자일 시 getInt 또는 getDouble
MemberVO vo = new MemberVO(); //위 객체들 담음
vo.setId(id);
vo.setPwd(pwd);
vo.setName(name);
vo.setEmail(email);
vo.setJoindate(joinDate);
list.add(vo);
}
rs.close();
stmt.close();
con.close();
} catch (Exception e){
System.out.println("자료 처리 중 에러 발생");
}
return list;
}
//데이터베이스 연결, 상태 확인
private void connDB() {
try {
Class.forName(driver);
System.out.println("오라클 드라이버 로딩 성공");
con = DriverManager.getConnection(url,user,pwd);
System.out.println("Connection 생성 성공");
stmt = con.createStatement();
System.out.println("Statement 생성 성공");
} catch(Exception e) {
System.out.println("DB 연결 실패"); //web-inf/lib/드라이버.jar 파일 설치 오류
}
}
}
- MemberVO.java
=> ValueObject : 컬럼들의 정보 저장할 클래스 (각 회원의 정보)
package servletdb.ex01;
import java.sql.Date;
public class MemberVO {
private String id; //캡슐화 => 정보 은닉
private String pwd;
private String name;
private String email;
private Date joindate;
public MemberVO() {
System.out.println("MemberVO 생성자 호출");
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getJoindate() {
return joindate;
}
public void setJoindate(Date joindate) {
this.joindate = joindate;
}
}
https://surhommejk.tistory.com/285
커넥션 풀 (Conection Pool) 통해 데이터베이스 연동
JDBC 드라이버를 통해 자바-데이터베이스 연결하는 작업을 모든 요청마다 매번 새로 처리
=> 네트워크 연결과 해제를 계속 반복하면서 성능 저하
=> 커넥션 풀로 해결
커넥션 풀 : 웹 애플리케이션 실행과 동시에 연동할 데이터베이스와의 연결을 미리 설정해둠
->필요할 때마다 미리 연결한 상태를 이용해 빠르게 데이터베이스와 연동
=> 미리 데이터베이스와 연결시킨 상태를 유지하는 기술
Connection 객체를 미리 생성
=> 요청이 있을 때마다 생성된 Connection을 빌려옴
=> 요청 처리 후 Pool에 반납 (반복)
사용법
1. 커넥션풀 기능 관련 jar 파일을 /WEB-INF/lib 폴더에 설치
2. 객체 생성 시 연결할 데이터베이스 정보를 JNDI로 설정
3. DAO 클래스에서 데이터베이스 연동 시 미리 설정한 JNDI로 연결 (HashMap형태)
- 커넥션풀 사용 전
- MemberVO
- MemberServlet
package servletdb.ex02;
import jakarta.servlet.http.HttpServlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("/member2") ////
public class MemberServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandle(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandle(request, response);
}
private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
MemberDAO dao = new MemberDAO(); //SQL문으로 조회할 MemberDAO 객체
List<MemberVO> list = dao.listMembers();
out.print("<html><body>");
out.print("<table border=1>");
out.print("<tr align='center' bgcolor='azure'>");
out.print("<th>아이디</th><th>비밀번호</th><th>이름</th><th>이메일</th><th>가입일자</th></tr>");
for (int i=0;i<list.size();i++) {
out.print("<tr><td>"+list.get(i).getId()+"</td><td>"+list.get(i).getPwd()+"</td><td>"
+list.get(i).getName()+"</td><td>"+list.get(i).getEmail()
+"</td><td>"+list.get(i).getJoindate()+"</td></tr>");
}
out.print("</table>");
out.print("</body></html>");
}
}
- MemberDAO
package servletdb.ex02;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class MemberDAO {
private static final String driver = "oracle.jdbc.driver.OracleDriver";
private static final String url = "jdbc:oracle:thin:@DESKTOP-HU410J6:1521:XE";
private static final String user = "userdb";
private static final String pwd = "1234";
private Connection con; //db 연동 객체
//private Statement stmt; //단점 : db 연동할 때마다 sql문 컴파일 -> 속도 느림
private PreparedStatement pstmt; //sql문 미리 컴파일 후 재사용 //연동, 반복 처리에 유용 //데이터베이스 컬럼 가져올 때 명령어 간결 (?) /////
//회원정보 목록 처리
public List<MemberVO> listMembers(){
List<MemberVO> list = new ArrayList<MemberVO>();
try {
connDB(); //db 연결 (서블릿에서 요청할 때마다)
String query = "select * from member_list"; //실행할 쿼리문
pstmt=con.prepareStatement(query); ////연결하면서 쿼리문 가져와 저장하고 있다가 실행할 때마다 불러옴 (cf. 실행하면서 쿼리문 가져옴)
ResultSet rs = pstmt.executeQuery(); //미리 설정한 sql문 실행 ////
while(rs.next()) { //rs => 커서 역할 (검색 결과 집합)
String id = rs.getString("id"); //컬럼값 하나 가져옴 (1번째, 2번째, ..) //파라미터로 0도 가능(0번째 컬럼)
String pwd = rs.getString("pwd");
String name = rs.getString("name");
String email = rs.getString("email");
Date joinDate = rs.getDate("joindate");
//데이터타입 숫자일 시 getInt 또는 getDouble
MemberVO vo = new MemberVO(); //위 객체들 담음
vo.setId(id);
vo.setPwd(pwd);
vo.setName(name);
vo.setEmail(email);
vo.setJoindate(joinDate);
list.add(vo);
}
rs.close();
pstmt.close(); ////
con.close();
} catch (Exception e){
System.out.println("자료 처리 중 에러 발생");
}
return list;
}
//데이터베이스 연결 상태 확인
private void connDB() {
try {
Class.forName(driver);
System.out.println("오라클 드라이버 로딩 성공");
con = DriverManager.getConnection(url,user,pwd);
System.out.println("Connection 생성 성공");
//pstmt = con.prepareStatement(driver); ////
//System.out.println("Statement 생성 성공");
} catch(Exception e) {
System.out.println("DB 연결 실패"); //web-inf/lib/드라이버.jar 파일 설치 오류
}
}
}
=> 현재 : 웹 애플리케이션에서 데이터베이스 요청이 있을 때마다 데이터베이스를 연결함
=> 비효율적
=> 서버에 맡기기 (=Connection Pool)
- 커넥션풀 연결
1.
커넥션풀 관련 jar => WEB-INF/lib 에 저장
2. 서버가 db 연결 담당
Server - context.xml - 컨텍스트 내부에 태그 추가
<Resource name="jdbc/oracle" auth="Container" type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@DESKTOP-HU410J6:1521:XE" username="userdb" password="1234" maxActive="50" maxWait="-1"></Resource>
※ maxActive : 동시에 들어올 수 있는 데이터 수
- 커넥션풀 사용 후
- MemberServlet
매핑주소 변경 (/member3)
- MemberDAO
package servletdb.ex03;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class MemberDAO {
// private static final String driver = "oracle.jdbc.driver.OracleDriver";
// private static final String url = "jdbc:oracle:thin:@DESKTOP-HU410J6:1521:XE";
// private static final String user = "userdb";
// private static final String pwd = "1234";
private Connection con; //db 연동 객체
//private Statement stmt; //단점 : db 연동할 때마다 sql문 컴파일 -> 속도 느림
private PreparedStatement pstmt; //sql문 미리 컴파일 후 재사용 //연동, 반복 처리에 유용 //데이터베이스 컬럼 가져올 때 명령어 간결 (?)
private DataSource dataFactory; //서버에서 데이터 가져옴 ////
public MemberDAO() { ////
try {
Context ctx = new InitialContext(); //서버의 컨텍스트 정보 가져오기 위해 연결
Context envContext = (Context) ctx.lookup("java:/comp/env"); ////
dataFactory = (DataSource) envContext.lookup("jdbc/oracle"); //미리 연결된 데이터베이스 가져옴 ////
} catch(Exception e) {
System.out.println("DB 연결 실패");
}
}
//회원정보 목록
public List<MemberVO> listMembers(){
List<MemberVO> list = new ArrayList<MemberVO>();
try {
// connDB(); //db 연결 (서블릿에서 요청할 때마다)
con = dataFactory.getConnection(); //서버는 미리 연결된 상태에서 DataSource 이용해 db 연결 ////
String query = "select * from member_list"; //실행할 쿼리문
pstmt=con.prepareStatement(query); ////연결하면서 쿼리문 가져와 저장하고 있다가 실행할 때마다 불러옴 (cf. 실행하면서 쿼리문 가져옴)
ResultSet rs = pstmt.executeQuery(); //미리 설정한 sql문 실행
while(rs.next()) { //rs => 커서 역할 (검색 결과 집합)
String id = rs.getString("id"); //컬럼값 하나 가져옴 (1번째, 2번째, ..) //파라미터로 0도 가능(0번째 컬럼)
String pwd = rs.getString("pwd");
String name = rs.getString("name");
String email = rs.getString("email");
Date joinDate = rs.getDate("joindate");
//데이터타입 숫자일 시 getInt 또는 getDouble
MemberVO vo = new MemberVO(); //위 객체들 담음
vo.setId(id);
vo.setPwd(pwd);
vo.setName(name);
vo.setEmail(email);
vo.setJoindate(joinDate);
list.add(vo);
}
rs.close();
pstmt.close(); ////
con.close();
} catch (Exception e){
System.out.println("자료 처리 중 에러 발생");
}
return list;
}
// //데이터베이스 연결 상태 확인
// private void connDB() {
// try {
// Class.forName(driver);
// System.out.println("오라클 드라이버 로딩 성공");
// con = DriverManager.getConnection(url,user,pwd);
// System.out.println("Connection 생성 성공");
// //pstmt = con.prepareStatement(driver);
// //System.out.println("Statement 생성 성공");
// } catch(Exception e) {
// System.out.println("DB 연결 실패"); //web-inf/lib/드라이버.jar 파일 설치 오류
// }
// }
}
- 회원가입 (insert 작업 추가)
- webapp/memberForm.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원가입 창</title>
<script type="text/javascript">
function fn_sendMember(){
let frmMember = document.frmMember;
let id = frmMember.id.value;
let pwd = frmMember.pwd.value;
let name = frmMember.name.value;
let email = frmMember.email.value;
if(id.length==0||id==""){
alert('아이디를 입력해주세요');
} else if (pwd.length==0||pwd==""){
alert('비밀번호를 입력해주세요');
} else if (name.length==0||name==""){
alert('이름을 입력해주세요');
} else if (email.length==0||email==""){
alert('이메일을 입력해주세요');
} else {
frmMember.method="post";
frmMember.action="member4";
frmMember.submit(); //서블릿을 전송
}
}
</script>
</head>
<body>
<form name=frmMember>
<h2>회원가입 창</h2>
<table>
<tr>
<td>아이디</td>
<td><input type="text" name="id"></td>
</tr>
<tr>
<td>비밀번호</td>
<td><input type="password" name="pwd"></td>
</tr>
<tr>
<td>이름</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td>이메일</td>
<td><input type="text" name="email"></td>
</tr>
</table>
<input type="button" value="가입하기" onclick="fn_sendMember()">
<input type="reset" value="다시 입력">
<input type="hidden" name="command" value="addMember"> <!-- ★어떤 목적(탈퇴면 value="delMember")으로 서버에 접근하는지 확인 -->
</form>
</body>
</html>
- MemberServlet
package servletdb.ex04;
import jakarta.servlet.http.HttpServlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("/member4")
public class MemberServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandle(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandle(request, response);
}
private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//가입 버튼 클릭 시 db에 추가하기, 알림창 생성
response.setContentType("text/html;charset=utf-8");
MemberDAO dao = new MemberDAO(); //서버에 연결돼있으므로 db 연결 따로 X
PrintWriter out = response.getWriter();
String command = request.getParameter("command");
if (command!=null && command.equals("addMember")){
String _id = request.getParameter("id"); //_변수는 클라이언트에게 받아온 값
String _pwd = request.getParameter("pwd");
String _name = request.getParameter("name");
String _email = request.getParameter("email");
MemberVO vo = new MemberVO(); //한명의 회원 정보로 저장, db에 넘김
vo.setId(_id);
vo.setPwd(_pwd);
vo.setName(_name);
vo.setEmail(_email);
dao.addMember(vo);
out.print("회원가입이 완료되었습니다");
}
}
}
- MemberDAO
package servletdb.ex04;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class MemberDAO {
private Connection con; //db 연동 객체
private PreparedStatement pstmt; //sql문 미리 컴파일 후 재사용 //연동, 반복 처리에 유용 //데이터베이스 컬럼 가져올 때 명령어 간결 (?)
private DataSource dataFactory; //서버에서 데이터 가져옴
public MemberDAO() {
try {
Context ctx = new InitialContext(); //서버의 컨텍스트 정보 가져오기 위해 연결
Context envContext = (Context) ctx.lookup("java:/comp/env");
dataFactory = (DataSource) envContext.lookup("jdbc/oracle"); //미리 연결된 데이터베이스 가져옴
} catch(Exception e) {
System.out.println("DB 연결 실패");
}
}
//회원정보 목록
public List<MemberVO> listMembers(){
List<MemberVO> list = new ArrayList<MemberVO>();
try {
con = dataFactory.getConnection(); //서버는 미리 연결된 상태에서 DataSource 이용해 db 연결
String query = "select * from member_list"; //실행할 쿼리문
pstmt=con.prepareStatement(query); ////연결하면서 쿼리문 가져와 저장하고 있다가 실행할 때마다 불러옴 (cf. 실행하면서 쿼리문 가져옴)
ResultSet rs = pstmt.executeQuery(); //미리 설정한 sql문 실행
while(rs.next()) { //rs => 커서 역할 (검색 결과 집합)
String id = rs.getString("id"); //컬럼값 하나 가져옴 (1번째, 2번째, ..) //파라미터로 0도 가능(0번째 컬럼)
String pwd = rs.getString("pwd");
String name = rs.getString("name");
String email = rs.getString("email");
Date joinDate = rs.getDate("joindate");
//데이터타입 숫자일 시 getInt 또는 getDouble
MemberVO vo = new MemberVO(); //위 객체들 담음
vo.setId(id);
vo.setPwd(pwd);
vo.setName(name);
vo.setEmail(email);
vo.setJoindate(joinDate);
list.add(vo);
}
rs.close();
pstmt.close();
con.close();
} catch (Exception e){
System.out.println("자료 처리 중 에러 발생");
}
return list;
}//listMembers 끝
//회원 추가
public void addMember(MemberVO memberVO) {
try {
con = dataFactory.getConnection();
String id = memberVO.getId();
String pwd = memberVO.getPwd();
String name = memberVO.getName();
String email = memberVO.getEmail();
String query = "insert into member_list(id, pwd, name, email) values(?,?,?,?)"; ////
pstmt=con.prepareStatement(query);
pstmt.setString(1, id); //첫번째 물음표에 id값 대입
pstmt.setString(2, pwd);
pstmt.setString(3, name);
pstmt.setString(4, email);
pstmt.executeUpdate();
pstmt.close();
} catch(Exception e) {
System.out.println("회원 추가 중 에러 발생");
}
}
}
'Programming > 국비학원' 카테고리의 다른 글
220927 - 서블릿 - 서블릿 확장 API (ServletContext 클래스), 쿠키, 세션 (0) | 2022.09.28 |
---|---|
220926 - 서블릿 -커넥션 풀, 서블릿 확장 API (포워드 / 바인딩) (0) | 2022.09.27 |
220922 - 서버 - 서블릿 예제 (0) | 2022.09.23 |
220921 - 서버 - 서블릿 매핑, 응답 및 요청 처리 (0) | 2022.09.22 |
220920 - 서버 - 웹 애플리케이션 개발 환경 구축 (0) | 2022.09.21 |