벡엔드 웹프로그래밍/JSP

JSP 웹프로그래밍 68일차 (25/2/21)

wkun 2025. 2. 21. 17:58

JSP 웹프로그래밍 67일차 (25/2/2

contents

 

PART 04 JSP 고급 문법

chapter 16 JDBC로 데이터베이스와 JSP 연동: 도서 조회, 등록, 수정, 삭제하기

01..JDBC의 개요 

02.JDBC 드라이버 로딩 및 DBMS 접속

03.데이터베이스 쿼리 실행

 

 

-----------------------------------------------------------

 

 

PART 04 JSP 고급 문법

 

chapter 16 JDBC로 데이터베이스와 JSP 연동: 도서 조회, 등록, 수정, 삭제하기

 

01..JDBC의 개요 

-JDBC(Java DataBase Connectivity)는 자바/JSP 프로그램 내에서 데이터베이스와 관련된 작업을 처리할 수 있도록 도와주는 자바 표준 인터페이스로, 관계형 데이터베이스 시스템에 접근하여 SQL 문을 실행하기 위한 자바 API 또는 자바 라이브러리임. JDBC  API를 사용하면 DBMS의 종류에 상관없이 데이터베이스 작업을 처리할 수 있음

-JDBC API는 java.sql.* 패키지에 의해 구현되며, 이 패키지는 여러 종류의 데이터베이스에 접근할 수 있음. java.sql.* 패키지는 단일 API를 제공하는 클래스와 인터페이스의 집합임. JDBC API를 사용하려면 JSP 페이지에 page 디렉티브 태그의 import 속성을 사용하여 java.sql.*을 설정해야 함

-JDBC를 사용한 JSP와 데이터베이스의 연동은 다음과 같은 단계로 프로그래밍됨

-연결하기: 1)라이브러리(드라이버) 확보 -> WEB-INF>lib> .... jar 2)java.sql.* 패키지 임포트 3)JDBC 드라이버 로딩

-대화하기: 4)데이터베이스 접속을 위한 Connection 객체 생성 5)쿼리문을 실행하기 위한 Statement,/PreparedStatement/CallableStatement 객체 생성 6)쿼리 실행 7)쿼리 실행의 결과 값(int, ResultSet) 사용 8)사용된 객체(ResultSet, Statement/PreparedStatement/CallableStatement, Connection) 종료

 

02.JDBC 드라이버 로딩 및 DBMS 접속

-데이터베이스에 접근하는 첫 단계는 JDBC 드라이버를 로딩하는 것이고, JDBC 드라이버를 로딩하고 나면 데이터베이스를 연결함. JDBC 드라이버가 로딩되면 자동으로 객체가 생성되고 DriverManager 클래스에 등록되며 형식은 다음과 같음. JDBC 드라이버 로딩은 프로그램 수행 시 한 번만 필요함

Class.forName(String ClassName);

 

-여기서 매개변수 className은 JDBC 드라이버의 이름임

 

[MySQL 드라이버를 로딩하는 예]

<% 
        try {
              Class.forName("com.mysql.jdbc.Driver");  =>드라이버 명시: 안 바뀜
       } catch (SQLException ex) {      ex)oracle, php 변경가능
            //예외 발생 처리
       }
%>

 

◎JDBC 드라이버 로딩을 하는 또 다른 방법(뭐가 더 적합하냐?의 문제: 실행순서 차이)

-웹 애플리케이션에서 많은 노력을 기울이지 않고 MySQL에서 다른 DBMS로 전환하려면 다음과 같이 WEBINF/web.xml 파일의 <init-param> 요소에 드라이버 이름을 설정함. 이렇게 하면 서블릿을 초기화할 때 로딩됨. web.xml 파일의 <init-param> 요소에 드라이버 이름을 설정함. 이렇게 하면 서블릿을 초기화할 때 로딩됨

<init-param>
           <param-name>jdbcDriver</param-name>
           <param-value>com.mysql.jdbc.Driver</param-value>
</init-param>                        oracle, php 3개 설정 -> 바꿔 사용

 

 

2)Connection 객체 생성하기

-JDBC 드라이버에서 데이터베이스와 연결된 커넥션을 가져오기 위해 DriverManager 클래스의 getConection() 메소드를 사용하며 형식은 다음과 같음. DriverManager 클래스로 객체를 생성할 때 JDBC 드라이버를 검색하고, 검색된 드라이버를 이용하여 Connection 객체를 생성한 후 이를 반환함

