반응형
PreparedStatement
: SQL문을 바로 실행하지 않고 잠시 보관한다.
- 미완성된 SQL문을 먼저 전달하고, 실행하기 전에 완성 형태로 만든 후 실행한다.
- 미완성된 SQL문 만들기
→ 사용자가 입력한 값들이 들어갈 수 있는 공간을 위치홀더 '?'로 확보한다.
→ 각 위치홀더에 맞는 값을 세팅한다.
- Statement의 자식 객체이다.
- Statement와의 차이점
① Statement는 완성된 SQL문을 작성하는 반면, PreparedStatement는 미완성된 SQL문에 위치홀더 '?'를
사용하여 작성한다.
② Statement로 작성 시: 'stmt = conn.createStatement();'
PreparedStatement로 작성 시: 'pstmt = conn.preparedStatement(sql);'
③ Statement로 SQL문 실행 시: 'stmt.executeXXX(sql);'
PreparedStatement로 SQL문 실행 시
: 'pstmt.setString(?위치, 값);', 'pstmt.setInt(?위치, 값);', '결과 = pstmt.executeXXX();'
- 한 번만 실행할 땐 Statement를 사용하고, 여러 번 실행할 땐 preparedStatement를 사용하는 것이 좋다.
VO
package member.model.vo;
import java.sql.Date;
public class Member {
private int userNo;
private String userId;
private String userPw;
private String userName;
private String gender;
private int age;
private String email;
private String phone;
private String address;
private String hobby;
private Date enrollDate;
public Member() {
super();
}
public Member(int userNo, String userId, String userPw, String userName, String gender
, int age, String email, String phone, String address, String hobby
, Date enrollDate) {
super();
this.userNo = userNo;
this.userId = userId;
this.userPw = userPw;
this.userName = userName;
this.gender = gender;
this.age = age;
this.email = email;
this.phone = phone;
this.address = address;
this.hobby = hobby;
this.enrollDate = enrollDate;
}
// 회원 추가용 생성자(userNo와 enrollDate 제외한 매개변수 생성자)
public Member(String userId, String userPw, String userName, String gender, int age
, String email, String phone, String address, String hobby) {
super();
this.userId = userId;
this.userPw = userPw;
this.userName = userName;
this.gender = gender;
this.age = age;
this.email = email;
this.phone = phone;
this.address = address;
this.hobby = hobby;
}
public Member(String userId, String userPw, String email, String phone, String address) {
super();
this.userId = userId;
this.userPw = userPw;
this.email = email;
this.phone = phone;
this.address = address;
}
public int getUserNo() {
return userNo;
}
public void setUserNo(int userNo) {
this.userNo = userNo;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserPw() {
return userPw;
}
public void setUserPw(String userPw) {
this.userPw = userPw;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public Date getEnrollDate() {
return enrollDate;
}
public void setEnrollDate(Date enrollDate) {
this.enrollDate = enrollDate;
}
@Override
public String toString() {
return "Member [userNo=" + userNo + ", userId=" + userId + ", userPw=" + userPw
+ ", userName=" + userName + ", gender=" + gender + ", age=" + age + ", email="
+ email + ", phone=" + phone + ", address=" + address + ", hobby=" + hobby
+ ", enrollDate=" + enrollDate + "]";
}
}
Run
package member.run;
import member.view.MemberView;
public class Run {
public static void main(String[] args) {
new MemberView().mainMenu();
}
}
View
package member.view;
import java.util.ArrayList;
import java.util.Scanner;
import member.controller.MemberController;
import member.model.vo.Member;
// View : 사용자가 보게 될 시각적인 요소를 담당한다.
public class MemberView {
private Scanner sc = new Scanner(System.in);
// 전역으로 MemberController에 요청할 수 있는 객체 생성
private MemberController mc = new MemberController();
public void mainMenu() {
// 프로그램 종료 전까지 메뉴 선택을 반복하기 위해 while문으로 감싸기
while(true) {
System.out.println("========회원관리 프로그램=========");
System.out.println("1. 회원 추가");
System.out.println("2. 회원 전체 조회");
System.out.println("3. 회원 아이디로 검색");
System.out.println("4. 회원 이름 검색");
System.out.println("5. 회원 정보 변경");
System.out.println("6. 회원 탈퇴");
System.out.println("0. 프로그램 종료");
System.out.println("=================================");
System.out.println("원하는 메뉴 번호를 입력하세요. ");
int menu = sc.nextInt();
sc.nextLine();
switch(menu) {
case 1: insertMember(); break;
case 2: selectAll(); break;
case 3: searchById(); break;
case 4: searchByName(); break;
case 5: updateMember(); break;
case 6: deleteMember(); break;
case 0: System.out.println("프로그램을 종료합니다."); return;
// break;를 쓰면 스위치문에서만 벗어나고 다시 반복됨
default: System.out.println("메뉴번호를 잘못 입력하였습니다.");
}
}
}
// 회원 추가용 화면
// 추가하고자 하는 회원의 정보를 입력받아 추가 '요청'할 수 있는 화면
// 1. 회원 추가 화면
public void insertMember() {
System.out.println("-------회원 추가-------");
// 입력
// 회원번호(시퀀스) enrollDate(default SYSDATE) 두 컬럼에 대해서 입력받지 않는다.
System.out.println("아이디: ");
String userId = sc.nextLine();
System.out.println("비밀번호: ");
String userPw = sc.nextLine();
System.out.println("이름: ");
String userName = sc.nextLine();
System.out.println("성별: ");
String gender = sc.nextLine();
System.out.println("나이: ");
int age = sc.nextInt();
sc.nextLine();
System.out.println("이메일: ");
String email = sc.nextLine();
System.out.println("휴대번호: (- 없이 숫자만 입력)");
String phone = sc.nextLine();
System.out.println("주소: ");
String address = sc.nextLine();
System.out.println("취미: ");
String hobby = sc.nextLine();
// 입력받은 정보를 매개변수로 넘겨서 회원 추가 요청 - Controller에 있는 메소드를 호출한다
mc.insertMember(userId, userPw, userName, gender, age, email, phone, address, hobby);
}
// 2. 회원 전체 조회 화면
public void selectAll() {
System.out.println("--------회원 전체 조회--------");
// Controller에 회원 전체 조회 요청
mc.selectAll();
}
// 3. 회원 아이디로 검색하는 화면
public void searchById() {
System.out.println("-------회원 아이디로 검색-------");
System.out.println("검색할 회원의 아이디 입력: ");
String userId = sc.nextLine();
// 입력한 아이디로 Controller에 요청하기
mc.searchById(userId);
}
// 4. 회원 이름으로 검색하는 화면
public void searchByName() {
System.out.println("--------회원 이름으로 검색--------");
System.out.println("검색할 회원의 이름 입력: ");
String userName = sc.nextLine();
mc.searchByName(userName);
}
// 5. 회원 정보를 수정하는 화면
public void updateMember() {
System.out.println("---------회원 정보 변경---------");
// 변경할 회원의 아이디
System.out.println("변경할 회원의 아이디: ");
String userId = sc.nextLine();
// 변경할 정보들
System.out.println("변경할 비밀번호 입력: ");
String userPw = sc.nextLine();
System.out.println("변경할 이메일 입력: ");
String email = sc.nextLine();
System.out.println("변경할 휴대번호 입력: ");
String phone = sc.nextLine();
System.out.println("변경할 주소 입력: ");
String address = sc.nextLine();
// 회원 정보 수정 요청
mc.updateMember(userId, userPw, email, phone, address);
}
// 6. 회원 탈퇴하는 화면
//
public void deleteMember() {
System.out.println("---------회원 탈퇴---------");
System.out.println("회원 탈퇴할 아이디: ");
String userId = sc.nextLine();
mc.deleteMember(userId);
}
//---------------------------------------------------
// 서비스 요청 시 사용자가 보게될 응답 화면
// 서비스 요청 성공 시 응답 화면
public void displaySuccess(String message) {
System.out.println("서비스 요청 성공: " + message);
}
// 서비스 요청 실패시 응답 화면
public void displayFail(String message) {
System.out.println("서비스 요청 실패: " + message);
}
// 전체 조회 결과가 없을 때 응답 화면
public void displayNoData(String message) {
System.out.println(message);
}
// 전체 조회 결과가 있을 때 응답 화면
public void displayList(ArrayList<Member> list) {
System.out.println("조회된 결과는 " + list.size() + "건입니다.");
// 향상된 for문
for(Member m : list) { // for(반환할타입 변수명 : 반복할저장소(컬렉션/배열))
System.out.println(m);
}
}
// 조회결과가 하나일 때
public void displayOne(Member m) {
System.out.println("조회된 결과는 다음과 같습니다.");
System.out.println(m);
}
}
Controller
package member.controller;
import java.util.ArrayList;
import member.model.dao.MemberDao;
import member.model.vo.Member;
import member.view.MemberView;
public class MemberController {
public void insertMember(String userId, String userPw, String userName, String gender
, int age, String email, String phone, String address
, String hobby) {
// 1. 전달된 데이터들을 Member 객체에 담기(가공 처리)
Member m = new Member(userId, userPw, userName, gender, age, email, phone, address
, hobby);
// 2. Dao의 insertMember 메소드를 호출(가공된 멤버객체를 보낸다.)
int result = new MemberDao().insertMember(m);
// 3. Dao에서 작업한 결과값에 따라 View에 보여질 화면을 정해준다.
if(result > 0) {
// 성공했으니 성공 메시지를 보낸다.
new MemberView().displaySuccess("회원 추가 성공");
} else {
// 실패했으니 실패 메시지를 보낸다.
new MemberView().displayFail("회원 추가 실패");
}
}
// 사용자의 회원 전체 조회 요청을 처리해주는 메소드
public void selectAll() {
// view에서 controller로 전체조회 요청 받음 -> Dao에게 DB로부터 전체조회해오라고 요청함
// -> Dao가 Controller에게 전체조회한 결과값을 전달해줌
// 결과값을 담을 변수
// SELECT - ResultSet -> ArrayList<Member>
ArrayList<Member> list = new MemberDao().selectAll();
// DAO에서 작업을 끝마친 결과를 전달받아 해당 결과를 토대로 어떤 화면을 보여줄지 정하여
// view에 전달한다.
// 조회결과가 있는지 없는지 판단 후 사용자가 보게될 화면을 지정한다.
if(list.isEmpty()) { // list가 비어있어 true인 경우
new MemberView().displayNoData("전체 조회 결과가 없습니다.");
} else { // list 조회된 경우 list에 Member가 담겨있음
new MemberView().displayList(list);
}
}
// 사용자가 입력한 아이디로 검색 요청을 처리해주는 메소드
public void searchById(String userId) {
Member m = new MemberDao().searchById(userId);
if(m == null) {
new MemberView().displayNoData(userId+"에 해당하는 조회 결과가 없습니다.");
} else {
new MemberView().displayOne(m);
}
}
// 사용자가 입력한 이름으로 검색 요청을 처리해주는 메소드
public void searchByName(String userName) {
ArrayList<Member> list = new MemberDao().searchByName(userName);
if(list.isEmpty()) {
new MemberView().displayNoData(userName+"에 해당하는 조회 결과가 없습니다.");
} else {
new MemberView().displayList(list);
}
}
// 사용자가 입력한 정보들을 변경 요청을 처리해주는 메소드
public void updateMember(String userId, String userPw, String email, String phone
, String address) {
Member m = new Member(userId, userPw, email, phone, address);
// m.getUserId();
// m.getUserPw();
// m.getEmail();
// m.getPhone();
// m.getAddress();
int result = new MemberDao().updateMember(m);
if(result > 0) {
new MemberView().displaySuccess("회원 정보 변경 성공");
} else {
new MemberView().displayFail("회원 정보 변경 실패");
}
}
// 사용자가 입력한 정보들을 삭제 요청 처리해주는 메소드
public void deleteMember(String userId) {
int result = new MemberDao().deleteMember(userId);
if(result > 0) {
new MemberView().displaySuccess("회원 탈퇴되었습니다.");
} else {
new MemberView().displayFail(userId+"에 해당하는 아이디가 없습니다.");
}
}
}
DAO
package member.model.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import member.model.vo.Member;
public class MemberDao {
public int insertMember(Member m) {
int result = 0;
Connection conn = null;
PreparedStatement pstmt = null;
// INSERT INTO MEMBER VALUES(SEQ_USERNO.NEXTVAL, 'XXX', 'XXX', ... SYSDATE);
String sql = "INSERT INTO MEMBER VALUES(SEQ_USERNO.NEXTVAL, ?, ?, ?, ?, ?, ?, ?
, ?, ?, DEFAULT)";
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC"
, "JDBC");
pstmt = conn.prepareStatement(sql);
// 미완성된 SQL문 완성시켜주기
pstmt.setString(1, m.getUserId());
pstmt.setString(2, m.getUserPw());
pstmt.setString(3, m.getUserName());
pstmt.setString(4, m.getGender());
pstmt.setInt(5, m.getAge());
pstmt.setString(6, m.getEmail());
pstmt.setString(7, m.getPhone());
pstmt.setString(8, m.getAddress());
pstmt.setString(9, m.getHobby());
result = pstmt.executeUpdate();
if(result > 0) {
conn.commit();
} else {
conn.rollback();
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
try {
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return result;
}
public ArrayList<Member> selectAll(){
Connection conn = null;
Statement stmt = null;
ResultSet rset = null;
ArrayList<Member> list = new ArrayList<>();
// 실행할 SQL문
String sql = "SELECT * FROM MEMBER";
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC"
, "JDBC");
stmt = conn.createStatement();
rset = stmt.executeQuery(sql);
/// 커서를 한 줄 옮기고 해당 위치에 데이터가 있으면 true, 없으면 false
while(rset.next()) {
// 현재 커서가 가르키고 있는 행의 데이터를 뽑아 Member 객체에 담기
Member m = new Member();
/*
* rset으로부터 어떤 컬럼에 해당하는 값을 뽑을 건지 제시
* -> 컬럼명(대소문자 가리지 않음), 컬럼 순번
* -> 권장사항 = 컬럼명 + 대문자
* rset.getInt() = int형 값 뽑을 때
* rset.getString() = String형 값 뽑을 때
* rset.getDate() = Date형 값 뽑을 때
* */
m.setUserNo(rset.getInt("USERNO"));
m.setUserId(rset.getString("USERID"));
m.setUserPw(rset.getString("USERPW"));
m.setUserName(rset.getString("USERNAME"));
m.setGender(rset.getString("GENDER"));
m.setAge(rset.getInt("AGE"));
m.setEmail(rset.getString("EMAIL"));
m.setPhone(rset.getString("PHONE"));
m.setAddress(rset.getString("ADDRESS"));
m.setHobby(rset.getString("HOBBY"));
m.setEnrollDate(rset.getDate("ENROLLDATE"));
// 한 행에 대한 모든 컬럼의 데이터값을 Member 객체 필드에 각각 담았다.
list.add(m);
}
} catch (ClassNotFoundException | SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
rset.close();
stmt.close();
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return list;
// 행의 데이터를 갖고 있는 Member 객체들이 인덱스에 담겨있는 리스트를 반환한다.
}
// 사용자에게 입력받은 아이디로 해당 회원이 있는지 정보 검색 처리하는 메소드
public Member searchById(String userId) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rset = null;
Member m = null;
String sql = "SELECT * FROM MEMBER WHERE USERID = ?";
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC"
, "JDBC");
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, userId);
rset = pstmt.executeQuery();
if(rset.next()) {
m = new Member(rset.getInt("USERNO")
, rset.getString("USERID")
, rset.getString("USERPW")
, rset.getString("USERNAME")
, rset.getString("GENDER")
, rset.getInt("AGE")
, rset.getString("EMAIL")
, rset.getString("PHONE")
, rset.getString("ADDRESS")
, rset.getString("HOBBY")
, rset.getDate("ENROLLDATE"));
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
try {
rset.close();
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return m;
}
public ArrayList<Member> searchByName(String userName) {
Connection conn = null;
PreparedStatement pstmt= null;
ResultSet rset = null;
ArrayList<Member> list = new ArrayList<>();
// String sql = "SELECT * FROM MEMBER WHERE USERNAME LIKE ?";
// pstmt.setString(1, "%" + userName + "%"); <- 위와 세트
String sql = "SELECT * FROM MEMBER WHERE USERNAME LIKE '%' || ? || '%'";
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC"
, "JDBC");
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, userName);
rset = pstmt.executeQuery();
while(rset.next()) {
list.add(new Member(rset.getInt("USERNO")
, rset.getString("USERID")
, rset.getString("USERPW")
, rset.getString("USERNAME")
, rset.getString("GENDER")
, rset.getInt("AGE")
, rset.getString("EMAIL")
, rset.getString("PHONE")
, rset.getString("ADDRESS")
, rset.getString("HOBBY")
, rset.getDate("ENROLLDATE")));
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
try {
rset.close();
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return list;
}
public int updateMember(Member m) {
Connection conn = null;
PreparedStatement pstmt = null;
int result = 0; // DML은 몇 행 실행되었는지 확인해야 하므로 int형
String sql="UPDATE MEMBER"
+ " SET"
+ " USERPW=?"
+ ", EMAIL=?"
+ ", PHONE=?"
+ ", ADDRESS=?"
+ "WHERE USERID=?";
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe",
"JDBC","JDBC");
pstmt=conn.prepareStatement(sql);
pstmt.setString(1,m.getUserPw());
pstmt.setString(2,m.getEmail());
pstmt.setString(3, m.getPhone());
pstmt.setString(4, m.getAddress());
pstmt.setString(5, m.getUserId());
result=pstmt.executeUpdate();
if(result>0) {
conn.commit();
}else {
conn.rollback();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return result;
}
public int deleteMember(String userId) {
Connection conn = null;
PreparedStatement pstmt = null;
int result = 0;
String sql = "DELETE FROM MEMBER WHERE USERID = ?";
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC"
, "JDBC");
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, userId);
result = pstmt.executeUpdate();
if(result > 0) {
conn.commit();
} else {
conn.rollback();
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
try {
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return result;
}
}
반응형