- 터미널 모드에서 커맨드 치는 것
- Thymeleaf (jsp대체/서브 사이드)
- 클라이언트 사이드 렌더링
- back-end가 화면을 그려주는 것(서브 사이드) 렌더링을 대체 하는 것
- 웹 화면과 연결 할 수 있음.
JAVA ←jdbc→ DB (소규모에서 사용 대규모 ㄴㄴ)
- 단순 반복적인 문장이 너무 많음
- 그러나 직관적이고 배우기 쉬움
사용할 데이터베이스에 맞는 드라이버를 제조사 홈페이지에서 다운로드 받아서 설치
https://www.oracle.com/kr/database/technologies/appdev/jdbc-downloads.html
File → Project Structure → Libraries
매 파일마다 jdbc 연결해야 한다.
util - 반복되는 문구
dao - 명령어 db 갔다 와서 결과는 vo에 담김
util에 common 자바 만든 후 입력
package com.kh.jdbc.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class Common { final static String ORACLE_URL = "jdbc:oracle:thin:@localhost:1521:xe"; final static String ORACLE_ID = "SCOTT"; final static String ORACLE_PWD = "TIGER"; final static String ORACLE_DRV = "oracle.jdbc.driver.OracleDriver"; public static Connection getConnection(){ //스태틱 객체 안만들고 바로 쓰겠다 Connection conn = null; //커넥션은 반드시 예외 처리를 해주어야 함 try{ Class.forName(ORACLE_DRV); //오라클 디바이스 드라이버 로딩 conn = DriverManager.getConnection(ORACLE_URL,ORACLE_ID,ORACLE_PWD); //연결 얻기 }catch (Exception e){ e.printStackTrace(); } return conn; } public static void close(Connection conn){ try{ if(conn != null && !conn.isClosed()){//!conn.isClosed() 연결이 끊기지 않았다면 conn.close(); System.out.println("Connection 해제 성공"); } }catch(Exception e){ e.printStackTrace(); } } public static void close(Statement stmt){ try{ if(stmt != null && !stmt.isClosed()){//!conn.isClosed() 연결이 끊기지 않았다면 stmt.close(); System.out.println("Connection 해제 성공"); } }catch(Exception e){ e.printStackTrace(); } } public static void close(ResultSet rSet){ try{ if(rSet != null && !rSet.isClosed()){//!conn.isClosed() 연결이 끊기지 않았다면 rSet.close(); System.out.println("Connection 해제 성공"); } }catch(Exception e){ e.printStackTrace(); } } }
package com.kh.jdbc.vo; //DB에 있는 정보를 퍼와서 객체를 만들어야 함 import java.math.BigDecimal; import java.sql.Date; public class EmpVO { private int no; private String name; private String job; private int mgr; private Date date; private BigDecimal sal; // 더블형 추가 private BigDecimal comm; private int deptNo; public EmpVO(int no, String name, String job, int mgr, Date date, BigDecimal sal, BigDecimal comm, int deptNo) { this.no = no; this.name = name; this.job = job; this.mgr = mgr; this.date = date; this.sal = sal; this.comm = comm; this.deptNo = deptNo; } public int getNo() { return no; } public void setNo(int no) { this.no = no; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } public int getMgr() { return mgr; } public void setMgr(int mgr) { this.mgr = mgr; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public BigDecimal getSal() { return sal; } public void setSal(BigDecimal sal) { this.sal = sal; } public int getDeptNo() { return deptNo; } public void setDeptNo(int deptNo) { this.deptNo = deptNo; } public BigDecimal getComm() { return comm; } public void setComm(BigDecimal comm) { comm = comm; } }
package com.kh.jdbc.dao; import com.kh.jdbc.util.Common; import com.kh.jdbc.vo.EmpVO; import java.math.BigDecimal; import java.math.BigInteger; import java.sql.*; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class EmpDAO { Connection conn = null; //자바와 오라클에 대한 연결 설정 Statement stmt = null; // SQL문을 수행하기 위한 객체 PreparedStatement pStmt = null; //// 더블형 추가 ResultSet rs = null; // statement 동작에 대한 결과로 전달되는 DB의 내용 Scanner sc = new Scanner(System.in); public List<EmpVO> empSelect() { List<EmpVO> list = new ArrayList<>(); try{ conn = Common.getConnection(); stmt = conn.createStatement(); //정적인 SQL에 사용 String sql = "SELECT * FROM EMP"; rs = stmt.executeQuery(sql); //select 문과 같이 여러개의 레코드(행)로 결과가 반환될 때 사용 while(rs.next()){ // 읽을 행이 있으면 참 int no = rs.getInt("EMPNO"); String name = rs.getString("ENAME"); String job = rs.getString("JOB"); int mgr = rs.getInt("MGR"); Date date = rs.getDate("HIREDATE"); BigDecimal sal = rs.getBigDecimal("SAL"); BigDecimal comm = rs.getBigDecimal("COMM"); int deptNo = rs.getInt("DEPTNO"); EmpVO vo = new EmpVO(no, name, job, mgr, date, sal, comm, deptNo); list.add(vo); } Common.close(rs); //연결과 역순으로 해제 Common.close(stmt); Common.close(conn); }catch(Exception e){ e.printStackTrace(); } return list; } public void empSelectPrint(List<EmpVO>list){ for(EmpVO e : list ){ System.out.println("사원번호 : " + e.getNo()); System.out.println("이름 : " + e.getName()); System.out.println("직책 : " + e.getJob()); System.out.println("매니저 : " + e.getMgr()); System.out.println("입사일 : " +e.getDate()); System.out.println("급여 : " + e.getSal()); System.out.println("성과급 : " + e.getComm()); System.out.println("부서번호 : " + e.getDeptNo()); System.out.println("-------------------"); } } public void empInsert(){ System.out.println("사원 정보를 입력 하세요."); System.out.print("사원번호(4자리) : "); int no = sc.nextInt(); System.out.print("이름 : "); String name = sc.next(); System.out.print("직책 : "); String job = sc.next(); System.out.print("매니저(4자리) : "); int mgr = sc.nextInt(); System.out.print("입사일 : "); String date = sc.next(); System.out.print("급여 : "); BigDecimal sal = sc.nextBigDecimal(); System.out.print("성과급 : "); BigDecimal comm = sc.nextBigDecimal(); System.out.print("부서번호 : "); int dept = sc.nextInt(); // String sql = "INSERT INTO EMP(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES(" // + no +", "+"'"+ name +"'"+", "+"'"+ job +"'" +", " // + mgr +", "+"'"+ date +"'" + ", " // + sal +", " + comm + ", " + dept + ")"; String sql = "INSERT INTO EMP(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES("; try{ conn = Common.getConnection(); //stmt = conn.createStatement(); pStmt = conn.prepareStatement(sql); pStmt.setInt(1,no); pStmt.setString(2,name); pStmt.setString(3,job); pStmt.setInt(4,mgr); pStmt.setString(5,date); pStmt.setBigDecimal(6,sal); pStmt.setBigDecimal(7,comm); pStmt.setInt(8,dept); // int ret = stmt.executeUpdate(sql); int ret = pStmt.executeUpdate(); System.out.println("Return : " + ret); }catch(Exception e){ e.printStackTrace(); } Common.close(stmt); Common.close(conn); } public void empUpdate() { System.out.println("변경할 사원의 이름을 입력 하세요 : "); String name = sc.next(); System.out.println("직책 : "); String job = sc.next(); System.out.println("급여 : "); BigDecimal sal = sc.nextBigDecimal(); System.out.println("성과급 : "); BigDecimal comm = sc.nextBigDecimal(); String sql = "UPDATE EMP SET JOB = ?, SAL = ?, COMM = ? WHRER ENAME = ?"; try{ conn = Common.getConnection(); pStmt = conn.prepareStatement(sql); pStmt.setString(1,job); pStmt.setBigDecimal(2,sal); pStmt.setBigDecimal(3,comm); pStmt.setString(4,name); pStmt.executeUpdate(); }catch(Exception e){ e.printStackTrace(); } Common.close(pStmt); Common.close(conn); } public void empDelete(){ System.out.println("삭제할 이름을 입력 하세요 : "); String name = sc.next(); String sql = "DELETE FROM EMP WHERE ENAME = ?"; try{ conn = Common.getConnection(); pStmt = conn.prepareStatement(sql); pStmt.setString(1,name); pStmt.executeUpdate(); }catch (Exception e){ e.printStackTrace(); } Common.close(pStmt); Common.close(conn); }
package com.kh.jdbc; import com.kh.jdbc.dao.EmpDAO; import com.kh.jdbc.vo.EmpVO; import java.util.List; import java.util.Scanner; public class JdbcMain { public static void main(String[] args) { Scanner sc = new Scanner(System.in); EmpDAO dao = new EmpDAO(); while(true){ System.out.println("====== [EMP Table Command] ====== "); System.out.println("메뉴를 선택 하세요 : "); System.out.println("[1]SELECT, [2]INSERT, [3]UPDATE, [4]DELETE, [5]EXIT :"); int sel = sc.nextInt(); switch (sel){ case 1: List<EmpVO> list = dao.empSelect(); dao.empSelectPrint(list); case 2: dao.empInsert(); break; case 3: dao.empUpdate(); case 4: dao.empDelete(); case 5: System.out.println("메뉴를 종료 합니다."); } } } }
import java.sql.;*
Class.forName(“oracle.jdbc.driver.OracleDriver”);
→ java.lang.Class 클래스의 forName 메소드는 문자열 형태로 전달된 클래스를 JVM으로 로드해주 는 기능을 가지고 있으며, Oracle JDBC 드라이버를 지정해 로드하여 DriverManager에 등록이 되도 록 하는 코드 입니다.
JDBC 드라이버를 로딩한 후 데이터베이스에 연결하기 위해 Connection 객체를 사용 할 수 있습니다.
Connection 객체는 데이터베이스에 연결해 작업을 수행 할 수 있도록 도와주는 객체 입니다.
DriverManager 클래스의 getConnection( ) 메소드를 호출하여 사용 합니다.
👉 conn = DriverManager.getConnection(Common.ORACLE_URL, Common.ORACLE_ID, Common.ORACLE_PW);
ORACLE_URL : JDBC 형식 URL
ORACLE_ID : 오라클 사용자 ID
ORACLE_PW : 오라클 사용자 비밀번호
👉 jdbc:oracle:thin:[hostname][:port]:dbname
"jdbc:oracle:thin:@localhost:1521:xe";
xe는 익스프레스 에디션을 의미하며 dbname 입니다.
👉 conn.close();
데이터베이스 연결을 한 후 실제 SQL문을 수행하기 위해서 Statement 객체를 생성 합니다.
데이터베이스 연결에 사용한 conn 객체를 통해 createStatement( ) 메소드를 호출해 Statement 객체를 얻어올 수 있습니다.
👉 Statement stmt = conn.createStatement( );
stmt : 표준 SQL문을 수행하기 위한 Statement 객체 입니다.
👉 stmt.close();
데이터베이스 작업이 완료되면 Statement 객체를 반환할 필요가 있어 close() 메소드를 호출해야 합니다.
Statement 인터페이스를 이용해 데이터베이스와 연동할 경우 연동할 때마다 DBMS에서 다시 SQL문을 컴파일해야 하므로 속도가 느려지는 단점이 있습니다.
이럴 경우 PreparedStatement 인터페이스를 사용하면 SQL문을 미리 컴파일해서 재 사용하므로 Statement 인터페이스보다 훨씬 빨르게 데이터베이스 작업을 수행 할 수 있습니다.
String query = "SELECT * FROM emp WHRER deptno = " + num; Statement stmt = conn.createStatement(); ResultSet rst = stmt.executeQuery(query);
String query = "SELECT * FROM emp WHERE deptno = ?"; PreparedStatement stmt = conn.preparedStatement(); stmt.setInt(10, deptno); ResultSet rst = stmt.executeQuery(query);
String sql = "INSERT INTO EMP(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (?,?,?,?,?,?,?,?)"; try { conn = Common.getConnection(); pstmt = conn.prepareStatement(sql); pstmt.setInt(1, no); pstmt.setString(2, name); pstmt.setString(3, job); pstmt.setInt(4, mgr); pstmt.setString(5, date); pstmt.setInt(6, sal); pstmt.setInt(7, comm); pstmt.setInt(8, dept); pstmt.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } }
VO는 데이터베이스에서 가져온 레코드를 자바 객체로 매핑하는 데 사용됩니다. VO 객체는 데이터베이스 테이블의 각 컬럼에 해당하는 멤버 변수를 갖습니다. VO 객체를 사용하면 데이터베이스에서 가져온 레코드를 객체화하여 다양한 처리를 수행할 수 있습니다.
DAO는 데이터베이스에 접근하여 데이터를 조회하거나 수정하는 데 사용됩니다. DAO는 VO 객체와 데이터베이스 간의 매핑을 담당하며, VO 객체를 이용하여 데이터베이스의 레코드를 조회하거나 수정합니다.
Controller는 모델(Model)과 뷰(View) 사이에서 사용자 입력을 처리하고, 모델에서 전달받은 데이터를 뷰에 전달하는 컴포넌트입니다. 일반적으로 웹 애플리케이션에서는 사용자의 HTTP 요청을 처리하고, 그에 따른 응답을 생성하는 데에 Controller를 사용합니다.
Controller의 역할은 다음과 같습니다.
Connection Pool은 데이터베이스에 접속하는 Connection 객체를 미리 생성하여 풀에 저장해 두는 기술입니다. 이렇게 미리 생성된 Connection 객체를 필요할 때마다 가져와 사용함으로써, 매번 Connection 객체를 생성하고 연결하는 데 드는 시간과 비용을 줄일 수 있습니다. 또한, Connection Pool은 동시에 여러 사용자가 데이터베이스에 접근할 때 발생하는 병목 현상을 해소할 수 있습니다.