static Connection getConnection(String url)
static Connection getConnection(String url, String user, String passwd )
static Connection getConnection(String url, Properties info)

 

-여기서 매개변수 url은 데이터베이스 경로임. url의 표현 형식은 'jdbc:dbms 이름:주소:포트 번호[데이터베이스 식별자]'임. 매개변수 user는 데이터베이스 사용자 이름이고 password는 데이터베이스 비밀번호임. 그리고 매개변수 info는 사용자 및 비밀번호 등의 추가 정보를 포함한 Properties 객체이고, 이 객체를 사용하려면 패키지 java.util.Properties를 임포트해야 함

-다음은 데이터베이스 경로만을 이용하여 Connection 객체를 생성하는 예임

 

[Connection 객체 생성 예: getConnection(String url) 메소드 사용]

<%
       Connection conn=null;
       try{
           Class.forName("com.mysql.jdbc.Driver");          누구?     id   &  password
           conn=DriverManager.getConnection(                 (1)        (2)             (3)
           "jdbc:mysql://localhost:3306/JSPBookDB?user=root&password=1234");
      }catch(SQLException ex){
            //예외 발생 처리
     }
%>

 

-다음은 데이터베이스 URL, 사용자 이름, 비밀번호를 이용하여 Connection 객체를 생성하는 예임

 

[Connection 객체 생성 예: getConnection(String url, String user, String passwd) 메소드 사용]

<%
       Connection conn=null;
       try{
           Class.forName("com.mysql.jdbc.Driver");         
           conn=DriverManager.getConnection(               
           "jdbc:mysql://localhost:3306/JSPBookDB","root", "1234");
      }catch(SQLException ex){
            //예외 발생 처리
     }
%>

 

-다음은 데이터베이스 URL과 Properties 객체를 이용하여 Connection 객체를 생성하는 예임

 

[Connection 객체 생성 예: getConnection(String url, Properties info) 메소드 사용]

<%
       Connection conn=null;
       try{
           Class.forName("com.mysql.jdbc.Driver");
           Properties props=new Properties();                 => 객체 만듬(=Message properties: key=value ex)user=root)
           props.put("user", "root");
           props.put("password", "1234");         
           conn=DriverManager.getConnection(               
                   "jdbc:mysql://localhost:3306/JSPBookDB","props");
      }catch(SQLException ex){
            //예외 발생 처리
     }
%>

 

3)데이터베이스 연결 닫기

-데이터베이스 연결이 더 이상 필요하지 않으면 데이터베이스와 JDBC 리소스가 자동으로 닫힐 때까지 대기하는 것이 아니라 close() 메소드로 생성한 Connection 객체를 해제함. 일반적으로 데이터베이스 리소스를 사용하지 않기 위해 사용을 끝내자마자 리소스를 해제하는 것이 좋음

void close() throws SQLException

 

[Close() 메소드 사용 예: 데이터베이스의 연결 종료하기]

<%
       Connection conn=null;
       try{
             //JDBC 드라이버 로딩
             //Connection 객체 생성
      }catch(SQLException ex){
            //예외 발생 처리
     }finally{
         if(conn!=null) conn.close();
     }
%>

 

예제 16-1.JDBC  API로 데이터베이스 접속하기

JSPBook/src/main/wepapp/ch16/member.sql

-- BookMartket 데이터베이스 생성
create database bookmarketdb;

-- 임포트
use bookmarketdb;

-- 테이블 생성
create table book(
b_id varchar(10) not null,
    b_name varchar(20),
    b_unitprice integer,
    b_author varchar(20),
    b_description text,
    b_publisher varchar(20),
    b_category varchar(20),
    b_unitsinstock long,
    b_releasedate varchar(20),
    b_condition varchar(20),
    b_filename varchar(20),
    primary key (b_id)
) default charset=utf8;

-- 테이블 확인
desc book;

