땅지원
땅지원's Personal blog
땅지원
전체 방문자
오늘
어제
  • 전체 (353)
    • Frontend (2)
      • React (2)
    • Backend (90)
      • Java (16)
      • Python (19)
      • Spring (23)
      • Database (21)
      • Troubleshooting (8)
    • DevOps (27)
      • ELK (13)
    • CS (40)
    • OS (2)
      • Linux (2)
    • Algorithm (95)
      • concept (18)
      • Algorithm Problem (77)
    • 인공지능 (25)
      • 인공지능 (12)
      • 연구노트 (13)
    • 수업정리 (35)
      • 임베디드 시스템 (10)
      • 데이터통신 (17)
      • Linux (8)
    • 한국정보통신학회 (5)
      • 학술대회 (4)
      • 논문지 (1)
    • 수상기록 (8)
      • 수상기록 (6)
      • 특허 (2)
    • 삼성 청년 SW 아카데미 (6)
    • 42seoul (12)
    • Toy project (3)
    • 땅's 낙서장 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • 20.11.6 BB21플러스 온라인 학술대회
  • 20.10.30 한국정보통신학회 온라인 학술대회

인기 글

태그

  • 이것이 리눅스다 with Rocky Linux9
  • D
  • ㅗ
  • I
  • E

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
땅지원

땅지원's Personal blog

JDBC 프로그래밍
Backend/Java

JDBC 프로그래밍

2022. 9. 14. 12:48

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
    'Backend/Java' 카테고리의 다른 글
    • JSP Programming
    • Servlet Programming
    • Java8
    • Java 순열과 조합
    땅지원
    땅지원
    신입 개발자의 우당탕탕 기술 블로그

    티스토리툴바