[JDBC] DAY 1

윤수인·2023년 12월 21일
0

📒국비학원 [DB]

목록 보기
9/14
post-thumbnail

JDBC :

  • DB <-> JAVA
  • 자바에서 DB를 연동하는 방법

DTO / DAO / VO 차이?

  • DTO (Data Transfer Object)
    DB에 접근한 뒤에 SELECT(가져오거나), INSERT(삽입)하는 값을 넣기 위함 (ex,변수(DB테이블의 컬럼) 저장, getter & setter)

  • DAO (Data Access Object)
    DB접근을 위한 객체
    INSERT(삽입),UPDATE(수정),DELETE(삭제),SELECT(조회)
    ③ DB와 연결할 Connection 설정

  • VO (Value Object)
    ① DTO와 유사함 (VO: Read-Only차이만 있음)
    ② 특정 객체를 만들어서 값을 전달

[Version up!]
JDBC - ibatis -> mybatis -> springDA

-> Type 4형식 배우기

📂 사용설명서 위치

  • C:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib




  • 위 주소랑 같은지 확인 ↑
  • (위에 알집 더블클릭하면 아래 화면 띄워짐) Driver 위치 확인

💻 입력

1. 데이터베이스 연결 [Connection]

  • 드라이버 로드 ClassforName / DB연결 DriverManger.getconnection


📌 Note Code


  • Connection = interface임 : 데이터를 받는 타입
  • Class.forName ("oracle.jdbc.driver.OracleDriver")
    Class라는 클래스 사용
    드라이버 로드 = 자바가 오라클의 사용방법 읽어와야함
    클래스 이름을 문자열로 받아들이고, 인스턴스 생성도 가능하고, 메서드도 호출할 수 있는 등의 동적 움직임 가능
  • db는 사용하고나면 닫아줘야함 close();
  • 마지막 반드시 초기화, dbConn=null;

Test1. DB연결자 만들기

package com.db;

import java.sql.Connection;
import java.sql.DriverManager;

public class DBConn {

	// 연결자를 담을 수 있는 그릇 만들기 = connection
	private static Connection dbConn;

	// 연결자 만들기 - 무조건 try-catch문으로
	// thin : type4 가장 빠른 방법
	public static Connection getConnection() {

		if (dbConn == null) {

			try {
				String url = "jdbc:oracle:thin:@192.168.16.16:1521:xe"; // @localhost : wifi연결할때마다 ip주소 바뀌니까
				String user = "suzi";
				String pwd = "a123";

				// 드라이버 로드 = 자바가 오라클의 사용방법 읽어와야함
				// "oracle.jdbc.driver." 패키지 이름 + OracleDriver 클래스 이름
				Class.forName("oracle.jdbc.driver.OracleDriver");

				dbConn = DriverManager.getConnection(url, user, pwd); // static

			} catch (Exception e) {
				System.out.println(e.toString());
			}

		}

		return dbConn;
	} 
	//db는 사용하고나면 닫아줘야함 => 그 안에 연결되어있는건 쓰레기값으로 변함 
	public static void close() {
		
		if(dbConn!=null) {//연결되어있는거니까
			
			try {
				if(!dbConn.isClosed()) { //dbconn이 닫혀있지않으면
					dbConn.close();
				}
			} catch (Exception e) {
				System.out.println(e.toString());
			}
		}
		
		dbConn = null; //반드시 초기화 : 쓰레기값
		
	}
	
}

Test1. DBConn[클래스]를 사용해서 DB에 연결해보는 예제

  • 데이터베이스 연결을 담당하는 DBConn
package com.dayDB;

import java.sql.Connection;

import com.db.DBConn;

public class Test1 {

	public static void main(String[] args) {

		Connection conn = DBConn.getConnection();
		
		if(conn==null) {
			System.out.println("데이터베이스 연결 실패!");
			System.exit(0);		
			}
		System.out.println("데이터베이스 연결 성공!!");
		System.out.println(conn);
		
		DBConn.close();
	}

}

✨ 출력

데이터베이스 연결 성공!!
oracle.jdbc.driver.T4CConnection@5e4c8041




💻 입력

2. DB연동방법 3가지

Test2. DB연동방법 3가지 과정

DB 연결방법 (3가지 코딩)

    1. DriverManger가 Connection을 생성 -> Test1
    1. Connection이 Statement를 생성 (Statement는 위에 3가지 중 하나)
    1. Statement가 query를 실행 (sql)에 담아놓음

