5주차 12/27 화요일

하이·2022년 12월 27일
0

수업

목록 보기
9/41
post-custom-banner

JDBC(Java Database Community)

: class + interface
java로 database연결하려면 이런 class를 사용하세요
=> classs를 여러개 제공, 가장 대표적인게 Driver class

java- jdk-11.0.17에
mysql 폴더 만들고, - mysql-connector-j.jar 옮기기

  • 문제점
    이렇게 여러개의 database에 접속방식/사용방식 이 각각 상이함
    => Java 쪽에서 공통 interface작성 제공
    => database vendor 제공

  • java program -> JDBC(interface -> driver class) - mysql



1. JDBC Driver Loading 단계

(2가지 방식이 있는데 , 하나만 기억하면 됨)

package jdbc;

public class Main {
	public static void main(String[] args) {
		
		
		
		try {
			//1. JDBC Driver Loading 단계
			Class.forName("com.mysql.cj.jdbc.Driver");
			System.out.println("Driver Loading 성공!");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		
	}
}



2. Database에 연결(connection)

network를 통해 접속
-> IP(MySQL이 설치된 컴퓨터의 IP)
-> port : 3306
-> protocoal : JDBC
-> 사용하려는 Database : library

package jdbc;

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

public class Main {
	public static void main(String[] args) {
		
		
		
		try {
			// 1. JDBC Driver Loading 단계
			Class.forName("com.mysql.cj.jdbc.Driver");
			System.out.println("Driver Loading 성공!");
			String jdbc_url = "jdbc:mysql://127.0.0.1:3306/library?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true";
			String id = "root";
			String pw = "test1234";
			
			// 2. Database접속
			Connection con = DriverManager.getConnection(jdbc_url, id, pw);	//drivermanager 라는 class가 가지는 getconnection기능을 (jdbc url, id,pw)로 연결
			System.out.println("데이터베이스 접속 성공 !!");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		
	}
}

연결이 성공하면 connection 객체가 생성됨



3. Statement 생성

statement가 필요 - statement를 conneciton을 이용해서 생성
① 일반 statement(기본)
prepared Statement (주로 사용)
③ callable Statement (stored procedure 호출)

// 3. Statement 생성
Statement stmt = con.createStatement();


4. SQL문장을 Statement를 이용해서 실행

실행할 때 executeQuery()->select 계열
executeUpdate()->insert, delete, update

// 4.Query를 작성해서 실행시킬거에요
String sql ="select bisbn, btitle, bauthor, bprice from book";
stmt.executeQuery(sql);


5. 결과 처리

만약 SQL문장이 select이면 리턴값을 ResultSet 객체가 나옴
=> Cursor

  • rs.next() 는 아래로
// 5. 결과처리
rs.next();
String title = rs.getString("btitle");
System.out.println("책 제목은 : " +title);



// 4.Query를 작성해서 실행시킬거에요
String sql ="SELECT bisbn, btitle, bauthor, bprice FROM book WHERE btitle LIKE '%여행%'";
ResultSet rs = stmt.executeQuery(sql);
			
// 5. 결과처리
while(rs.next()) {
String title = rs.getString("btitle");
System.out.println("책 제목은 : " +title);
}



			// 3. Statement 생성
			Statement stmt = con.createStatement();

			// 4.Query를 작성해서 실행시킬거에요
			String keyword ="자바";
			String sql ="SELECT bisbn, btitle, bauthor, bprice FROM book WHERE btitle LIKE '%" + keyword + "%'";
			ResultSet rs = stmt.executeQuery(sql);
			
			// PreparedStatement로 사용해야 함
			// PreparedStatement는 SQL을 가지고 생성함 !
			
