
리스트 과제 함께 진행
=> 포인트!
1) 쿠키명을 같게 하면 넣을 때 마다 덮어쓰기 됨
2) 따라서 계속 추가해줄려면 쿠키 갖고와서 거기에 추가해서 다시 넣어주는 식으로 사용해야함.
3) 쿠키에는 String 밖에 넣을 수 없고 특수문자 중 제한된 것들이 있음
선생님의 틈새 강의

성낙현의 JSP 자바 웹 프로그래밍

CREATE TABLE tbl_bbs(
idx INT NOT NULL AUTO_INCREMENT COMMENT '인덱스',
ref_idx INT NULL DEFAULT '0' COMMENT '참조글인덱스',
level_idx INT NULL DEFAULT '0' COMMENT '글 레벨',
sort_order INT NULL DEFAULT '1' COMMENT '댓글 정렬 순서',
user_id VARCHAR(20) NOT NULL COMMENT '아이디' COLLATE 'utf8mb4_general_ci',
title VARCHAR(200) NOT NULL COMMENT '제목' COLLATE 'utf8mb4_general_ci',
content TEXT NOT NULL COMMENT '글내용' COLLATE 'utf8mb4_general_ci',
display_date CHAR(10) NULL DEFAULT NULL COMMENT '노출등록일' COLLATE 'utf8mb4_general_ci',
reg_date DATETIME NULL DEFAULT NOW() COMMENT '등록일',
modify_date DATETIME NULL COMMENT '수정일',
read_cnt INT NULL DEFAULT '0' COMMENT '조회수',
file_path VARCHAR(200) NULL DEFAULT NULL COMMENT '파일 저장 경로' COLLATE 'utf8mb4_general_ci',
file_name VARCHAR(100) NULL DEFAULT NULL COMMENT '파일명' COLLATE 'utf8mb4_general_ci',
file_ext VARCHAR(10) NULL DEFAULT NULL COMMENT '파일확장자' COLLATE 'utf8mb4_general_ci',
file_size INT NULL DEFAULT '0' COMMENT '파일 사이즈',
PRIMARY KEY (idx) USING BTREE,
INDEX FK_bbs_tbl_member (user_id) USING BTREE,
CONSTRAINT FK_bbs_tbl_member FOREIGN KEY (user_id) REFERENCES tbl_member (memberId) ON UPDATE CASCADE ON DELETE CASCADE
)
COMMENT = '게시판 테이블'
COLLATE = 'utf8mb4_general_ci'
ENGINE = InnoDB
;
package common;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import jakarta.servlet.ServletContext;
public class JDBConnect {
public Connection conn; // DB 연결용
public Statement stmt; // 쿼리 날리는 용
public PreparedStatement psmt; // 쿼리 날리는 용2
public ResultSet rs; // 쿼리 결과셋 받는 용
// 기본생성자로 연결 : 값이 박혀있기 때문에 값이 달라질경우 다 수정 필요
public JDBConnect() {
try {
Class.forName("org.mariadb.jdbc.Driver");
String url = "jdbc:mariadb://localhost:3306/maria";
String dbId = "root";
String dbPwd = "1234";
conn = DriverManager.getConnection(url, dbId,dbPwd); // DriverManager는 db뿐만 아니라 모든 파일에 대해 연결 가능
System.out.println("DB 연결 성공 : 기본 생성자");
} catch(Exception e) {
e.printStackTrace();
}
}
// 사용자 생성자 이용 1 : 메서드를 호출할 때 값을 다 이용해서 연결하는 방식
public JDBConnect(String driver, String url, String dbId, String dbPwd) {
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, dbId,dbPwd);
System.out.println("DB 연결 성공 : 사용자 정의 생성자1");
} catch (Exception e) {
e.printStackTrace();
}
}
// 사용자 생성자 이용 2 : 서블릿 컨텍스트 이용 방법 (web.xml 정보 이용) 필드에서 가장 많이 씀
// 다만, 여러 DB를 사용하는 경우 DBtype 등의 인자를 하나 더 받아서 구분해서 동적으로 사용할 수 있도록 하기도 함.
public JDBConnect(ServletContext application) {
try {
String driver = application.getInitParameter("Driver");
Class.forName(driver);
String url = application.getInitParameter("URL");
String dbId = application.getInitParameter("dbId");
String dbPwd = application.getInitParameter("dbPwd");
conn = DriverManager.getConnection(url, dbId, dbPwd);
System.out.println("DB 연결 성공 : 사용자 정의 생성자2");
} catch(Exception e) {
e.printStackTrace();
}
}
// 연결 다한 후 종료하는 메서드
public void close() {
try {
if (rs != null) rs.close();
if (stmt != null) stmt.clearBatch();
if (psmt != null) psmt.close();
if (conn != null) conn.close();
System.out.println("JDBC 연결 자원 해지 성공");
} catch(Exception e) {
e.printStackTrace();
}
}
}
<%@ page import="common.JDBConnect" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JDBC Connection 테스트</title>
</head>
<body>
<h2>기본 생성자 연결 테스트</h2>
<%
JDBConnect jdbc = new JDBConnect();
out.print("jdbc : " + jdbc + "<br>");
jdbc.close();
%>
<h2>사용자 정의 생성자 1 연결 테스트</h2>
<%
String driver1 = application.getInitParameter("Driver");
String url1 = application.getInitParameter("URL");
String dbId1 = application.getInitParameter("dbId");
String dbPwd1 = application.getInitParameter("dbPwd");
JDBConnect jdbc1 = new JDBConnect(driver1, url1, dbId1, dbPwd1);
out.print("jdbc1 : " + jdbc1 + "<br>");
jdbc1.close();
%>
<h2>사용자 정의 생성자 2 연결 테스트</h2>
<%
JDBConnect jdbc2 = new JDBConnect(application);
out.print("jdbc2 : " + jdbc2 + "<br>");
jdbc2.close();
%>
</body>
</html>
- 커넥션 풀
1) 배경 : 과거 Java 프로젝트는 이런식으로 커넥션을 맺어서 사용했으나, 속도가 다소 떨어져서 `커넥션 풀`이라는 개념이 사용 됨.
2) 장점 : 커넥션 객체를 미리 생성해 풀에 넣어 놓고 요청이 있을 때 이미 생성된 커낵션 객체를 사용하는 방법으로 이미 메모리에 올라와있으니, 속도도 빠름
- JNDI(Java Naming and Directory Interface)
1) 디렉터리 서비스에서 제공하는 데이터 및 객체를 발견(discover)하고 참고(lookup) 하기 위한 자바 API다.
2) 간단히 요약하자면 우리가 연결하고 싶은 데이터베이스의 DB Pool을 미리 Naming 시켜주는 방법 중 하나이다


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 ConnectPool {
public Connection conn;
public Statement stmt;
public PreparedStatement psmt;
public ResultSet rs;
// 기본생성자로 생성
public ConnectPool() {
try {
Context initCtx = new InitialContext();
Context ctx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource) ctx.lookup("jdbc_maria");
conn = ds.getConnection();
System.out.println("DB 커넥션 풀 연결 성공");
} catch (Exception e) {
System.out.println("DB 커넥션 풀 연결 실패");
e.printStackTrace();
}
}
// close()메서드
public void close() {
try {
if (rs != null) rs.close();
if (stmt != null) stmt.clearBatch();
if (psmt != null) psmt.close();
if (conn != null) conn.close();
System.out.println("DB 커넥션 풀 자원 해지 성공");
} catch (Exception e) {
e.printStackTrace();
}
}
}
<h2>DB Connection pool 연결 테스트</h2>
<%
ConnectPool pool = new ConnectPool();
pool.close();
%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="common.JDBConnect"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String memberId = "test10";
String name = "테스트회원10";
String pwd = "1234";
StringBuilder sb = new StringBuilder();
sb.append("INSERT INTO tbl_member(memberId, name, pwd, regdate)");
sb.append("VALUES (?, ?, ?, NOW())");
JDBConnect jdbc = new JDBConnect();
PreparedStatement psmt = jdbc.conn.prepareStatement(sb.toString());
psmt.setString(1, memberId);
psmt.setString(2, name);
psmt.setString(3, pwd);
// executeQuery = 셀렉트 / executeUpdate = 수정, 삭제, 삽입 excuteUpdate는 리턴타입이 있고 int 형임
int result = psmt.executeUpdate();
out.print(String.format("%d 개의 행이 입력되었습니다.", result));
// 다썻으니 닫자
jdbc.close();
%>
</body>
</html>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="common.JDBConnect"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%!
/*
Statement = 정적 쿼리를 날리는 용으로 냅다 텍스트 박아서 날리는 용 (사용할 때 마다 컴파일 함 / 요즘 잘 사용 안 함.)
PreparedStatement = ?를 이용해서 파라미터 세팅해서 날리는 동적 쿼리 용! (컴파일 정보를 갖고있어서 실행속도가 더 빠름)
*/
int total = 0;
StringBuilder sb = new StringBuilder();
JDBConnect jdbc = new JDBConnect();
int test(int startNum, int maxNum) {
sb.append("INSERT INTO tbl_member(memberId, name, pwd, regdate)");
sb.append("VALUES (?, ?, ?, NOW())");
total = 0;
String pwd = "1234";
try {
for(int i = startNum; i <= maxNum; i++){
String id = "test" + i;
String name = "테스트회원" + i;
PreparedStatement psmt = jdbc.conn.prepareStatement(sb.toString());
psmt.setString(1, id);
psmt.setString(2, name);
psmt.setString(3, pwd);
int result = psmt.executeUpdate();
total = total + result;
}
} catch (Exception e) {
e.printStackTrace();
}
return total;
}
%>
<%
out.print(test(11, 15) + "행을 추가하였습니다.");
%>
</body>
</html>