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형식 배우기
📂 사용설명서 위치
(위에 알집 더블클릭하면 아래 화면 띄워짐) Driver 위치 확인
📌 Note Code
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
Test2. DB연동방법 3가지 과정
DB 연결방법 (3가지 코딩)
statement
▶ statement : 가장 기본 / 대소문자 구분해서 복잡
▶ PreparedStatement : 가장 많이 씀
▶ CallableStatement (plsql - 프로시저를 호출해서 사용함)
📌 Note Code
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();
}
}
성공 추가!
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.종료