			// 5. 결과처리
			while(rs.next()) {
			String title = rs.getString("btitle");
			System.out.println("책 제목은 : " +title);
			}

여기서 잠깐 !

statement 사용이 너무 불편! (+ 속도도 느림)
=> Prepared Statement를 사용 -> 코드 변경이 필요
=> 속도가 빠르고, IN Parameter사용으로 구현도 용이 !!

// PreparedStatement로 사용해야 함
// PreparedStatement는 SQL을 가지고 생성함 !
// PreparedStatement는 IN Parameter를 이용할 수 있음 => ?로 표현 !
// 주의할 점,Keyword 부분에는 ?(IN Parameter)를 쓸 수 없
String keyword = "자바";
String sql = "SELECT bisbn, btitle, bauthor, bprice FROM book WHERE btitle LIKE ?";
PreparedStatement pstmt = con.prepareStatement(sql);
// 실행하기 전에 ? 를 채워야 함 !
pstmt.setString(1, "%" + keyword +"%");
			
ResultSet rs = pstmt.executeQuery();
			



6. 사용한 자원 해제

connection -> Prepared Statement -> ResultSet

rs.close()
pstmt.close()
con.close()

pstmt.close()
con.close()


DeleteExam.java

package jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class DeleteExam {
	public static void main(String[] args) {
		// 특정 책을 지우기
		try {
			//1. 드라이버 로딩
			Class.forName("com.mysql.cj.jdbc.Driver");
			String jdbc_url = "jdbc:mysql://127.0.0.1:3306/library?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true";
			String id ="root";
			String pw ="test1234";
			Connection con = DriverManager.getConnection(jdbc_url, id, pw);
			
			// 3.
			String sql = "DELETE FROM where btitle LIKE ?";
			PreparedStatement pstmt = con.prepareStatement(sql);			
			pstmt.setString(1, "%여행%");		// 첫번째 ?에 들어가는 내용
			
			// 4. 실행
			int count = pstmt.executeUpdate();
			// 앗, 리턴값은 정수값이 옴
			// 영향을 받은 row의 수
			
			// 5. 결과처리
			System.out.println("삭제한 row의 수는 : " + count);
			
			// 6. 사용한 자원 반납
			pstmt.close();
			con.close();
					
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

만약 사용한 SQL이 insert/ update/delete 라면 transaction처리를 해줘야함
JDBC에서 Transaction 설정을 Connection 해야함

코드%사진



DO(Domain Object)

VO(Value Object) : 한개 혹은 두개이상 속성을 묶어서 값을 표현하는 객체
도메인이 가진 전체 필드가 아닌, 프로그램에서 필요한 몇몇 속성을 가짐
DO의 서브셋(?)
<-> DO는 모든 데이터 전체를 표현하기 위해 만듦

DTO(Data Transfer Object) : 저렇게 만든 VO를 데이터를 ~하기 위해서 전달하기 위함
primary key 존재

Entity

Domain

: 개발해야하는 문제. 로직+데이터



학사정보통합시스템

  • 학생정보/교수정보/학과정보/과목정보
  • 홍길동/20살/무역학과/010-0000-0000
    => 하나의 instance로..
    class 안에는 이름/나이/학과/전화번호

도메인에 대한 클래스를 만들고

VO

: 객체를 지칭하는 용어
-> class가 있어야함
: class Book



Scanner(Java.util)

(문자열)입력을 쉽게 받을 수 있도록 도와주는 class
-> keyword 입력을 받고, 책을 검색해서 "책 제목, 저자, 가격" 을 출력하시오.(비싼 책부터 출력)

BookSearchCmd2.java

public class BookSearchCmd2 {

	public static void main(String[] args) {
		
		Scanner s = new Scanner(System.in);
		String input = s.nextLine();
		
		try {
			// 1. JDBC Driver Loading 단계
			Class.forName("com.mysql.cj.jdbc.Driver");
			String jdbc_url = "jdbc:mysql://127.0.0.1:3306/library?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true";
			String id = "root";
			String pw = "test1234";
			// 2. Database 접속
			Connection con = DriverManager.getConnection(jdbc_url, id, pw); 
			
			StringBuffer sql = new StringBuffer();
			sql.append("SELECT bisbn, btitle, bauthor, bprice ");
			sql.append("FROM book ");
			sql.append("WHERE btitle like ?");
			sql.append("ORDER BY bprice DESC");

			PreparedStatement pstmt = con.prepareStatement(sql.toString());
			// 실행하기 전에.. ? 를 채워야 해요!
			pstmt.setString(1, "%" + input + "%");
			
			ResultSet rs = pstmt.executeQuery();
			
			ArrayList<Book> list = new ArrayList<Book>();
			
			// 5. 결과처리!
			while(rs.next()) {
				Book book = new Book(rs.getString("bisbn"),
						rs.getString("btitle"),
						rs.getString("bauthor"),
						rs.getInt("bprice"));
				list.add(book);
			}
			
			for(Book book: list) {
				System.out.println(book);
			}
			
			// 6. 사용한 자원 해제.
			rs.close();
			pstmt.close();
			con.close();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

Book.java

package jdbc.vo;

// VO는 데이터를 표현하는 객체
// 값을 저장하고 표현하는 객체로 비즈니스 로직이 들어올 수 없음
// Database의 Table을 참조해서 만들어요
public class Book {
	
	private String bisbn;
	private String btitle;
	private String bauthor;
	private int    bprice;
	
	public Book() {
		
	}

	
	public Book(String bisbn, String btitle, String bauthor, int bprice) {
		super();
		this.bisbn = bisbn;
		this.btitle = btitle;
		this.bauthor = bauthor;
		this.bprice = bprice;
	}


	public String getBisbn() {
		return bisbn;
	}

	public void setBisbn(String bisbn) {
		this.bisbn = bisbn;
	}

	public String getBauthor() {
		return bauthor;
	}

	public void setBauthor(String bauthor) {
		this.bauthor = bauthor;
	}

	public String getBtitle() {
		return btitle;
	}

	public void setBtitle(String btitle) {
		this.btitle = btitle;
	}


	public int getBprice() {
		return bprice;
	}

	public void setBprice(int bprice) {
		this.bprice = bprice;
	}

	@Override
	public String toString() {
		return bisbn + "," + btitle + "," + bauthor + "," + bprice; 
	}


}


SqlTest2.java

package jdbc;

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 jdbc.vo.Department;

public class SqlTest2 {
	public static void main(String[] args) {
		// JDBC를 이용해서 DB에서 데이터를 추출해서 출력
		
		
		try { 
			// 1.Driver Loading
			Class.forName("com.mysql.cj.jdbc.Driver");
			
			//2. DB 연결
			String jdbc_url = "jdbc:mysql://127.0.0.1:3306/mysql_test_db?characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true";
			String id = "root";
			String pw = "test1234";
			try {
				Connection con = DriverManager.getConnection(jdbc_url, id, pw);
				
				// 3. 실행할 SQL문장을 가지고 있는 Statement를 생성해요!
				StringBuffer sql = new StringBuffer();
				sql.append("SELECT category, department_name, capacity ");
				sql.append("FROM tb_department ");
				sql.append("WHERE category = '공학' and capacity between 20 and 30 ");
				sql.append("ORDER BY department_name ASC");

				PreparedStatement pstmt = con.prepareStatement(sql.toString());
				
				// 4. 실행!
				ResultSet rs = pstmt.executeQuery();
				
				// 5-1. arraylist, while, for
				ArrayList<Department> list = new ArrayList<Department>();
				
				// 5. 결과처리
				
				while(rs.next()) {
				// 여기까지하고, instance를 담기 위한 class인 VO를 만든다 Department
				Department dept = new Department(rs.getString("department_name"),
						rs.getString("category"),
						rs.getInt("capacity"));
					// arraylist에 추가해요
					list.add(dept);
				}
				
				for(Department d : list) {
					System.out.println(d.getDepartment_name());
				}
				
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

Department.java

: VO

package jdbc.vo;

public class Department {

	// VO는 필요한 것만 넣어도 됨
	private String category;
	private String department_name;
	private int capacity;
	
	public Department() {
		// TODO Auto-generated constructor stub
	}
	
	
	
	public Department(String category, String department_name, int capacity) {
		super();
		this.category = category;
		this.department_name = department_name;
		this.capacity = capacity;
	}



	public String getCategory() {
		return category;
	}
	public void setCategory(String category) {
		this.category = category;
	}
	public String getDepartment_name() {
		return department_name;
	}
	public void setDepartment_name(String department_name) {
		this.department_name = department_name;
	}
	public int getCapacity() {
		return capacity;
	}
	public void setCapacity(int capacity) {
		this.capacity = capacity;
	}
}


profile
기록의 즐거움 😆💻
post-custom-banner

0개의 댓글