-- 데이터 삽입
INSERT INTO book VALUES('ISBN1234', 'C# 프로그래밍', 27000, '우재남','C#을 처음 접하는 독자를 대상으로 일대일 수업처럼 자세히 설명한 책이다. 꼭 알아야 할 핵심 개념은 기본 예제로 최대한 쉽게 설명했으며, 중요한 내용은 응용 예제, 퀴즈, 셀프 스터디, 예제 모음으로 한번 더 복습할 수 있다.', '한빛아카데미', 'IT모바일', 1000,  '2022/10/06', 'new', 'ISBN1234.jpg');
INSERT INTO book VALUES('ISBN1235', '자바마스터', 30000, '송미영', '자바를 처음 배우는 학생을 위해 자바의 기본 개념과 실습 예제를 그림을 이용하여 쉽게 설명합니다. 자바의 이론적 개념→기본 예제→프로젝트 순으로 단계별 학습이 가능하며, 각 챕터의 프로젝트를 실습하면서 온라인 서점을 완성할 수 있도록 구성하였습니다.', '한빛아카데미', 'IT모바일',1000, '2023/01/01', 'new', 'ISBN1235.jpg');
INSERT INTO book VALUES('ISBN1236', '파이썬 프로그래밍', 30000, '최성철', '파이썬으로 프로그래밍을 시작하는 입문자가 쉽게 이해할 수 있도록 기본 개념을 상세하게 설명하며, 다양한 예제를 제시합니다. 또한 프로그래밍의 기초 원리를 이해하면서 파이썬으로 데이터를 처리하는 기법도 배웁니다.', '한빛아카데미', 'IT모바일', 1000, '2023/01/01', 'new', 'ISBN1236.jpg');

select * from book;

 

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>


<style>
body{
padding-left: 30%;
}
</style>
</head>
<body>
<h3>챕터16</h3>
<p><a href="ch16_1">실습 16-1</a></p>
<p><a href="ch16_2">실습 16-2</a></p>
<p><a href="ch16_3">실습 16-3</a></p>
</body>
</html>

 

JSPBook/src/main/java/controller/ch16/ch16_1_controller.java

package controller.ch16;


import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;


import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;


@WebServlet("/ch16_1")
public class ch16_1_controller extends HttpServlet{


@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("index.html에서 컨트롤로 이동");

Connection conn=null;

String url="jdbc:mysql://localhost:3306/bookmarketdb";
String user="root";
String password="1234";
Statement stmt=null;

try {
Class.forName("com.mysql.jdbc.Driver");
conn=DriverManager.getConnection(url, user, password);
System.out.println("데이터 베이스 연결이 되었습니다");

String sql ="INSERT INTO book VALUES('ISBN1237', 'C# 프로그래밍2', 28000, '우재남','C#을 처음 접하는 독자를 대상으로 일대일 수업처럼 자세히 설명한 책이다. 꼭 알아야 할 핵심 개념은 기본 예제로 최대한 쉽게 설명했으며, 중요한 내용은 응용 예제, 퀴즈, 셀프 스터디, 예제 모음으로 한번 더 복습할 수 있다.', '한빛아카데미', 'IT모바일', 1000, '2022/10/06', 'new', 'ISBN1234.jpg')";
stmt = conn.createStatement();
stmt.executeUpdate(sql);


} catch (Exception e) {
System.out.println("데이터 베이스 연결이 실패하였습니다");
e.printStackTrace();
}
finally {
if(stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {e.printStackTrace();}
}
}


}


@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {


}


}

 

실행 결과

 

 

03.데이터베이스 쿼리 실행: SQL을 전달

-Connection 객체를 생성하여 데이터베이스가 연결되었다면 쿼리 실행 객체를 이용하여 쿼리를 실행함. 쿼리 실행 객체는 Statement, PreparedStatement, CallableStatement임. 쿼리의 실행 성공이나 실패 여부와 상관없이 쿼리 실행 객체와 Connection 객체의 리소스를 해제해야 함

 

1)Statement 객체로 데이터 접근하기

-Statement 객체는 정적인 쿼리에 사용하며 형식은 다음과 같음. 이 객체는 하나의 쿼리를 사용하고 나면 더는 사용할 수 없음. 하나의 쿼리를 끝내면 close()를 사용하여 객체를 즉시 해제해야 함. close()를 사용하여 객체를 즉시 해제하지 않으면 무시할 수 없는 공간이 필요하며 페이지가 다른 작업을 수행하는 동안 멈추지 않기 때문임. Statement 객체는 복잡하지 않은 간단한 쿼리문을 사용하는 경우에 좋음

