Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

어리바리 신입 개발자의 얼렁뚱땅 개발 기록 ✨

23.03.29 / [insert 쿼리 실행] jsp - mysql 연결하기(JDBC) , mysql 드라이버이해하기 본문

Database/MYSQL

23.03.29 / [insert 쿼리 실행] jsp - mysql 연결하기(JDBC) , mysql 드라이버이해하기

낫쏘링 2023. 3. 29. 16:01
728x90

INSERT쿼리 실행  - 사용자로부터 데이터를 입력 받아 DB로 INSERT

 

[ 사전 작업 ]

0. 사용자로부터 데이터 입력 받는 폼 테이블 만들기 (user_insert_form.jsp)

<form action="<%=request.getContextPath() %>/userinsert/user_insert_action.jsp" method="post">
<table border="1">
<tr>
	<td>아이디</td>
	<td><input type="text" name="m_id" size="20"></td>
</tr>
<tr>
	<td>암호</td>
	<td><input type="text" name="m_pw" size="20"></td>
</tr>
<tr>
	<td>권한</td>
	<td><input type="text" name="m_level" size="20"></td>
</tr>
<tr>
	<td>이름</td>
	<td><input type="text" name="m_name" size="20"></td>
</tr>
<tr>
	<td>이메일</td>
	<td><input type="text" name="m_email" size="20"></td>
</tr>
<tr>
	<td colspan="2"><input type="submit" value="회원가입"></td>
</tr>
</table>
</form>
1. 클래스/인터페이스 IMPORT (user_insert_action.jsp)

<%@ page import = "java.sql.DriverManager" %>
<%@ page import = "java.sql.Connection" %>
<%@ page import = "java.sql.PreparedStatement" %>
<%@ page import = "java.sql.SQLException" %>

인터페이스 - 구현을 명령 받은 클래스 
Connection - ConnectionImpl
PreparedStatement - ClinetPreparedStatement



2. post 방식 한글 처리 / 사용자로부터 입력 받은 데이터를 불러와서 변수에 담기 (user_insert_action.jsp)

request.setCharacterEncoding("euc-kr");
//데이터를 보내는 방식이 post일 경우
//request.getParameter("name이름");을 사용하면 언어 인코딩 해줘야 한다.


String u_id = request.getParameter("u_id");
String u_pw = request.getParameter("u_pw");
String u_level = request.getParameter("u_level");
String u_name = request.getParameter("u_name");
String u_email = request.getParameter("u_email");

 

[ JDBC(Java data base connectivity) 프로그램 순서 7단계 ]

1. mysql 드라이버 로딩

드라이버 로딩 코드를 통해 한 번 로딩 하면 그 다음 부터는 다시 로딩하지 않고 사용 가능하다.
(프로그램을 실행해서 최초로 한 번 로딩되면 다음 프로그램 실행에서 로딩 코드를 다시 실행하지 않고도 계속 데이터 베이스와 연결된다. 단, 서버가 끊기면 다시 최초 한 번 로딩한다. 프로그램이 종료돼도 드라이버 로딩 상태/데이터 베이스 연결 상태로 유지되어 있다.)
Class.forName("com.mysql.jdbc.Driver");

 

2. Connection객체로 DB연결  :  ip / port번호 / db접속id / db접속비번 / db명(sid,service name) 

Connection - DB 연결 
// 데이터타입 객체참조변수 = 초기화 ;
Connection conn = null;
PreparedStatement pstmt = null;	

// "jdbc:DB프로그램://localhost:port번호/DB네임"
String jdbcDriver = "jdbc:mysql://localhost:3306/dev47db?" +
        "useUnicode=true&characterEncoding=euckr";
String dbUser = "dev47id";
String dbPass = "dev47pw";

// DriverManager 인터페이스를 통해 구현을 명령 받은 getConnection 메소드 (객체)
// static으로 생성된 메소드 -> 객체 참조 변수 생성 없이 클래스명으로 주소 찾아갈 수 있다.
// DriverManager는 객체 참조 변수가 아닌 클래스
// getConnection은 static으로 생성된 메소드라는 뜻
conn = DriverManager.getConnection(jdbcDriver, dbUser, dbPass);

