✅ 초난감 DAO
지금부터는 DAO에 대해서 한번 알아보겠습니다.
- DB 생성 SQL
USE toby_study; CREATE TABLE users( id VARCHAR(10) PRIMARY KEY, name VARCHAR(20) NOT NULL, password VARCHAR(20) NOT NULL );
- user
package com.jhcode.spring.domain; public class User { String id; String name; String password; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
- UserDao
package com.jhcode.spring.dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import com.jhcode.spring.domain.User; public class UserDao { public void add(User user) throws ClassNotFoundException, SQLException{ String className = "org.mariadb.jdbc.Driver"; String url = "jdbc:mariadb://localhost:3306/toby_study?characterEncoding=UTF-8"; String userId = "root"; String password = "1234"; Class.forName(className); Connection con = DriverManager.getConnection(url, userId, password); //프리페어 스테이트먼츠 사용 String sql = "INSERT INTO users(id, name, password) values(?,?,?)"; PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, user.getId()); pst.setString(2, user.getName()); pst.setString(3, user.getPassword()); pst.executeUpdate(); pst.close(); con.close(); } public User get(String id) throws ClassNotFoundException, SQLException { String className = "org.mariadb.jdbc.Driver"; String url = "jdbc:mariadb://localhost:3306/toby_study?characterEncoding=UTF-8"; String userId = "root"; String password = "1234"; Class.forName(className); Connection con = DriverManager.getConnection(url, userId, password); String sql = "SELECT * FROM users WHERE id=?"; PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, id); ResultSet rs = pst.executeQuery(); User user = new User(); if (rs.next()) { user.setId(rs.getString("id")); user.setName(rs.getString("name")); user.setPassword(rs.getString("password")); } rs.close(); pst.close(); con.close(); return user; } }
“MariaDB”를 사용해서 DB와 연결시켰다.
className
과url
부분은 아래의 블로그를 참고했습니다.🔹JDBC를 이용하는 작업의 일반적인 순서는 다음과 같습니다.
- #1 드라이브 연결(Class.forName)
Class 클래스(클래스의 이름이 Class이다 헷갈리지 말자, java.lang패키지에 있어서 import 없이도 사용할 수 있다)에 있는 forName() 메서드를 사용해서 드라이브를 연결시킵니다. 매개변수로 넘겨준 className은 String 타입으로 불러올 드라이버의 이름을 위에서 먼저 선언하였습니다.
ClassNotFoundExcption
을 try-catch문으로 잡거나throws
를 통해 던져야 합니다.
- #2 연결자(Connection) 호출
프로그램과 DB의 연결을 관리해주는 객체입니다.
DriverManager
클래스에 getConnection()메서드를 사용해서, 연결자 객체를 생성한 다음 이를 쉽게 참조(사용)하기 위해서 먼저 선언한 Connection 타입의 참조변수 conn에 대입한 것입니다. 매개변수로 연결할 jdbc드라이버의 url, DB에 접속할 때 사용할 id와 password를 미리 선언하여 코드를 보기 쉽게 하였습니다. SQLException을 예외를 처리해야합니다.
- #3 Statement, PrepareStatement 객체 생성
- statement
//스테이트먼트 쿼리문, 데이터베이스에 저장하는 쿼리문 작성 sql = "INSERT INTO users(id, name, password) values('"+id+"','"+name+"','"+password+"')"; //쿼리문 수행 DB가 수정되기 때문에 executeUpdate 사용함 int result = stm.executeUpdate(sql); //반환타입이 int다 정상적으로 수행한 쿼리문의 개수를 알려준다.
statement 객체를 생성할 때는 인자로 값을 넘겨주지 않아도 되서 쿼리문을 먼저 작성하지 않고도 객체를 생성할 수 있습니다.
statement 쿼리문을 작성할 때 유의해야할 것은 “” 따옴표 안에 작성된 쿼리문에 변수명이 들어가게 되면, 변수로 인식되지 않고 쿼리문 자체(문자열)로 인식됩니다. 따라서 위의 코드와 같이 변수의 값이 들어가는게 아니라 “id”라는 문자열이 DB에 저장됩니다. 중간에 작은 따옴표 ‘ 와 큰 따옴표 “를 섞어서 쿼리문을 작성하여 id 변수가 문자열이 아닌 변수로 인식되게 만들어줘야 합니다.
담아야할 데이터가 많으면 많을수록 따옴표의 개수도 많아지므로 여간 불편하고 헷갈리는 코드입니다. 이를 프리페어 스테이트먼트(PreparedStatement)를 통해 해결할 수 있습니다.
- prepareStatement
//프리페어 스테이트먼트 쿼리문 작성 String sql = "INSERT INTO users(id, name, password) values(?,?,?)"; PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, user.getId()); pst.setString(2, user.getName()); pst.setString(3, user.getPassword()); pst.executeUpdate();
prepareStatement 객체를 생성하기 위해선 인자로 쿼리문을 먼저 넘겨줘야 합니다. 그래서 쿼리문을 먼저 작성하였습니다. 쿼리문은 컬럼의 개수만큼 와일드카드를 사용합니다.
setter을 사용해서 prepareStatement 객체에 정보를 저장합니다. 각 타입에 맞는 setter을 사용해야 합니다.
pst.setString(parameterIndex, x)
parameterIndex
: 쿼리문에서 물음표의 순번x
: 저장할 값
- statement
- #4 쿼리문 실행
SELECT 문은
ResultSet
을 반환하고, INSERT, UPDATE, DELETE 문은 처리된 레코드의 개수를 반환합니다. CREATE나 ALTER 문은 쿼리를 정상적으로 수행하면 0을 반환합니다. SELECT문으로 조회하여 반환된ResultSet
객체에서 정보가 있는지interator
로 확인할 수 있습니다. 정보가 있다면, User 객체에 정보를 옮기고 해당 객체를return
하여 해당 메소드를 호출한 곳에서 사용할 수 있도록 만듭니다.
- #1 드라이브 연결(Class.forName)
- main()을 이용한 DAO 테스트 코드
public static void main(String[] args) throws ClassNotFoundException, SQLException { UserDao dao = new UserDao(); User user = new User(); user.setId("whiteship"); user.setName("jhcode"); user.setPassword("mariaDB"); dao.add(user); System.out.println(user.getId() + " 등록 성공"); User user2 = dao.get(user.getId()); System.out.println(user2.getName()); System.out.println(user2.getPassword()); System.out.println(user2.getId() + " 조회 성공"); }
JDBC를 이용하여 사용자 정보가 DB에 저장되고 조회되는 간단한 DAO를 작성했습니다.
프로젝트 환경
- IDE : STS3 - 3.9.18.RELEASE
- SpringFramework : 5.3.20
- Java : 11
- Maven
📖토비 스프링 3.1 -p54~59
🚩jhcode33의 toby-spring-study.git으로 이동하기
Uploaded by N2T