Statement CreateStatement() throws SQLException

 

-일단 Statement  객체를 생성하면 Statement  객체의 executeQuery()나 executeUpdate() 메소드를 호출하여 쿼리문을 실행함. 이러한 메소드는 쿼리문 대부분의 요구 사항을 처리할 수 있음

 

Statement 객체의 메소드 종류

메소드 반환 유형 설명
executeQuery(String sql) ResultSet SELECT 문을 실행할 때 사용함(ResultSet 객체 반환)
executeUpdate(String sql) int 삽입, 수정, 삭제와 관련된 SQL 문 실행에 사용함
close() void Statement  객체를 반환할 때 사용함

 

*DML(Data Manipulation Language, 데이터 조작어)

-생성 insert into :void setter
-수정 update to
-삭제 delete
executeUpdate(String sql)
-조회 select: 리턴 get executeQuery(String sql)

cf) 회원(DTO: Data Transfer Object): Member 객체 -> 4바퀴 돔(생성, 수정, 삭제, 조회)

 -로직을 가지지 않고 getter/setter 메소드만 가진 순수한 데이터 객체 클래스

 

executeQuery 메소드로 데이터 조회하기

-executeQuery 메소드는 정적인 SELECT 쿼리문을 통해 데이터를 검색하는 데 사용하며 형식은 다음과 같음

ResultSet executeQuery(String sql) throws SQLException

 

-여기서 매개변수 sql은 데이터베이스에 보낼 쿼리문임

 

[executeQuery() 메소드 사용 예: SELECT 쿼리문]

<%
        Connection conn = null;

         ··· (생략) ···
         Statement stmt = conn.createStatement();

         String sql = "SELECT * FROM Member WHERE id='1' ";
         ResultSet rs=stmt.executeQuery(sql);
         stmt.close();
%>

 

executeUpdate() 메소드로 데이터 삽입, 수정, 삭제하기

executeUpdate() 메소드는 INSERT, UPDATE, DELETE 쿼리문을 통해 데이터를 삽입, 수정, 삭제하는 데 사용하며 형식은 다음과 같음

int executeUpdate(String sql) throws SQLException

 

-여기서 매개변수 sql은 데이터베이스에 보낼 쿼리문임

 

[executeUpdate() 메소드 사용 예(삽입): INSERT 쿼리문]

<%
        Connection conn = null;

         ··· (생략) ···
         Statement stmt = conn.createStatement();

         String sql = "INSERT  INTO Member(id, name, passwd) VALUES('1', '홍길순', '1234' )";
         int rs=stmt.executeUpdate(sql);
     
%>

 

[executeUpdate() 메소드 사용 예(수정): UPDATE 쿼리문]

<%
        Connection conn = null;

         ··· (생략) ···
         Statement stmt = conn.createStatement();

         String sql = "UPDATE Member SET name= '관리자' WHERE id='1' )";
         int rs=stmt.executeUpdate(sql);
    
%>

 

[executeUpdate() 메소드 사용 예(삭제): DELETE 쿼리문]

<%
        Connection conn = null;

         ··· (생략) ···
         Statement stmt = conn.createStatement();

         String sql = "DELETE  FROM Member WHERE id='1' ";
         int rs=stmt.executeUpdate(sql);
        
%>

 

예제 16-2.Statement 객체로 INSERT 쿼리문 실행하기

JSPBook/src/main/wepapp/ch16/member.sql

use bookmarketdb;

create table member(
id varchar(20) not null,
    passwd varchar(20),
    name varchar(30),
    primary key(id)
    
);

select * from member;

 

JSPBook/src/main/wepapp/ch16/insert01.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Database SQL</title>
</head>
<body>
<form method="post" action="ch16_2">
<p> 아이디 : <input type="text" name="id">
<p> 비밀번호 : <input type="password" name="passwd">
<p> 이름 : <input type="text" name="name">
<p> <input type="submit" value="전송">
</form>
</body>
</html>

 

JSPBook/src/main/java/ch16/ch16_2_controller.java

package controller.ch16;


import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;


import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;


@WebServlet("/ch16_2")
public class ch16_2_controller extends HttpServlet{


@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

RequestDispatcher ds = request.getRequestDispatcher("ch16/insert01.jsp");
ds.forward(request, response);


}


