YJ의 새벽
JDBC 활용 연습용. ( 이메일 받아서 정보출력 ) 본문
community Dynamic Web Project 생성.
community server 생성.
오라클 넘어와서 . community 계정생성
CREATE USER community IDENTIFIED BY 1234;
GRANT CONNECT, RESOURCE TO community;
ALTER USER community DEFAULT TABLESPACE SYSTEM QUOTA UNLIMITED ON SYSTEM;
테스트용 테이블 생성.
CREATE TABLE "MEMBER" (
"MEMBER_NO" NUMBER PRIMARY KEY,
"MEMBER_EMAIL" VARCHAR2(50) NOT NULL,
"MEMBER_PW" VARCHAR2(30) NOT NULL,
"MEMBER_NICK" VARCHAR2(30) NOT NULL,
"MEMBER_TEL" CHAR(11) NOT NULL,
"MEMBER_ADDR" VARCHAR2(500),
"PROFILE_IMG" VARCHAR2(200),
"ENROLL_DT" DATE DEFAULT SYSDATE ,
"SECESSION_FL" CHAR(1) DEFAULT 'N'
);
COMMENT ON COLUMN "MEMBER"."MEMBER_NO" IS '회원 번호';
COMMENT ON COLUMN "MEMBER"."MEMBER_EMAIL" IS '회원 이메일(아이디)';
COMMENT ON COLUMN "MEMBER"."MEMBER_PW" IS '회원 비밀번호';
COMMENT ON COLUMN "MEMBER"."MEMBER_NICK" IS '회원 닉네임(중복x)';
COMMENT ON COLUMN "MEMBER"."MEMBER_TEL" IS '전화번호(- 미포함)';
COMMENT ON COLUMN "MEMBER"."MEMBER_ADDR" IS '회원 주소';
COMMENT ON COLUMN "MEMBER"."PROFILE_IMG" IS '회원 프로필 이미지';
COMMENT ON COLUMN "MEMBER"."ENROLL_DT" IS '회원 가입일';
COMMENT ON COLUMN "MEMBER"."SECESSION_FL" IS '탈퇴여부(Y:탈퇴, N:미탈퇴)';
-- 회원 번호 시퀀스
CREATE SEQUENCE SEQ_MEMBER_NO;
INSERT INTO MEMBER
VALUES(SEQ_MEMBER_NO.NEXTVAL, 'user01@kh.or.kr', 'pass01!',
'유저일', '01011111111', '04540,,서울시 중구 남대문로 120,,2층 A강의장',
NULL, DEFAULT, DEFAULT);
INSERT INTO MEMBER
VALUES(SEQ_MEMBER_NO.NEXTVAL, 'user02@kh.or.kr', 'pass02!',
'유저이', '01022222222', '10004, 서울시 종로구 통인동',
NULL, DEFAULT, DEFAULT);
INSERT INTO MEMBER
VALUES(SEQ_MEMBER_NO.NEXTVAL, 'user03@kh.or.kr', 'pass03!',
'유저삼', '01033333333', '25746, 서울시 성북구 정릉3동',
NULL, DEFAULT, DEFAULT);
INSERT INTO MEMBER
VALUES(SEQ_MEMBER_NO.NEXTVAL, 'user04@kh.or.kr', 'pass04!',
'유저사', '01044444444', '94564, 인천시 부평구 산곡동',
NULL, DEFAULT, DEFAULT);
COMMIT;
-- 인증 테이블 생성
-- 한 이메일로 발급 받은 인증번호가 계속 업데이트
CREATE TABLE CERTIFICATION (
EMAIL VARCHAR2(50) PRIMARY KEY,
C_NUMBER CHAR(6) NOT NULL,
ISSUE_DT DATE DEFAULT SYSDATE
);
Servers/context.xml 들어가서
추가하기.
<Resource
name="jdbc/oracle"
auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@localhost:1521:xe"
username="community"
password="1234"
maxTotal="50"
maxIdle="10"
maxWaitMillis="-1"
/>
<!--
name : JNDI 이름 Context의 lookup()을 사용하여 자원을 찾을때 사용한다. java:comp/env 디렉터리에서 찾을 수 있다.
auth : 자원 관리 주체 지정(Application 또는 Container)
type : Resource의 타입 지정
driverClassName : JDBC 드라이버 클래스 이름.
maxTotal : DataSource 에서 유지할 수 있는 최대 커넥션 수
maxIdle : 사용되지 않고 풀에 저장될 수 있는 최대 커넥션의 개수. 음수일 경우 제한이 없음
maxWaitMillis : 커넥션 반납을 기다리는 시간(-1은 반환될 때 까지 기다림)
-->
JDBCTemplate.class 작성 ( Connection pool )
public class JDBCTemplate {
// DB 연결
//( Connection 생성) , 자동커밋 off , 트랜잭션제어 , JDBC 객체 자동반환
// 반복사용되는 코드를 모아둔 클래스
//모든 필드, 메서드가 static , 클래스명.메서드명 호출할수있도록.
private static Connection conn = null;
/** DB 연결정보를 담고있는 Connection 생성 및 반환메서드
* @return conn
*/
public static Connection getConnection() {
try {
// JNDI ( Java Naming and Directory Interface API )
Context initContext = new InitialContext();
// servers -> context.xml 파일 찾기.
Context envContext = (Context)initContext.lookup("java:/comp/env");
// DBCP 세팅의 <Resource> 태그를 찾아서 DataSource 형식의 객체로 얻어오기
// DataSource : Connection Pool 을 구현하는객체 ( 만들어둔 Connection 얻어오기 가능)
DataSource ds = (DataSource)envContext.lookup("jdbc/oracle");
conn = ds.getConnection();
conn.setAutoCommit(false); // 자동커밋 비활성화
}catch(Exception e) {
System.out.println("[Connection 생성중 예외 발생]");
e.printStackTrace();
}
return conn;
}
/** Connection 객체 자원 반환메서드
* @param conn
*/
public static void close(Connection conn) {
try {
if(conn != null && !conn.isClosed()) conn.close();
}catch(Exception e) {
e.printStackTrace();
}
}
/** Statement 객체 자원 반환메서드 ( PreparedStatement(자식)
* 다형성/ 동적바인딩
* @param stmt
*/
public static void close(Statement stmt) {
try {
if(stmt != null && !stmt.isClosed()) stmt.close();
}catch(Exception e) {
e.printStackTrace();
}
}
/** ResultSet 객체 자원 반환메서드
* @param rs
*/
public static void close(ResultSet rs) {
try {
if(rs != null && !rs.isClosed()) rs.close();
}catch(Exception e) {
e.printStackTrace();
}
}
/** 트랜잭션 Commit 메서드
* @param conn
*/
public static void commit(Connection conn) {
try {
if(conn != null && !conn.isClosed()) conn.commit();
}catch(Exception e) {
e.printStackTrace();
}
}
/** 트랜잭션 Rollback 메서드
* @param conn
*/
public static void rollback(Connection conn) {
try {
if(conn != null && !conn.isClosed()) conn.rollback();
}catch(Exception e) {
e.printStackTrace();
}
}
}
EncodingFilter.class 작성
// ' / ' == /community == 최상위주소
// ' /* ' == 최상위 주소 하위 모든. == 모든요청
@WebFilter(filterName = "encodingFilter", urlPatterns = "/*")
public class EncodingFilter extends HttpFilter implements Filter{
// 서버 실행시 or 필터 코드 변경시
// 필터 객체가 자동 생성되는데
// 그때, 필터에 필요한 내용을 초기화하는 메서드
public void init(FilterConfig fConfig) throws ServletException{
System.out.println("문자 인코딩 필터 초기화");
}
// 서버 실행중 필터 코드가 변경되어
// 기존 필터를 없애야 할 때 수행되는 메서드
public void destroy() {
System.out.println("문자 인코딩 필터 파괴");
}
// 필터 역할을 수행하는 메서드
public void doFilter(ServletRequest request,ServletResponse response, FilterChain chain) throws IOException, ServletException {
// ServletRequest == HttpServletRequest 의 부모타입
// ServletResponse == HttpServletResponse 의 부모타입 . 필요시 다운캐스팅.
// 모든 요청의 문자 인코딩을 UTF-8 로 설정.
request.setCharacterEncoding("UTF-8");
// 모든 응답의 문자 인코딩을 UTF-8 로 설정.
response.setCharacterEncoding("UTF-8");
//-----------------------------------------
//application scope 로 최상위 경로 얻어올수 있는 값 세팅
// 1) application 내장객체 얻어오기
ServletContext application = request.getServletContext();
// 2) 최상위 주소 얻어오기
String contextPath = ( (HttpServletRequest)request).getContextPath();
// 3) 세팅
application.setAttribute("contextPath",contextPath);
// 연결된 다음 필터 수행 ( 없으면 Servlet 수행 )
chain.doFilter(request, response);
}
}
Member.class
public class Member {
private int memberNo;
private String memberEmail;
private String memberPw;
private String memberNickname;
private String memberTel;
private String memberAddress;
private String profileImage;
private String enrollDate;
private String secessionFlag;
public Member() { }
public Member(int memberNo, String memberEmail, String memberPw, String memberNickname, String memberTel,
String memberAddress, String profileImage, String enrollDate, String secessionFlag) {
this.memberNo = memberNo;
this.memberEmail = memberEmail;
this.memberPw = memberPw;
this.memberNickname = memberNickname;
this.memberTel = memberTel;
this.memberAddress = memberAddress;
this.profileImage = profileImage;
this.enrollDate = enrollDate;
this.secessionFlag = secessionFlag;
}
public int getMemberNo() {
return memberNo;
}
public void setMemberNo(int memberNo) {
this.memberNo = memberNo;
}
public String getMemberEmail() {
return memberEmail;
}
public void setMemberEmail(String memberEmail) {
this.memberEmail = memberEmail;
}
public String getMemberPw() {
return memberPw;
}
public void setMemberPw(String memberPw) {
this.memberPw = memberPw;
}
public String getMemberNickname() {
return memberNickname;
}
public void setMemberNickname(String memberNickname) {
this.memberNickname = memberNickname;
}
public String getMemberTel() {
return memberTel;
}
public void setMemberTel(String memberTel) {
this.memberTel = memberTel;
}
public String getMemberAddress() {
return memberAddress;
}
public void setMemberAddress(String memberAddress) {
this.memberAddress = memberAddress;
}
public String getProfileImage() {
return profileImage;
}
public void setProfileImage(String profileImage) {
this.profileImage = profileImage;
}
public String getEnrollDate() {
return enrollDate;
}
public void setEnrollDate(String enrollDate) {
this.enrollDate = enrollDate;
}
public String getSecessionFlag() {
return secessionFlag;
}
public void setSecessionFlag(String secessionFlag) {
this.secessionFlag = secessionFlag;
}
@Override
public String toString() {
return "Member [memberNo=" + memberNo + ", memberEmail=" + memberEmail + ", memberPw=" + memberPw
+ ", memberNickname=" + memberNickname + ", memberTel=" + memberTel + ", memberAddress=" + memberAddress
+ ", profileImage=" + profileImage + ", enrollDate=" + enrollDate + ", secessionFlag=" + secessionFlag
+ "]";
}
}
index.jsp 일부만 받아옴.
<section class="content-1">
<h3> 회원 정보 조회 ( AJAX )</h3>
<p> 이메일을 입력받아 일치하는 회원 정보를 출력</p>
이메일 : <input type="text" id="in1">
<button id="select1"> 조회 </button>
<div id="result1" style="height:150px;">
</div>
</section>
main.js 파일 .
console.log("main.js loaded.");
// 회원 정보 조회 비동기 통신 (AJAX);
document.getElementById("select1").addEventListener("click",function(){
const input = document.getElementById("in1");
const div = document.getElementById("result1");
// AJAX 코드 작성 (jQuery 방식)
$.ajax({
url: "member/selectOne",
data: {"memberEmail" : input.value},
type: "POST",
dataType: "JSON", // dataType : 응답데이터형식을 지정
//-> "JSON"으로 지정시 자동으로 JS객체로 변환
success: function(member){
console.log(member);
// 1) div에 작성된 내용 모두 삭제
div.innerHTML = "";
if(member != null){ // 회원 정보 존재 O
// 2) ul 요소 생성
const ul = document.createElement("ul");
// 3) li 요소 생성 * 5 + 내용 추가
const li1 = document.createElement("li");
li1.innerText = "이메일 : " + member.memberEmail;
const li2 = document.createElement("li");
li2.innerText = "닉네임 : " + member.memberNickname;
const li3 = document.createElement("li");
li3.innerText = "전화번호 : " + member.memberTel;
const li4 = document.createElement("li");
li4.innerText = "주소 : " + member.memberAddress;
const li5 = document.createElement("li");
li5.innerText = "가입일 : " + member.enrollDate;
// 4) ul에 li를 순서대로 추가
ul.append(li1, li2, li3, li4, li5);
// 5) div에 ul 추가
div.append(ul);
} else { // 회원 정보 존재 X
// 1) h4 요소 생성
const h4 = document.createElement("h4");
// 2) 내용 추가
h4.innerText = "일치하는 회원이 없습니다";
// 3) 색 추가
h4.style.color = "red";
// 4) div에 추가
div.append(h4);
}
},
error: function(request){
console.log("AJAX 에러 발생");
console.log("상태코드 : "+request.status); // 404, 500
}
})
});
SelectOneServlet.class
@WebServlet("/member/selectOne")
public class SelectOneServlet extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//파라미터 얻어오기
String memberEmail = req.getParameter("memberEmail");
try {
MemberService service = new MemberService();
Member member = service.selectOne(memberEmail);
// JAVA 객체를 Javascript 객체로 변환하여 응답(출력)
// JAVA 객체 -> javascript형태 JSON -> javascript 객체.
// GSON 라이브러리를 이용한 JAVA객체 -> JSON 변환
// new GSON().toJson
// --> 매개변수에 작성된 객체를 JSON형태로 변환한 후
// 스트림 통해서 출력
new Gson().toJson(member, resp.getWriter());
}catch(Exception e) {
e.printStackTrace();
}
}
}
MemberService.class
public class MemberService {
private MemberDAO dao = new MemberDAO();
public Member selectOne(String memberEmail) throws Exception {
Connection conn = getConnection();
Member member = dao.selectOne(conn , memberEmail);
close(conn);
return member;
}
}
member-sql.xml 파일
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>member-sql.xml</comment>
<entry key="selectOne">
SELECT MEMBER_EMAIL, MEMBER_NICK, MEMBER_TEL, MEMBER_ADDR,
TO_CHAR(ENROLL_DT, 'YYYY"년" MM"월" DD"일"') AS ENROLL_DATE
FROM MEMBER
WHERE MEMBER_EMAIL = ?
AND SECESSION_FL = 'N'
</entry>
</properties>
MemberDAO . class
public class MemberDAO {
private Statement stmt;
private PreparedStatement pstmt;
private ResultSet rs;
private Properties prop;
public MemberDAO() {
try {
prop = new Properties();
String filePath = MemberDAO.class.getResource("/edu/kh/community/sql/member-sql.xml").getPath();
prop.loadFromXML( new FileInputStream(filePath));
}catch(Exception e) {
e.printStackTrace();
}
}
public Member selectOne(Connection conn, String memberEmail) throws Exception {
Member member = null;
try {
String sql = prop.getProperty("selectOne");
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, memberEmail);
rs = pstmt.executeQuery();
if(rs.next()) {
member = new Member();
member.setMemberEmail(rs.getString(1));
member.setMemberNickname(rs.getString(2));
member.setMemberTel(rs.getString(3));
member.setMemberAddress(rs.getString(4));
member.setEnrollDate(rs.getString(5));
}
}finally {
close(rs);
close(pstmt);
}
return member;
}
}
index.jsp 파일
<%@ page language="java" contentType="text/html; cherset=UTF-8"
pageEncoding ="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>17_웹 문서 구조</title>
<link rel="stylesheet" href="resources/css/main-style.css">
<!-- fontawesome 사이트 아이콘 이용 -->
<script src="https://kit.fontawesome.com/f7459b8054.js" crossorigin="anonymous"></script>
</head>
<body>
<main>
<!-- jsp : include 태그
다른 jsp 파일의 내용을 해당 위치에 포함시킴
* 경로 작성시
내부 접근경로 ( 최상위 : /webapp )
-->
<jsp:include page="/WEB-INF/views/common/header.jsp"/> <!-- header.jsp 로 include -->
<section class="content">
<section class="content-1">
<h3> 회원 정보 조회 ( AJAX )</h3>
<p> 이메일을 입력받아 일치하는 회원 정보를 출력</p>
이메일 : <input type="text" id="in1">
<button id="select1"> 조회 </button>
<div id="result1" style="height:150px;">
</div>
</section>
<section class="content-2">
<form action="#" name="login-frm">
<!-- 아이디, 비밀번호, 로그인 버튼 -->
<fieldset id="id-pw-area">
<section>
<input type="text" name="inputId"
placeholder="아이디" autocomplete="off">
<!-- autocomplete="off" : 자동완성 사용 X -->
<input type="password" name="inputPw" placeholder="비밀번호">
</section>
<section>
<!-- type="submit"이 기본값 -->
<button>로그인</button>
</section>
</fieldset>
<!-- label 태그 내부에 input태그를 작성하면 자동 연결됨 -->
<label>
<input type="checkbox" name="saveId"> 아이디 저장
</label>
<!-- 회원가입 / ID/PW 찾기 -->
<article id="signUp-find-area">
<a href="#">회원가입</a>
<span>|</span>
<a href="#">ID/PW찾기</a>
</article>
</form>
</section>
</section>
</main>
<jsp:include page="/WEB-INF/views/common/footer.jsp"/> <!-- footer.jsp 로 include -->
<!-- main.js 연결 -->
<script src="${contextPath}/resources/js/main.js"></script>
<!-- jQuery 라이브러리 추가 -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
</body>
</html>
header.jsp
<%@ page language="java" contentType="text/html; cherset=UTF-8"
pageEncoding ="UTF-8" %>
<header>
<section>
<%--
<%= request.getContextPath() %>
${pageContext.servletContext.contextPath}
--%>
<!-- 클릭 시 메인페이지로 이동하는 로고 -->
<a href="${contextPath}">
<img src="${contextPath}/resources/images/logo1.jpg" id="home-logo">
</a>
</section>
<!-- 검색창 영역 -->
<section>
<article class="search-area">
<!-- 내부 input 태그의 값을 서버 또는 페이지로 전달(제출) -->
<form action="#">
<fieldset>
<input type="text" id="query" name="query"
placeholder="검색어를 입력해주세요.">
<!-- 검색 버튼 -->
<button type="submit" id="search-btn" class="fa-solid fa-magnifying-glass"></button>
</fieldset>
</form>
</article>
</section>
<section></section>
</header>
<nav>
<ul>
<li><a href="#">공지사항</a></li>
<li><a href="#">자유 게시판</a></li>
<li><a href="#">질문 게시판</a></li>
<li><a href="#">FAQ</a></li>
<li><a href="#">1:1문의</a></li>
</ul>
</nav>
footer.jsp
<%@ page language="java" contentType="text/html; cherset=UTF-8"
pageEncoding ="UTF-8" %>
<footer>
<p>
Copyright © KH Information Educational Institute A-Class
</p>
<article>
<a href="#">프로젝트 소개</a>
<span>|</span>
<a href="#">이용약관</a>
<span>|</span>
<a href="#">개인정보처리방침</a>
<span>|</span>
<a href="#">고객센터</a>
</article>
</footer>
'SelfStudy > JDBC' 카테고리의 다른 글
JDBC 활용 연습용3. ( 암호화 (로그인)) (0) | 2023.03.27 |
---|---|
JDBC 활용 연습용2. ( ajax 이용 화면에 정보 바로뿌리기 ) (0) | 2023.03.24 |
JDBC 연습2 ( SELECT (사용자입력) + JSP ) (0) | 2023.03.22 |
JDBC 연습 ( SELECT + JSP ) (0) | 2023.03.22 |
JDBC ( insert , update , select ) (0) | 2023.03.17 |
Comments