statement

  • sql 구문을 연결해서 실행해주는 인터페이스

statement : 가장 기본 / 대소문자 구분해서 복잡


PreparedStatement : 가장 많이 씀

CallableStatement (plsql - 프로시저를 호출해서 사용함)




📌 Note Code


  • Statement : SQL 쿼리를 실행하는 데 사용되는 인터페이스
  • DML [INSERT / UPDATE / DELETE / MERGE] 가 있지만 , DB연동할때는 MERGE는 안씀.
    : int result = stmt.executeUpdate(sql) executeUpdate 메서드를 쓰고,select할 땐 executeQuery 메서드를 쓴 뒤 ResultSet을 얻어옴

Test2. JDBC를 사용하여 데이터베이스에 연결하고 SQL 쿼리를 실행하는 예제

package com.dayDB;

import java.sql.Connection;
import java.sql.Statement;

import com.db.DBConn;

//sql 구문을 연결해서 실행해주는 인터페이스 
//Statement : 가장 기본 / 대소문자 구분해서 복잡
//PreparedStatement (가장 많이 씀)
//CallableStatement (plsql - 프로시저를 호출해서 사용함)

public class Test2 {

	public static void main(String[] args) {

		Connection conn = DBConn.getConnection(); // 1번 DriverManger가 Connection을 생성
		
		if(conn==null) {
			System.out.println("데이터베이스 연결 실패!");
			System.exit(0);
		}
		
		//DB 연결방법 (3가지 코딩)
		//1. DriverManger가 Connection을 생성 -> Test1
		// 2. Connection이 Statement를 생성 (Statement는 위에 3가지 중 하나)
		// 3. Statement가 query를 실행함

		try {

			Statement stmt = conn.createStatement(); // conn = db까지 찾아가는 연결고리가 있으므로 createStatement()에 넣어줌

			String sql;

			// query는 sql안에 들어있음 / 잘 실행하면 1 , 잘못하면 0
			sql = "insert into score (hak,name,kor,eng,mat) ";
			sql += "values ('111','배수지',70,50,80)";
			
			int result = stmt.executeUpdate(sql); // 0 아니면 1 반환
			
			if(result ==1 ) {
				System.out.println("성공 추가!");
			}
			

		} catch (Exception e) {
			System.out.println(e.toString());
		}
			DBConn.close();
		
	}

}

✨ 출력

성공 추가! 

✅ cmd

  • 이름과 학번 바꿔서 다시 집어넣고 오라클에서 select * from score하면 배수지,유인나 둘다 들어가있음.


  • DB의 INSERT / UPDATE / DELETE 하는 법


💻 입력

3. JDBC를 사용한[Connection]- 학번/과목점수/랭킹 출력 예제

Test3. 사용자한테 값을 받는 class와 DB에 저장하는 query로 나누기

scoreDTO : DTO [Data Transfer Object] : 데이터를 DB에 전달해주는 역할

package com.score6;

public class ScoreDTO { // DTO [Data Transfer Object] : 데이터를 DB에 전달해주는 역할

	
	//사용자한테 5개 데이터 받았는데 어디에가 넣어야할지 모를땐 무조건 DTO!!! => 객체생성해야함 
	
	private String hak;
	private String name;
	private int kor;
	private int eng;
	private int mat;
	
	//집어넣을 땐 위에 5개의 데이터
	//꺼내올 땐 8개의 데이터 
	private int tot;
	private int ave;
	private int rank;
	
	
	
	public String getHak() {
		return hak;
	}
	public void setHak(String hak) {
		this.hak = hak;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getKor() {
		return kor;
	}
	public void setKor(int kor) {
		this.kor = kor;
	}
	public int getEng() {
		return eng;
	}
	public void setEng(int eng) {
		this.eng = eng;
	}
	public int getMat() {
		return mat;
	}
	public void setMat(int mat) {
		this.mat = mat;
	}
	public int getTot() {
		return tot;
	}
	public void setTot(int tot) {
		this.tot = tot;
	}
	public int getAve() {
		return ave;
	}
	public void setAve(int ave) {
		this.ave = ave;
	}
	public int getRank() {
		return rank;
	}
	public void setRank(int rank) {
		this.rank = rank;
	}
	
	
	@Override
		public String toString() {
		
		String str;
		str = String.format("%8s %8s %4d %4d %4d %4d %4d %4d", 
				hak,name,kor,eng,mat,tot,ave,rank);
	
			return str;
		}
}

scoreDAO DAO [Data Access Object] : DB에 연결 /처리

package com.score6;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import com.db.DBConn;

public class ScoreDAO {// DB에 연결 / 처리 클래스 (Data Access Object)