@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//step 1 : 파라미터 수신
request.setCharacterEncoding("UTF-8");

String id=request.getParameter("id");
String passwd=request.getParameter("passwd");
String name=request.getParameter("name");

//step 2 : DB연결
Connection conn=null;

String url="jdbc:mysql://localhost:3306/bookmarketdb";
String user="root";
String password="1234";

//step 4 : 쿼리 실행
Statement stmt=null;

try {
Class.forName("com.mysql.jdbc.Driver");
conn=DriverManager.getConnection(url, user, password);
//step 3 : 쿼리 작성
String sql="INSERT INTO Member(id, passwd, name) VALUES('" + id + "','" + passwd + "','" + name + "')";
//step 4 : 쿼리 실행
stmt=conn.createStatement();
stmt.executeUpdate(sql);
System.out.println("Member 테이블 삽입이 성공했습니다.");
} catch (Exception e) {
System.out.println("Member 테이블 삽입이 실패했습니다.");
System.out.println("v: " + e.getMessage());
}finally {
if(stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {e.printStackTrace();}
}
}
}


}

 

실행 결과

 

2)PreparedStatement 객체로 데이터 접근하기

-PreparedStatement  객체는 동적인 쿼리에 사용하며 형식은 다음과 같음. PreparedStatement 객체는 하나의 객체로 여러 번의 쿼리를 실행할 수 있으며, 동일한 쿼리문을 특정값만 바꾸어서 여러 번 실행해야 할 때, 매개변수가 많아서 쿼리문을 정리해야 할 때 유용함

PreparedStatement  preparedStatement(String sql) throws SQLException 

 

-여기서 매개변수 sql은 데이터베이스에 보낼 쿼리문이며, 쿼리문에 정해지짖 않은 값을 물음표(?)로 표시하여 사용함. 이 물음표에 값을 할당하기 위해 setXxx() 메소드를 사용하는데, 이 메소드는 2개의 매개변수로 설정한 물음표 위치 값(1부터 시작함)과 실제 할당될 값을 가짐. 이때 Xxx는 필드의 데이터형으로, 해당 필드의 데이터형이 문자열이면 setString()이 되고 int이면 setInt()가 됨

 

예제 16-2.PreparedStatement 객체로 INSERT 쿼리문 실행하기

JSPBook/src/main/java/ch16/ch16_2_controller.java

package controller.ch16;


import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;


import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;


@WebServlet("/ch16_2")
public class ch16_2_controller extends HttpServlet{


@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

RequestDispatcher ds = request.getRequestDispatcher("ch16/insert01.jsp");
ds.forward(request, response);


}


@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//step 1 : 파라미터 수신
request.setCharacterEncoding("UTF-8");

String id=request.getParameter("id");
String passwd=request.getParameter("passwd");
String name=request.getParameter("name");

//step 2 : DB연결
Connection conn=null;

String url="jdbc:mysql://localhost:3306/bookmarketdb";
String user="root";
String password="1234";

//step 4 : 쿼리 실행
//Statement stmt=null;
PreparedStatement stmt = null;

try {
Class.forName("com.mysql.jdbc.Driver");
conn=DriverManager.getConnection(url, user, password);
//step 3 : 쿼리 작성
//String sql="INSERT INTO Member(id, passwd, name) VALUES('" + id + "','" + passwd + "','" + name + "')";
String sql="INSERT INTO Member(id, passwd, name) VALUES(?,?,?)";
//String sql="UPDATE Member SET name=? WHERE id=?";
//String sql="DELETE FROM Member WHERE id=?";
//쿼리 작성요령 1. "insert into member(id, passwd, name) VALUES('','','')"
//쿼리 작성요령 2. "insert into member(id, passwd, name) VALUES('id','password','name')"
//쿼리 작성요령 2. "insert into member(id, passwd, name) VALUES('"+id+"','"+password+"','"+name+"')"

//step 4
stmt=conn.prepareStatement(sql);
//? 데이터 입력
stmt.setString(1, name);
stmt.setString(2, id);
//stmt.setString(3, passwd);
stmt.executeUpdate();
System.out.println("Member 테이블 삽입이 성공했습니다.");
} catch (Exception e) {
System.out.println("Member 테이블 삽입이 실패했습니다.");
System.out.println("v: " + e.getMessage());
}finally {
if(stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {e.printStackTrace();}
}
}
}


}

 

