JDBC(Java Database Connectivity)
데이터베이스에 연결하여 검색하고 변경할 수 있게 하는 표준 API
자바 프로그램에서 서로다른 DBMS라도 같은 방법으로 접근 가능
<JDBC 드라이버 다운로드>
www.oracle.com/database/technologies/jdbcdriver-ucpdownloads.html
<설치 방법>
1. [java 설치 디렉터리\jre\lib\ext]에 복사하는 방법
2. 시스템 변수에 CLASS_PATH를 생성. 드라이버가 있는 경로를 CLASS_PATH의 값으로 지정
3. 프로젝트이름에서 팝업:[File|Properties|Java Build Path|Libraries|AddExt. Jars] 설정
** 사실 실무에서는 JDBC를 쓰지않고 MyBatis라는 프레임워크를 이용하여 편리하게 Java - DB를 연결해서 사용한다
JDK와 JRE에 대해서
설치방법 1에 따르면 jre\lib\ext에 JDBC 드라이버를 복사해야하지만 2019년 6월 이후로 jre가 더 이상 나오지 않음.
최신버전 java를 사용하기위해 java SE 15를 다운받았으며 이는 jre가 안에 내장되어있다.
따라서 드라이버를 추가해야하려면 설치방법 3과 같은 방법으로 프로젝트 라이브러리에 드라이버를 추가해주는 것이
더욱 용이한 방법
<JDBC 프로그래밍 단계>
단계 1 : JDBC 드라이버 적재
jdbc.drivers 환경변수 이용하는 방법
ORACLE : System.setProperty("jdbc.drivers", "oralce.jdbc.OracleDriver");
MariaDB : System.setProperty("jdbc.drivers", "com.mariadb.jdbcDriver");
Class.forName( ) 메서드 이용하는 방법
ORACLE : Class.forName("oralce.jdbc.OracleDriver");
MariaDB : Class.forName("com.mariadb.jdbcDriver");
단계2 : 데이터베이스 연결
DriverManager클래스의 getConnection( )메서드 이용
메서드 인자 : 접속url, id, password
String url = "jdbc:oracle:thin:@localhost:1521:XE";
String id = "hmart";
String password = "1234";
con = DriverManager.getConnection(url, id, password);
String url = "jdbc:mysql://IP주소:3306/db이름";
String id = "hmart";
String password = "1234";
con = DriverManager.getConnection(url, id, password);
단계 3, 4 : Statement 생성 + SQL 전송
Statement클래스 : SQL문을 수행할 수 있도록 해주는 클래스
executeQuery( ) : SELECT문사용. 반환값이 ResultSet
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select * from 고객");
executeUpdate( ) : 변경연산에 사용. 반환값은 int(처리된 데이터 수)
String query = "update 고객 set 적립금 = 6000 where 고객이름 = '정소화' ";
Statement stmt = con.createStatement();
int count = stmt.executeUpdate(query);
<Statement의 단점 및 극복방법>
질의 구성이 복잡
컴파일 타임에는 오류를 발견할 수 없음
SQL을 실행할 때마다 질의를 해석하는 오버헤드가 있음
PreparedStatement (Statement로 부터 상속)
파라미터 개념 도입
‒ 질의문은 미리 컴파일. 속도 향상
질의문 구성이 쉬움
CallableStatement (PreparedStatement로 부터 상속)
저장 프로시저 실행 가능(속도, 소스코드의 독립성, 보안성
단계 5 : 검색 결과 받기
executeQuery의 결과 : ResultSet rs
ResultSet : 튜플의 집합체
rs : 커서(포인터)
단계 6 : 리소스 해제
stmt.close();
pstmt.close();
rs.close();
con.close();
<DBUtil.java>
package com.ssafy.ws.step3.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DBUtil {
private final String driver ="com.mysql.cj.jdbc.Driver";
private final String url="jdbc:mysql://localhost:3306/ssafyweb?serverTimezone=Asia/Seoul"; //jdbc:dbprotocol://host:port/database이름"
private final String user="root";
private final String password="1234";
private static DBUtil instance = new DBUtil();
//singleton pattern
private DBUtil() {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
System.out.println("Driver Load 실패!! ");
}
}
public static DBUtil getInstance() {
return instance;
}
public Connection getConncetion() throws SQLException {
return DriverManager.getConnection(url, user, password);
}
public void close(Statement stmt, Connection conn) {
try {
if(stmt != null) stmt.close();
if(conn != null) conn.close();
} catch (SQLException e) {
System.out.println("자원 반납 실패!!");
}
}
public void close(ResultSet result, Statement stmt, Connection conn) {
try {
if(result != null) result.close();
if(stmt != null) stmt.close();
if(conn != null) conn.close();
} catch (SQLException e) {
System.out.println("자원 반납 실패!!");
}
}
// public void close(AutoCloseable...autoCloseables) {
// for(AutoCloseable c: autoCloseables) {
// if(c != null) {
// try {
// c.close();
// } catch (Exception e) {
// System.out.println("자원 반납 실패!!");
// }
// }
// }
// }
}
<BookDaoImpl.java> - MVC패턴으로 DBUtil.java를 적용
package com.ssafy.ws.step3.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.ssafy.ws.step3.dto.Book;
import com.ssafy.ws.step3.util.DBUtil;
public class BookDaoImpl implements BookDao {
private static BookDao instance= new BookDaoImpl();
private DBUtil db = DBUtil.getInstance();
private BookDaoImpl() {
}
public static BookDao getInstance() {
return instance;
}
@Override
public int insert(Book book) throws SQLException {
Connection conn=null;
PreparedStatement stmt=null;
String sql="INSERT INTO Book(isbn, title, author, price, `desc`) VALUES (?,?,?,?,? )";
conn = db.getConncetion();
stmt = conn.prepareStatement(sql);
stmt.setString(1, book.getIsbn());
stmt.setString(2, book.getTitle());
stmt.setString(3, book.getAuthor());
stmt.setInt(4, book.getPrice());
stmt.setString(5, book.getDesc());
int row = stmt.executeUpdate();
db.close(stmt, conn);
return row;
}
@Override
public List<Book> select() throws SQLException {
Connection conn=null;
PreparedStatement stmt=null;
ResultSet result=null;
String sql="SELECT isbn, title, author, price, `desc` FROM book";
List<Book> books = new ArrayList<Book>();
conn = db.getConncetion();
stmt = conn.prepareStatement(sql);
result = stmt.executeQuery();
while (result.next()) {
books.add(new Book(
result.getString("isbn"),
result.getString("title"),
result.getString("author"),
result.getInt("price"),
result.getString("desc")
)
);
}
return books;
}
public static void main(String [] args) throws SQLException {
BookDao dao = BookDaoImpl.getInstance();
dao.insert(new Book("999-999", "WebProgramming","ssafy",20000,"Web Programming"));
List<Book> books = dao.select();
for(Book book: books)
System.out.println(book);
}
}
* 이렇게 column명이나 숫자로 쓰는거 가능
result.getString("isbn"),
result.getString("title"),
result.getString("author"),
result.getInt("price"),
result.getString("desc")
result.getString(1),
result.getString(2),
result.getString(3),
result.getInt(4),
result.getString(5)
* 백쿼터 왜써줌? mysql에서 desc는 string이 아닌 text라는 특별한 거라서
String sql="INSERT INTO Book(isbn, title, author, price, `desc`) VALUES (?,?,?,?,? )";
<추가>
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
public class JDBCBasic {
private static String driver = "com.mysql.jdbc.Driver";
private static String url = "jdbc:mysql://127.0.0.1:3306/ssafydb";
private static String user = "root";
private static String password = "1234";
private static ArrayList<Department> deptList = new ArrayList<Department>();
public static void main(String arg[]) throws Exception {
// 1. Driver load - Class.forname("MySQL Driver이름");
Class.forName(driver);
// 2. DB 연결 - DriverMager.getConnection(url,id,password)
Connection conn = DriverManager.getConnection(url, user, password);
// 3. Query 실행 - Statement stmt = conn.createStatement();
// PreparedStatement pstmt = conn.prepareStatement(sql);
// execute(), executeUpdate(), executeQuery()
Statement stmt = conn.createStatement();
String sql = "select department_id, department_name from departments where department_id<100";
String deptName = "Administrator";
int deptId = 10;
String sqlUpdate = "Update departments set department_name=? where department_id=?";
PreparedStatement pstmt = conn.prepareStatement(sqlUpdate);
pstmt.setString(1, deptName);
pstmt.setInt(2, deptId);
pstmt.executeUpdate();
// 4. Query 결과 처리 - ResultSet result = pstmt.executeQuery();
// ResultSet result = stmt.executeQuery(query);
ResultSet result = stmt.executeQuery(sql);
while (result.next()) {
deptList.add(new Department(
result.getInt(1),
result.getString(2)
));
}
// 5. DB 연결 종료 - result.close(), pstmt.close(), conn.close()
if (result != null) result.close();
if (stmt != null) stmt.close();
if (conn != null) conn.close();
for(Department dept:deptList)
System.out.println(dept);
}
}
일괄갱신
JAVA 안에서 AutoCommit이 되지만 효율적으로 하기 위해
con.setAutoCommit(false)을 해주고 나중에 한번에 com.commit()을 해주기도 한다.
'Backend > Java' 카테고리의 다른 글
JSP Programming (0) | 2022.09.16 |
---|---|
Servlet Programming (0) | 2022.09.16 |
Java8 (0) | 2022.08.05 |
Java 순열과 조합 (0) | 2022.08.04 |
Java 코딩테스트를 위한 문법 (0) | 2022.08.02 |