	//추가
	//return 0아님 1 이어야하니까 int
	
	//DAO는 연결시켜주는애니까 그럼 일단 먼저 데이터 내놔(ScoreDTO)~~~
	public int insertData(ScoreDTO dto) {
		
		int result = 0;
		
		//db찾아가야함
		Connection conn = DBConn.getConnection();
		
		//(2) PreparedStatement - interface

		PreparedStatement pstmt = null;
		String sql; //쿼리를 저장할 저장소 sql 필요함
		
		try {
			
			sql = "insert into score (hak,name,kor,eng,mat) ";
			sql += "values (?,?,?,?,?)";
			
			// 2. connection 이 Statement를 만드는거니까
			pstmt = conn.prepareStatement(sql); // conn = db를 미리 찾아가 -> 
			// sql insert문(29,30)을 가지고가서 db에 검사를 맡고 pstmt에 insert문이 들어가있음
				
			
			//(첫번째 물음표, dto에 5개의데이터가있으니까 => 순서대로 (?,?,?,?,?) 안에 들어가게 됨)
			pstmt.setString(1, dto.getHak()); 
			pstmt.setString(2, dto.getName());
			pstmt.setInt(3, dto.getKor());
			pstmt.setInt(4, dto.getEng());
			pstmt.setInt(5, dto.getMat());
			
			result = pstmt.executeUpdate(); // **실제로 DB로 가는 명령어!!!**
			
			pstmt.close(); // 꼭 닫아주기
			
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		
		return result;
	}
	
	
	
	// 수정
	public int updateData(ScoreDTO dto) {

		int result = 0;

		Connection conn = DBConn.getConnection();
		PreparedStatement pstmt = null;
		String sql;

		try {

			sql = "update score set kor=?,eng=?,mat=? "; 
			sql += "where hak=?";//조건문

			pstmt = conn.prepareStatement(sql);

			pstmt.setInt(1, dto.getKor());
			pstmt.setInt(2, dto.getEng());
			pstmt.setInt(3, dto.getMat());
			pstmt.setString(4, dto.getHak());

			result = pstmt.executeUpdate();

		} catch (Exception e) {
			System.out.println(e.toString());
		}
		return result;

	}

	//삭제
	public int deleteData(String hak) {
		
		int result = 0;
		
		Connection conn = DBConn.getConnection();
		PreparedStatement pstmt = null;
		String sql;
		
		try {
			
			sql = "delete score where hak = ? ";
			
			pstmt = conn.prepareStatement(sql);
			
			pstmt.setString(1, hak);

			result = pstmt.executeUpdate();
			
			pstmt.close();
			
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		
		return result;
	}
	
	
	
	//전체 출력 ((동명이인이 나올 수도 있으니까 LIST로 받음)
	public List<ScoreDTO> getList(){
		
		List<ScoreDTO> lists = new ArrayList<ScoreDTO>();
		
		
		Connection conn = DBConn.getConnection();
		PreparedStatement pstmt = null;
		
		//select를 하게 됐을때 select 한 결과(table)를 담는 그릇인 ResultSet (interface) 가 무조건 필요함
		ResultSet rs = null;
				
		String sql;
		
		try {
			
			//select문
			sql =  "select hak,name,kor,eng,mat,";
			sql += "(kor+eng+mat) tot, (kor+eng+mat)/3 ave,";
			sql += "rank() over (order by (kor+eng+mat) desc) rank "; //랭킹
			sql += "from score";
			
			pstmt = conn.prepareStatement(sql);
			
			rs = pstmt.executeQuery(); //select = exexcuteQuery임
			
			while(rs.next()) { //next() : 다음 한칸 내려봤을때 데이터가 있니?
				
				//데이터가 있으면
				ScoreDTO dto = new ScoreDTO();
				
				dto.setHak(rs.getString(1));//1번부터 시작 
				dto.setName(rs.getString("name"));
				dto.setKor(rs.getInt(3));
				dto.setEng(rs.getInt("eng"));
				dto.setMat(rs.getInt(5));
				
				dto.setTot(rs.getInt("tot"));
				dto.setAve(rs.getInt(7));
				dto.setRank(rs.getInt("rank"));
				
				
				lists.add(dto);
				
			}
			rs.close();
			pstmt.close();

		} catch (Exception e) {
			System.out.println(e.toString());
		}

		return lists;

	}

	
	
	
	// 이름검색 (동명이인이 나올 수도 있으니까 LIST로 받음)
	public List<ScoreDTO> searchName(String name) {

		List<ScoreDTO> lists = new ArrayList<ScoreDTO>();

		Connection conn = DBConn.getConnection();
		PreparedStatement pstmt = null;

		// select를 하게 됐을때 select 한 결과(table)를 담는 그릇인 ResultSet (interface) 가 무조건 필요함
		ResultSet rs = null;
				
		String sql;
		
		try {
			
			//select문
			sql =  "select hak,name,kor,eng,mat,";
			sql += "(kor+eng+mat) tot, (kor+eng+mat)/3 ave,";
			sql += "rank() over (order by (kor+eng+mat) desc) rank "; //랭킹
			sql += "from score where name = ?";
			
			pstmt = conn.prepareStatement(sql);
			
			pstmt.setString(1, name);
			
			rs = pstmt.executeQuery(); //select = exexcuteQuery임
			
			while(rs.next()) { // 이름몇개인지 모르니까 while / next() : 다음 한칸 내려봤을때 데이터가 있니?
				
				//데이터가 있으면
				ScoreDTO dto = new ScoreDTO();
				
				dto.setHak(rs.getString(1));//1번부터 시작 
				dto.setName(rs.getString("name"));
				dto.setKor(rs.getInt(3));
				dto.setEng(rs.getInt("eng"));
				dto.setMat(rs.getInt(5));
				
				dto.setTot(rs.getInt("tot"));
				dto.setAve(rs.getInt(7));
				dto.setRank(rs.getInt("rank"));
				
				
				lists.add(dto);
				
			}
			rs.close();
			pstmt.close();

		} catch (Exception e) {
			System.out.println(e.toString());
		}

		return lists;

	}
	
	
	
	//학번검색  (동명이인이 나올 수도 있으니까 LIST로 받음)
		public ScoreDTO searchHak(String hak) { //hak은 똑같은 데이터 없음 - primary key => dto에 담을거고 dto를 반환해주면 됨

			ScoreDTO dto = null; //new 객체생성 - 없을 수도 있으니까 , 필요할때 객체생성하면 됨

			Connection conn = DBConn.getConnection();
			PreparedStatement pstmt = null;

			// select를 하게 됐을때 select 한 결과(table)를 담는 그릇인 ResultSet (interface) 가 무조건 필요함
			ResultSet rs = null;
					
			String sql;
			
			try {
				
				//select문
				sql =  "select hak,name,kor,eng,mat,";
				sql += "(kor+eng+mat) tot, (kor+eng+mat)/3 ave "; //from 앞에 붙으면 안되니까 한칸 띄기
				//sql += "rank() over (order by (kor+eng+mat) desc) rank "; //랭킹 - 어차피 1명이므로 
				sql += "from score where hak = ?";
				
				pstmt = conn.prepareStatement(sql);
				
				pstmt.setString(1, hak);
				
				rs = pstmt.executeQuery(); //select = exexcuteQuery임
				
				if(rs.next()) { // 어차피 하나 = if /  다음 한칸 내려봤을때 데이터가 있니?
					
					// 데이터가 있으면
					dto = new ScoreDTO();

					dto.setHak(rs.getString(1));// 1번부터 시작
					dto.setName(rs.getString("name"));
					dto.setKor(rs.getInt(3));
					dto.setEng(rs.getInt("eng"));
					dto.setMat(rs.getInt(5));

					dto.setTot(rs.getInt("tot"));
					dto.setAve(rs.getInt(7));
				}

				rs.close();
				pstmt.close();

			} catch (Exception e) {
				System.out.println(e.toString());
			}

			return dto;

		}
	}

score : 사용자한테 데이터 5개 받아내는 클래스

package com.score6;

import java.util.Iterator;
import java.util.List;
import java.util.Scanner;

public class Score { //사용자한테 데이터 5개 받아내는 클래스

	ScoreDAO dao = new ScoreDAO();
	
	Scanner sc = new Scanner(System.in);
	
	//입력
	public void insert() {
		
		ScoreDTO dto = new ScoreDTO(); //dto는 실행할때마다 새롭게 만들거니까 안에다가 만들어줘야함
		
		System.out.print("학번?");
		dto.setHak(sc.next());
		
		System.out.print("이름?");
		dto.setName(sc.next());
		
		System.out.print("국어?");
		dto.setKor(sc.nextInt());
		
		System.out.print("영어?");
		dto.setEng(sc.nextInt());
		
		System.out.print("수학?");
		dto.setMat(sc.nextInt());
		
		int result = dao.insertData(dto); //5개의 데이터를 dto를 가지고 dao에 가서 실행 한후 1/0으로 반환
		
		if(result != 0) {
			System.out.println("추가 성공!");
		}else {
			System.out.println("추가 실패!");
		}
	}
	
	
	//수정
	public void update() {
		ScoreDTO dto = new ScoreDTO();
		
		System.out.println("수정할 학번?");
		dto.setHak(sc.next());
		
		System.out.print("국어?");
		dto.setKor(sc.nextInt());
		
		System.out.print("영어?");
		dto.setEng(sc.nextInt());
		
		System.out.print("수학?");
		dto.setMat(sc.nextInt());
		
		int result = dao.updateData(dto);
		
		if(result != 0) {
			System.out.println("수정 성공!");
		}else {
			System.out.println("수정 실패!");
		}
		
	}
	
	
	
	//
	public void delete() {
		
		try {
			
			System.out.print("삭제할 학번?");
			String hak = sc.next();
			
			int result = dao.deleteData(hak);// 학을 넘기면 삭제가 됨

			
			if(result != 0) {
				System.out.println("삭제 성공!");
			}else {
				System.out.println("삭제 실패!");
			}
			
		} catch (Exception e) {
			// TODO: handle exception
		}
		
		
	}

	public void selectAll() {

		List<ScoreDTO> lists = dao.getList();

		Iterator<ScoreDTO> it = lists.iterator();

		while (it.hasNext()) {
			ScoreDTO dto = it.next();
			System.out.println(dto.toString());
		}

	}

	public void searchName() {
		
		System.out.print("검색할 이름?");
		String name = sc.next();
		
		List<ScoreDTO> lists = dao.searchName(name); //name으로 select를 해서 lists로 돌려줌.
		
		Iterator<ScoreDTO> it = lists.iterator();

		while (it.hasNext()) {
			ScoreDTO dto = it.next();
			System.out.println(dto.toString());
		}
	}

	
	public void searchHak() {

		System.out.print("검색할 학번?");
		String hak = sc.next();

		ScoreDTO dto = dao.searchHak(hak); //name으로 select를 해서 lists로 돌려줌.
		
		if (dto != null) { //안에 뭐가있다면
			System.out.println(dto.toString()); //그냥 어차피 하나 나오니까 그거 출력해~
		}
	}
}

scoreMain : 메뉴) 1. 2. 3.

package com.score6;

import java.util.Scanner;

public class ScoreMain {

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		Score ob = new Score();
		
		int ch;
		
		while(true) {
			
			do {
				System.out.print("1.추가 2.수정 3.삭제 4.전체출력 5.이름검색 6.학번검색 7.종료");
				ch = sc.nextInt();
				
			}while(ch<1);
			
			switch (ch) {
			
			case 1:
				ob.insert();
				break;
				
			case 2:
				ob.update();
				break;
				
			case 3:
				ob.delete();
				break;
				
			case 4:
				ob.selectAll();
				break;
				
			case 5:
				ob.searchName();
				break;

			case 6:
				ob.searchHak();
				break;

			case 7:
				System.exit(0);
				break;

			default:
				break;
			}
		}
	}
}

✨ 출력

1.추가 2.종료1
학번?111
이름?suzi
국어?50
영어?60
수학?70
추가 성공!
1.추가 2.종료1
학번?222
이름?inna
국어?60
영어?70
수학?80
추가 성공!
1.추가 2.종료

✅ cmd

  • cmd로 확인해도 잘 나옴 select * from score;
  • 앞에 수정이 있다면 delete score;

profile
어제보다 조금 더 성장하기!

0개의 댓글