◎setXxx() 메소드의 종류: 보낼 데이터 값(데이터 타입)

메소드 반환 유형 설명
setString(int parameterIndex, String x) void 필드 유형이 문자열인 경우
setInt(int parameterIndex, int x) void 필드 유형이 정수형인 경우
setLong(int parameterIndex, long x) void 필드 유형이 정수형인 경우
setDouble(int parameterIndex, double x) void 필드 유형이 실수형인 경우
setFloat(int parameterIndex, float x) void 필드 유형이 실수형인 경우
setObject(int parameterIndex, Object x) void 필드 유형이 객체형인 경우
setDate(int parameterIndex, Date x) void 필드 유형이 날짜형인 경우
setTimestamp(int parameterIndex, Timestamp x) void 필드 유형이 시간형인 경우

*int parameterIndex: 물음표 순서  ( ?,  ?,  ?)

                                                       (1) (2) (3)

 

PreparedStatement  객체의 메소드 종류

메소드 반환 유형 설명
executeQuery() ResultSet SELECT 문을 실행할 때 사용함(ResultSet 객체 반환)
executeUpdate() int 삽입, 수정, 삭제와 관련된 SQL 문 실행에 사용함
close() void PreparedStatement  객체를 반환할 때 사용함

 

executeQuery 메소드로 데이터 조회하기

-executeQuery() 메소드는 동적인 SELECT 쿼리문을 통해 데이터를 검색하는 데 사용하며 형식은 다음과 같음

int executeQuery(String sql) throws SQLException

 

-여기서 매개변수 sql은 데이터베이스에 보낼 쿼리문임.

 

-이 예의 실행 결과는 앞서 Statement 객체가 제공하는 메서드로 SELECT 문을 실행한 예의 실행 결과와 동일함

<%
        Connection conn = null;

         ··· (생략) ···

         String sql = "SELECT * FROM Member WHERE id=? ";         -> 파라미터: 개수만큼 ?, ?, ?

         PreparedStatement pstmt = conn.prepareStatement(sql);
         pstmt.setString(1, "1");                                                                     => 나중에 넣어줌

         ResultSet rs=stmt.executeQuery(sql);
         pstmt.close();
%>

 

executeUpdate() 메소드로 데이터 삽입, 수정, 삭제하기

-executeUpdate() 메소드는 INSERT, UPDATE, DELETE 쿼리문을 통해 데이터를 삽입, 수정, 삭제하는 데 사용하며 향식은 다음과 같음

int executeUpdate(String sql) throws SQLException

 

-여기서 매개변수 sql은 데이터베이스에 보낼 쿼리문임

 

-이 예의 실행 결과는 앞서 Statement 객체가 제공하는 메서드로 INSERT 문을 실행한 예의 실행 결과와 동일함

 

[executeUpdate() 메소드 사용 예(삽입): INSERT 쿼리문]

<%
        Connection conn = null;

         ··· (생략) ···

         String sql="INSERT INTO member(id, passwd, name) VALUES(?,?,?)";

         PreparedStatement pstmt = conn.prepareStatement(sql);

         pstmt.setString(1, "1");                                                                   
         pstmt.setString(2, "홍길순");            -> (?,?,?) 변경
         pstmt.setString(3, "1234");    

         pstmt.executeUpdate();
         ··· (생략) ···
         pstmt.close();
%>

 

[executeUpdate() 메소드 사용 예(수정): UPDATE 쿼리문]

<%
        Connection conn = null;

         ··· (생략) ···
                                  순서
         String sql="UPDATE member SET name=? WHERE id=?";   <- 행 검색

         PreparedStatement pstmt = conn.prepareStatement(sql);           : 다중 검색 가능

         pstmt.setString(1, "1");                                                                   
         pstmt.setString(2, "관리자");      
         pstmt.executeUpdate();
         ··· (생략) ···
         pstmt.close();
%>

 

예제 16-2.PreparedStatement 객체로 UPDATE 쿼리문 실행하기

JSPBook/src/main/java/ch16/ch16_2_controller.java

package controller.ch16;


import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;


import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;