// getConnection 메소드 호출 후 conn 변수에 할당된 리턴 값(참조 주소)
// Connection 인터페이스로부터 구현을 명령 받은 ConnectionImpl 클래스의 주소
// com.mysql.cj.jdbc.ConnectionImpl@61f2e5fd	
// 질문) DriverManager 클래스의 주소를 찾아가서 메소드를 호출해서 conn에 할당했는데 왜 주소가 ConnectionImpl ?
// DriveManager 클래스에 선언된 메소드 getConnection를 보면...
/* public static Connection getConnection(String url, String user, String password){
        Connection re_conn = null;
        re_conn = new ConnectionImpl();
        return re_conn; */
// Connection 인터페이스를 데이터 타입으로 메소드를 선언했다.
// Connection 인터페이스를 데이터 타입으로 변수를 선언하고 ConnectionImpl 클래스의 주소 할당
//그리고 그 주소를 리턴했기 때문이다.
System.out.println(conn + "<-- conn");

// 현재 참조하고 있는 클래스 (주소 x)
// class com.mysql.cj.jdbc.ConnectionImpl
System.out.println(conn.getClass() + "<-- conn.getClass()");

 

3. Query실행을 위한 준비 ( statement 또는 PreparedStatement객체생성)

PreparedStatement - mysql 쿼리에 입력될 SQL 문 할당
(아직은 사용자가 입력한 값을 mysql에 자동으로 전달할 수 없는 상태)
// db에서 데이터를 추가(Insert), 삭제(Delete), 수정(Update)하는 SQL 문을 실행할 수 없는 상태
pstmt = conn.prepareStatement("INSERT INTO tb_member VALUES(?,?,?,?,?)");
// 질문) conn 객체참조변수의 주소(ConnectionImpl)를 찾아가서 메소드를 호출해서 할당했는데 왜 주소가 ClientPreparedStatement ?
// ConnectionImpl 클래스에 선언된 메소드 prepareStatement를 보면...
/* public PreparedStatement prepareStatement(String sql) {
    System.out.println("3-1단계 : 쿼리실행준비 ConnectionImpl.java");
    PreparedStatement ps = new ClientPreparedStatement();
    return ps; */
// PreparedStatement 인터페이스를 데이터 타입으로 메소드를 선언했다.
// PreparedStatement 인터페이스를 데이터 타입으로 변수를 선언하고 ClientPreparedStatement 클래스의 주소 할당
// 그리고 그 주소를 리턴했기 때문이다.
System.out.println(pstmt + "<-- pstmt1");

// insert SQL 문에 변수와 인덱스를 통해 값을 넣어주기 
// 사용자에게 입력 받은 정보는 계속 바뀌기 때문에 변수를 통해 넣어주는 것
// pstmt.setString(?에 들어갈 순서/index, 값을 담은 변수)
pstmt.setString(1, u_id);
pstmt.setString(2, u_pw);
pstmt.setString(3, u_level);
pstmt.setString(4, u_name);
pstmt.setString(5, u_email);
System.out.println(pstmt + "<-- pstmt2");

// 사용자가 입력한 값을 mysql에 자동으로 전달하기 위해 INSERT SQL문을 선언하고 인덱스와 변수를 셋팅해줬지만
// 아직은 사용자가 입력한 값을 mysql에 자동으로 전달할 수 없는 상태

 

4. Query실행

executeUpdate - mysql 쿼리에 입력될 SQL 문 실행
(사용자가 입력한 값을 mysql에 자동으로 전달할 수 있는 상태)

// executeUpdate() - db에서 데이터를 추가(Insert), 삭제(Delete), 수정(Update)하는 SQL 문을 실행
// executeQuery() - db에서 데이터를 선택(select)하는 SQL 문을 실행할 때
int result = pstmt.executeUpdate();
// executeUpdate()의 리턴 값은 SQL 문 실행으로 인해 영향을 받는 행 수를 반환 - 그래서 리턴 값을 int로 받는 것 
// (다섯 행을 수정update했을 경우 리턴 값 : 5)
System.out.println(result + "<-- result");

5. Query실행결과 사용 (insert,update,delete의 경우 생략 가능단계)

- insert 쿼리 실행이기 때문에 생략

 

6. statement 또는 PreparedStatement객체 종료(close())

pstmt.close();

 

7. DB연결(Connection 객체) 종료(close())

conn.close();

 

[ getParameter vs getString vs getAttribute ]

