DAO
- 실질적으로 DB에 접근하는 객체
- DB를 사용해 데이터를 조회하거나 조작하는 기능을 전담하도록 만든 오브젝트 (보통 singleton 패턴으로 만듦)
# 오늘의 코딩 #
- 이번엔 SQL Injection이 발생하지 않는 PreparedStatement 활용해보자
- Singleton으로 만들어서 하나의 객체만 생성되고 그 객체가 DB와 연동, Login을 수행해보자
# Login VO 클래스
- Login 사용 클래스에서 설정한 ID와 PW를 저장하고 반환해줄 클래스
public class LoginVO {
private String id, pass;
public LoginVO() {
super();
}
public LoginVO(String id, String pass) {
this.id = id;
this.pass = pass;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
@Override
public String toString() {
return "LoginVO [id=" + id + ", pass=" + pass + "]";
}
}
# Login DAO 클래스
- DB와 연결되어 일을 할 클래스
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import test.dao.DbConnection;
public class LoginDAO {
public String usePreparedStatement(LoginVO loginVO) throws SQLException {
String name ="";
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
DbConnection db = DbConnection.getInstance();
try {
//1.드라이버로딩 & 2.Connection얻기 (중복된 일이라 따로 method 만들어놨음)
con = db.getConn();
//3.쿼리문 생성 객체 얻기
StringBuilder selectName = new StringBuilder();
selectName
.append(" select name ")
.append(" from test_login ")
.append(" where id = ? and pass = ? "); // ? : 바인드 변수!!
pstmt = con.prepareStatement(selectName.toString());
//4.바인드 변수에 값 설정 (VO Class에서 가져오기)
pstmt.setString(1, loginVO.getId());
pstmt.setString(2, loginVO.getPass());
//5.쿼리문 수행 후 결과 얻기
rs = pstmt.executeQuery();
if(rs.next()) {//입력된 id와 p/w에 일치하는 레코드가 존재
name = rs.getString("name"); // 조회된 이름 가져와서 변수에 할당
}//end if
}finally{
//6.연결 끊기 (얘도 method 만들어놨음)
db.closeDB(rs, pstmt, con);
}//end finally
return name;
}//usePreparedStatement
}//class
# Login을 수행할 클래스
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.sql.SQLException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
@SuppressWarnings("serial")
public class TestLogin extends JFrame implements ActionListener {
private JTextField jtfId;
private JPasswordField jpfPass;
private JLabel jlblOutput;
public TestLogin() {
super("로그인");
jtfId=new JTextField();
jpfPass=new JPasswordField();
jlblOutput=new JLabel("출력");
jtfId.setBorder(new TitledBorder("아이디"));
jpfPass.setBorder(new TitledBorder("비밀번호"));
jlblOutput.setBorder(new TitledBorder("결과"));
jpfPass.addActionListener(this);
setLayout(new GridLayout(3,1));
add(jtfId);
add(jpfPass);
add(jlblOutput);
// 종료
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
dispose();
}//windowClosing
@Override
public void windowClosed(WindowEvent e) {
System.exit(JFrame.ABORT);
}//windowClosed
});
setBounds(100, 100, 250, 300);
setVisible(true);
}//TestLogin
public void usePreparedStatement() {
LoginDAO ld = new LoginDAO();
//아이디와 비밀번호를 받자
LoginVO lv = new LoginVO(jtfId.getText(), new String(jpfPass.getPassword()));
try {
String name = ld.usePreparedStatement(lv);
if("".equals(name)) {//이름이 조회되지 않음
JOptionPane.showMessageDialog(this, "아이디나 비밀번호를 확인해주세요.");
return;
}//end if
jlblOutput.setText(name + "님 반갑습니다.");
} catch (SQLException e) {
JOptionPane.showMessageDialog(this, "죄송합니다.");
e.printStackTrace();
}//end catch
}//usePreparedStatement
@Override
public void actionPerformed(ActionEvent e) {
usePreparedStatement(); // SQLInjection 공격불가
}//actionPerformed
public static void main(String[] args) {
new TestLogin();
}//main
}//class
# 출력 결과 #
(기존 DB 데이터의 ID와 비밀번호는 각각 WOO/4321)

> 로그인 성공시 화면

> 로그인 실패시 화면
'Development > JDBC' 카테고리의 다른 글
| [JDBC] Procedure 호출 / in parameter / out parameter / CallableStatement 활용 (0) | 2021.10.20 |
|---|---|
| [JDBC] ResultSetMetaData / Transaction 처리 (0) | 2021.10.19 |
| [Java/JDBC] Singleton Pattern (0) | 2021.10.14 |
| [JDBC] SQL Exception / SQL Injection (0) | 2021.10.13 |
| [JDBC] ResultSet / Statement 활용 (0) | 2021.10.12 |