@WebServlet("/ch16_2")
public class ch16_2_controller extends HttpServlet{


@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

RequestDispatcher ds = request.getRequestDispatcher("ch16/insert01.jsp");
ds.forward(request, response);


}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// step 1: 파라미터 수신
request.setCharacterEncoding("UTF-8");

String id = request.getParameter("id");
String passwd = request.getParameter("passwd"); // passwd는 사용되지 않음
String name = request.getParameter("name");

// step 2: DB연결
Connection conn = null;
String url = "jdbc:mysql://localhost:3306/bookmarketdb";
String user = "root";
String password = "1234";

PreparedStatement stmt = null;

try {
Class.forName("com.mysql.cj.jdbc.Driver"); // MySQL Connector/J 8.0 이상
conn = DriverManager.getConnection(url, user, password);

// step 3: 쿼리 작성
String sql = "UPDATE Member SET name=? WHERE id=?";

// step 4
stmt = conn.prepareStatement(sql);
// ? 데이터 입력
stmt.setString(1, name); // name을 첫 번째 매개변수로 설정
stmt.setString(2, id); // id를 두 번째 매개변수로 설정
stmt.executeUpdate();

System.out.println("Member 테이블 업데이트가 성공했습니다.");
} catch (SQLException e) {
System.out.println("Member 테이블 업데이트가 실패했습니다.");
System.out.println("v: " + e.getMessage());
} catch (Exception e) {
System.out.println("예외 발생: " + e.getMessage());
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}



}

 

*실행 순서

                        doget()
index.html ---------------------> Server
                                             Controller
                            ↙                   
                          dopost()
         form  ------------------------>        Controller                              ▣: DB(member)
                       key=value   //전처리  1)getparam 수신                ↗
                                       //모델 이동 2)DB 연결: Connection 
                                                         3)SQL 작성: insert into( )
                                                         4)Data 전송: Statement Query 전송
        ▤    <-------------------  //뷰이동  5)이동 DS(dispatcher)

 

[executeUpdate() 메소드 사용 예(삭제): DELETE  쿼리문]

<%
        Connection conn = null;

         ··· (생략) ···
                                  순서
         String sql="DELETE FROM member WHERE id=?";  <- 꾸며주는 절: 없어도됨(없으면 다 바뀜) 

         PreparedStatement pstmt = conn.prepareStatement(sql);           : 다중 검색 가능

         pstmt.setString(1, "1");                                                                    
         pstmt.executeUpdate();
         ··· (생략) ···
         pstmt.close();
%>

 

예제 16-2.PreparedStatement 객체로 DELETE 쿼리문 실행하기

JSPBook/src/main/java/ch16/ch16_2_controller.java

package controller.ch16;


import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;


import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;


@WebServlet("/ch16_2")
public class ch16_2_controller extends HttpServlet{


@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

RequestDispatcher ds = request.getRequestDispatcher("ch16/insert01.jsp");
ds.forward(request, response);


}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// step 1: 파라미터 수신
request.setCharacterEncoding("UTF-8");

String id = request.getParameter("id");

// step 2: DB연결
Connection conn = null;
String url = "jdbc:mysql://localhost:3306/bookmarketdb";
String user = "root";
String password = "1234";

PreparedStatement stmt = null;

try {
Class.forName("com.mysql.cj.jdbc.Driver"); // MySQL Connector/J 8.0 이상
conn = DriverManager.getConnection(url, user, password);

// step 3: 쿼리 작성
String sql = "DELETE FROM Member WHERE id=?";

// step 4
stmt = conn.prepareStatement(sql);
// ? 데이터 입력
stmt.setString(1, id);
stmt.executeUpdate();

System.out.println("Member 테이블 삭제가 성공했습니다.");
} catch (SQLException e) {
System.out.println("Member 테이블 삭제가 실패했습니다.");
System.out.println("v: " + e.getMessage());
} catch (Exception e) {
System.out.println("예외 발생: " + e.getMessage());
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}


}

*DELETE 쿼리에서는 id만 필요

*PreparedStatement 사용법: executeUpdate() 메서드는 이미 PreparedStatement에 바인딩된 SQL 문을 실행하므로 stmt.executeUpdate(sql);에서 sql을 다시 전달할 필요가 없음 -> stmt.executeUpdate();

 

예제 16-3.하나의 객체로 합친 뒤 결과 전달받기