getParameter("name이름")
 - 화면에서 사용자에게 입력 받은 데이터 중 해당 name/변수에 해당하는 값 '문자열'로 가져오기
 - Parameter란 매개변수라는 뜻이기 때문에 getParameter는 매개변수에 담긴 값을 가져오겠다는 뜻이다.
 - 그 중에서도 화면(web browser)을 통해 사용자에게 입력 받은 데이터를 불러오겠다는 뜻이기 때문에
   사용자가 입력한 데이터가 담긴 매개변수를 괄호() 안에 넣어줘야 한다.
 - insert 실행 쿼리를 위한 코드에서는 user_insert_form.jsp 파일에서 폼테이블을 이용해 사용자가 입력한 데이터를         name(u_id, u_pw 등...)에 담아 전달 받았기 때문에 name이름을 입력해 주는 것
 - 사용자에게 입력 받은 데이터를 처리하는 메소드이기 때문에 당연히 setParameter는 없음

질문) 다른 jsp 파일에서 name이름을 받아오는데 왜 import랑 객체 생성-주소 사용 안 함?
- 다른 jsp 파일에서 form 태그의 속성인 action과 input 태그의 속성인 submit을 통해 전달 받았음
getString("컬럼명")
 - 해당 컬럼에서 '문자열'로 가져오기
 - 때문에 변수가 들어가야하는 곳에 getString을 이용하면 '문자열'이 되기 때문에 에러가 발생한다.
   pstmt = conn.prepareStatement(selectQuery+" WHERE " + ? +"=?"); 에서 첫 번째 ?에는 변수가 들어가야 하고       두 번째 ?에는 문자열이 들어가야 한다. 때문에 첫 번째 ?에는 문자열로 값을 반환하는 setString을 통해 대입해줄 수 없다.
   반면, 두 번째 ?는 문자열이기 때문에 문자열로 값을 반환하는 setString을 통해 대입이 가능하다.
   실제로 콘솔창에 출력된 결과를 보면 
SELECT * FROM tb_member WHERE 'u_id'='value1-1' 가 뜬다.
   원래 입력은 
SELECT * FROM tb_member WHERE u_id='value1-1'  같이 컬럼을 찾는 부분은 작은 따옴표가 없어야 한다.
 - 변수는 따옴표 없이 그냥 쓰고 문자열은 '작은따옴표'로 감싸지기 때문

setString(인덱스, 컬럼명)
- 해당 인덱스에 해당 컬럼을 '문자열'로 셋팅


질문) 메소드의 매개변수 자리에 "큰따옴표"를 쓸 때 안 쓸 때가 있다. 왜?
 - pstmt.setString(1,send_id); 에서 send_id는 큰 따옴표가 없는데
 - rs.getString("u_id"); 에는 큰 따옴표가 있다.
 - 매개변수의 인수로 변수가 들어가면 따옴표를 사용하지 않고 문자열로 들어가면 큰 따옴표를 사용한다.
 - send_id는 getParameter를 통해 send_id 문자열에 해당하는 값을 찾아 담아준 변수이기 때문에 큰 따옴표를 사용하지 않았다. (String send_id = request.getParameter("send_id");
 - "u_id"는 말 그대로 rs에 할당된 주소에 찾아가 u_id라는 문자열에 해당하는 값을 찾는 것이기 때문에 변수가 아닌 문자열로 사용되어 큰 따옴표를 붙인 것이다. 
(예를 들면 rs에 할당된 주소에는 u_id = "id001" / u_pw = "pw001" / u_name = "홍길동" 이라는 값들이 저장되어 있다고 하면 re.getString("u_id")는 rs에 할당된 주소에 찾아가 u_id라는 문자열과 같은 변수를 찾아 값을 출력하라는 것이다.)

getAttribute("문자열")
 - 이전에 다른 JSP 또는 Servlet 페이지에 설정된 매개 변수를 가져 오는 데 사용된다. (setAttribute로 설정)
 - 리턴 타입이 object (리턴 타입이 string인 getParameter와 getString과의 차이점)
 - 리턴 타입이 object이기 때문에 문자열로 사용하려면
   String 변수 = (String)session.getAttribute("name"); 와 같이 문자열로 형변환을 통해서 사용해야 한다.
 - setAttribute로 설정한 키와 값이 없으면 아무 것도 없는 상태이므로 null을 반환한다.
   request.getParameter("name3");에서는 사용자가 입력한 name들 중 name3에 해당하는 홍길동3을 불러온다면,
   session.getAtrribute("name3");에서는 session.setAttribute("name3","홍길동");이라고 먼저 호출해줘야
   홍길동3을 불러올 수 있고 그렇지 않으면 null을 반환한다.

setAttribute("키/name/key","값/value")
 - 스코프 영역에 name과 value 를 설정해준다.
 - 한 메소드에 선언된 name과 value는 서로 묶여있다.

 

 

728x90