들어가기 전에
이번 시간엔 JDBC를 이용해 데이터베이스에서 입력/수정/조회/삭제를 하는 프로그램을 만들어 보도록 하겠습니다.
학습 목표
- JDBC를 이용해 입력/수정/삭제/조회 프로그래밍을 할 수 있다.
핵심 개념
- JDBC
- PreparedStatement
- ResultSet
- Connection
학습하기
들어가기 전에
이번 시간엔 JDBC를 이용해 데이터베이스에서 입력/수정/조회/삭제를 하는 프로그램을 만들어 보도록 하겠습니다.
학습 목표
핵심 개념
학습하기
실습코드
RoleDao.java - SELECT
package kr.or.connect.jdbcexam.dao;
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 java.util.List;
import kr.or.connect.jdbcexam.dto.Role;
public class RoleDao {
private static String dburl = "jdbc:mysql://localhost:3306/connectdb";
private static String dbUser = "connectuser";
private static String dbpasswd = "connect123!@#";
public List<Role> getRoles() {
List<Role> list = new ArrayList<>();
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String sql = "SELECT description, role_id FROM role order by role_id desc";
try (Connection conn = DriverManager.getConnection(dburl, dbUser, dbpasswd);
PreparedStatement ps = conn.prepareStatement(sql)) {
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
String description = rs.getString(1);
int id = rs.getInt("role_id");
Role role = new Role(id, description);
list.add(role); // list에 반복할때마다 Role인스턴스를 생성하여 list에 추가한다.
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return list;
}
}
JDBCExam3.java - SELECT
package kr.or.connect.jdbcexam;
import java.util.List;
import kr.or.connect.jdbcexam.dao.RoleDao;
import kr.or.connect.jdbcexam.dto.Role;
public class JDBCExam3 {
public static void main(String[] args) {
RoleDao dao = new RoleDao();
List<Role> list = dao.getRoles();
for(Role role : list) {
System.out.println(role);
}
}
}
RoleDao.java - Delete
package kr.or.connect.jdbcexam.dao;
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 java.util.List;
import kr.or.connect.jdbcexam.dto.Role;
public class RoleDao {
private static String dburl = "jdbc:mysql://localhost:3306/connectdb";
private static String dbUser = "connectuser";
private static String dbpasswd = "connect123!@#";
public int deleteRole(Integer roleId) {
int deleteCount = 0;
Connection conn = null;
PreparedStatement ps = null;
try {
Class.forName( "com.mysql.jdbc.Driver" );
conn = DriverManager.getConnection ( dburl, dbUser, dbpasswd );
String sql = "DELETE FROM role WHERE role_id = ?";
ps = conn.prepareStatement(sql);
ps.setInt(1, roleId);
deleteCount = ps.executeUpdate();
}catch(Exception ex) {
ex.printStackTrace();
}finally {
if(ps != null) {
try {
ps.close();
}catch(Exception ex) {}
} // if
if(conn != null) {
try {
conn.close();
}catch(Exception ex) {}
} // if
} // finally
return deleteCount;
}
}
JDBCExam4.java - Delete
package kr.or.connect.jdbcexam;
import kr.or.connect.jdbcexam.dao.RoleDao;
public class JDBCExam4 {
public static void main(String[] args) {
//삭제 테스트
int roleId = 500;
RoleDao dao = new RoleDao();
int deleteCount = dao.deleteRole(roleId);
System.out.println(deleteCount);
}
}
RoleDao.java - Update
package kr.or.connect.jdbcexam.dao;
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 java.util.List;
import kr.or.connect.jdbcexam.dto.Role;
public class RoleDao {
private static String dburl = "jdbc:mysql://localhost:3306/connectdb";
private static String dbUser = "connectuser";
private static String dbpasswd = "connect123!@#";
public int updateRole(Role role) {
int updateCount = 0;
Connection conn = null;
PreparedStatement ps = null;
try {
Class.forName( "com.mysql.jdbc.Driver" );
conn = DriverManager.getConnection ( dburl, dbUser, dbpasswd );
String sql = "update role set description = ? where role_id = ?";
ps = conn.prepareStatement(sql);
ps.setString(1, role.getDescription());
ps.setInt(2, role.getRoleId());
updateCount = ps.executeUpdate();
}catch(Exception ex) {
ex.printStackTrace();
}finally {
if(ps != null) {
try {
ps.close();
}catch(Exception ex) {}
} // if
if(conn != null) {
try {
conn.close();
}catch(Exception ex) {}
} // if
} // finally
return updateCount;
}
}
JDBCExam5.java - Update
package kr.or.connect.jdbcexam;
import kr.or.connect.jdbcexam.dao.RoleDao;
import kr.or.connect.jdbcexam.dto.Role;
public class JDBCExam5 {
public static void main(String[] args) {
//수정테스트
int roleId = 500;
String description = "CEO";
Role role = new Role(roleId, description);
RoleDao dao = new RoleDao();
int updateCount = dao.updateRole(role);
System.out.println(updateCount);
}
}
[참고] Role 스키마 구조
mysql> describe Role;
+-------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| role_id | int(11) | NO | PRI | NULL | |
| description | varchar(100) | YES | | NULL | |
+-------------+--------------+------+-----+---------+-------+
생각해보기
참고 자료
https://docs.oracle.com
https://docs.oracle.com
comment
JDBC Process에서 Class 생성시 sql문과 executeUpdate - int, executeQuery ResultSet 결과처리 로직을 제외한 나머지를 제거할 수 있을 거같습니다
1. DataBase와 Java Application 간에 Connection을 맺는 부분과, MySQL Driver 클래스를 JVM에 로드하는 부분의 중복을 제거할 수 있을 것 같습니다.
2. Java SE 7 부터 추가된 try-with-resources 문을 사용한다면, Connection 객체, PreparedStatement 객체, ResultSet 객체를 사용한 후 자동으로 닫아주기 때문에 해당 객체의 close 부분의 코드를 줄일 수 있습니다.
제가 인텔리제이를 사용하고 mysql 버전도 달라서 진행하는데 조금 어려움이 있었습니다. 블로그에 정리해놨으니 필요하시면 보세요. (코드와 같은 강의에 포함된 내용은 없습니다)
https://seung00.tistory.com/category/language%20and%20framework/java
너무 좋은 강의 항상 감사합니다
여러분! Time zone 관련된 에러가 발생하는 경우
DB의 주소 뒤에 ?serverTimezone=UTC
을 붙여 주시기 바랍니다^__^다른 분들은 고생하지 않으셨으면 합니다.
mysql 버전 8버전 이상이신분들
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> 참고 윗 버전 디펜던시 추가
Dao 에서 클래스 적으실때 업그레이드 된 클래스 네임 적으셔야합니다
Class.forName("com.mysql.cj.jdbc.Driver");
또 JDBCExam1 에서 서버 타임존 에러 뜨시는 분들은 DAO에서
private static String dbUrl = "jdbc:mysql://localhost:3306/connectdb?serverTimezone=UTC";
로 바꿔보세요
궁금한게 있는데
RoleDao.java -select 소스 final 부분에서
finally {
try {
if(rs != null) rs.close();
if(ps != null) ps.close();
if(conn != null) conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
이런식으로 짜면 문제 있나요?
인텔리제이로는 어떻게 하나요?
오류가 뜬다면 참고 바랍니다... 이틀을 해맸네요...
1. 기본 클래스 JDBCExam1 ... 를 찾을 수 없다 ...
=> 이유가 다양한데 제 경우엔 파일 디렉토리 중에 한글이 포함되어서 그랬습니다. 전부 영어(띄어쓰기는 상관 없음)로 바꿔주고 clean 해주니 해결되었습니다.
2. java.sql.SQLException: Unable to load authentication plugin 'caching_sha2_password'.
만들어둔 계정의 암호 플러그인이 caching_sha2_password(기본값) 이어서 발생합니다. mysql에 root 권한으로 접속 후 다음 코드를 실행하면 됩니다.
mysql -h localhost -u root -p mysql (이후 비밀번호 입력)