JSPBook/src/main/wepapp/ch16/member.sql

use bookmarketdb;

create table member(
id varchar(20) not null,
    passwd varchar(20),
    name varchar(30),
    primary key(id)
    
);

insert member values("a", "1111", "이a");
insert member values("b", "1111", "김a");
insert member values("c", "1111", "채a");
insert member values("d", "1111", "신a");
select * from member;

 

JSPBook/src/main/java/ch16/member.java

package controller.dto;


public class member {
private String id;
private String password;
private String name;
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;
}



}

 

JSPBook/src/main/java/ch16/ch16_3_controller.java

package controller.ch16;


import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;


import controller.dto.member;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;


@WebServlet("/ch16_3")
public class ch16_3_controller extends HttpServlet{


@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


RequestDispatcher ds = request.getRequestDispatcher("ch16/select01.jsp");
ds.forward(request, response);
}


@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//step 1 : 파라미터 수신
request.setCharacterEncoding("UTF-8");
String id=request.getParameter("id");



//step 2 : DB연결
Connection conn=null;

String url="jdbc:mysql://localhost:3306/bookmarketdb";
String user="root";
String password="1234";

//step 4 : 쿼리 실행
//Statement stmt=null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn=DriverManager.getConnection(url, user, password);
//step 3 : 쿼리 작성
//String sql="INSERT INTO Member(id, passwd, name) VALUES('" + id + "','" + passwd + "','" + name + "')";
//String sql="insert into member(id, passwd, name) VALUES(?,?,?)";
String sql="select * from member";

//step 4
stmt=conn.prepareStatement(sql);
//? 데이터 입력
//stmt.setString(1, id);
rs = stmt.executeQuery(sql);
//하나의 행이 결과로 전달될 때
/*
member mb=null; //리턴 할 것을 밖으로 빼줌
if(rs.next()) {
String rid = rs.getString("id");
String rpw = rs.getString("passwd");
String rname = rs.getString("name");
mb = new member();
mb.setId(rid);
mb.setPassword(rpw);
mb.setName(rname);
}
*/
//여러개의 행이 결과로 전달될때

ArrayList<member> arr = new ArrayList<member>();
while(rs.next()) {
String rid = rs.getString("id");
String rpw = rs.getString("passwd");
String rname = rs.getString("name");
//꺼낸값 하나의 객체로 합치기
member mb = new member();
mb.setId(rid);
mb.setPassword(rpw);
mb.setName(rname);
//ArrayList에 하나의 객체로 넣기
arr.add(mb);
}


//step 5 : 뷰이동
request.setAttribute("memberlist", arr);
//request.setAttribute("member", mb);
RequestDispatcher ds = request.getRequestDispatcher("ch16/result.jsp");
ds.forward(request, response);

System.out.println("Member 테이블 삽입이 성공했습니다.");
} catch (Exception e) {
System.out.println("Member 테이블 삽입이 실패했습니다.");
System.out.println("v: " + e.getMessage());
}finally {
if(stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {e.printStackTrace();}
}
}
}


}

 

JSPBook/src/main/webapp/ch16/select01.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Database SQL</title>
</head>
<body>
<form method="post" action="ch16_3">
<p> 아이디 : <input type="text" name="id">
<p> <input type="submit" value="검색">
</form>
</body>
</html>

 

JSPBook/src/main/webapp/ch16/result.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ page import="controller.dto.member" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
//member mb = (member)request.getAttribute("member");
ArrayList<member> arr=(ArrayList<member>)request.getAttribute("memberlist");
%>
<!-- 하나의 dto 객체를 전달받았을때
<table border="1">
<tr>
<th>아이디</th><th>패스워드</th><th>이름</th>
</tr>
<tr>
<td></td><td></td><td></td>
</tr>
</table>
-->
<!-- ArrayList로 여러개의 dto 객체를 전달받았을 때 -->
<%
for(int i=0; i<arr.size(); i++){
member amb = arr.get(i);
%>
<table border="1">
<tr>
<td>아이디</td><td>패스워드</td><td>이름</td>
</tr>
<tr>
<td><%=amb.getId() %></td><td><%=amb.getPassword() %></td><td><%=amb.getName() %></td>
</tr>
</table>
<% } %>
</body>
</html>

 

실행 결과