Day32
Day32
1.JDBC를 이용해서 MVC패턴을 이해하고 연동할 수 있다.
2.VO,Entity등의 값 전달을 명확하게 이해 할 수 있다.
3.프로그램 개발을 통해 데이터 베이스 테이블의 객체를 연동할 수 있고 활용할 수 있다.
JDBC Driver 와 Oracle Database 구조
jdbc - jdbc coding 절차
driver
등록 -> Dbms
연결 -> statement
생성 -> sql
전송 -> 결과
받기 -> 닫기(close)
1) driver 등록
DriverManager
Class.forName("oracle.jdbc.driver.OracleDriver"); //오라클 드라이버
etc)
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver"); //sql드라이버
Class.forName("org.git.mn.mysql.Driver");
DB연결에 필요한 드라이버들을 Class.forName으로 가져온다.
2) dmbs 연결
해당 드라이버로 부터 Connection instance
를 획득 ( DriverManager -> Connection )
public static Connection
getConnection( String url, String user, String password )throws SQLException
예시)
Connection conn = DriverManager.getConnection ("jdbc:oracle:thin:@localhost:1521:XE","scott","TIGER");
3) statement 생성
Connection instance
로 부터 Statement instance
를 획득
DriverManager -> Connection -> Statement
Statement stmt = conn.createStatement();
Statement를 Connection에 생성
4) sql 전송
Statement method()
를 이용해서 SQL 실행
5) 결과 받기
실행 후 결과를 ResultSet(select)
혹은 int형 변수(DML)
로 받아서 처리 하겠다.
DriverManager -> Connection -> Statement -> ResultSet
// case01) ResultSet(select)
String query = "SELECT ID, LAST_NAME FROM EMP";
ResultSet rs = stmt.executeQuery(query) // ResultSet으로 처리
while(rs.next){
System.out.println(rs.getString("ID") + "/t" + rs.getString(2));
}
// case02 ) DML
String query = "update emp set last_name = 'kim' where id = '10000'";
int res = stmt.executeUpdate(query) //int형 DML로 받아서 처리
6) 닫기
// case 01 ) ResultSet(select)
rs.close()
stmt.close()
conn.close();
// case 02 ) DML
stmt.close()
conn.close();
MVC패턴의 구조 및 설명
- package and class and interface
1)common : JDBCTempl = connection, close, rollback, commit
2)com.vo : MyEmpVo = 사원번호,이름,직업,봉급
3)com.cv : ContandView = 페이지 이동,검증,view : main()
4)com.dao : (interface)MyEmpDao / MyEmpDaoImple = DML 연동
5)com.biz : MyEmpBiz = 로직(연산 등 dao호출)ss
흐름의 순서 : 3 <-> 5 <-> 4 <-> 1
- 💡작업의 순서
[vo 작성 -> controller and view -> biz -> dao -> db]
com.vo.MyEmpVo -> com.cv.ContandView -> com.biz.MyEmpBiz -> com.dao.My.dao
-> common.JDBCTemplate -> db연동
- VO 클래스
package com.vo;
public class MyEmpVO {
private int empno;
private String ename;
private String job;
private double sal;
public MyEmpVO() {
super();
// TODO Auto-generated constructor stub
}
public MyEmpVO(int empno, String ename, String job, double sal) {
super();
this.empno = empno;
this.ename = ename;
this.job = job;
this.sal = sal;
}
public int getEmpno() {
return empno;
}
public void setEmpno(int empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
}
db
테이블을VO
에서 만든다고 생각하면 쉽다.
defualt 생성자 ,field,getter&setter 를 만들어주자.
Controller And View
package com.cv;
import java.util.*;
import com.biz.*;
import com.vo.*;
public class ContandVIew {
static Scanner sc = new Scanner(System.in);
public static int View_Menew(){
StringBuilder sb = new StringBuilder();
sb.append(" 메뉴 \n");
sb.append("1.전체 출력 \n");
sb.append("2.입 력\n");
sb.append("3.수 정\n");
sb.append("4.삭 제\n");
sb.append("5.검 색\n");
sb.append("6.종 료 \n");
System.out.println(sb.toString());
System.out.print("Input no : ");
int no = sc.nextInt();
return no;
}
public static void main(String[] args) {
//View -> controller -> biz -> dao ->db
int no=0;
MyEmpVO vo = null; //null = 필요할 때 마다 생성할 수 있는 유형
List<MyEmpVO> all = null;
do {
no = View_Menew();
switch (no) {
case 1: System.out.println(" 전체 출력 "); // getSelectAll()
all = new MyEmpBiz().getSelectAll();
for(MyEmpVO res : all) {
String str = String.format("%10d %10s %10s %5.1f \n",
res.getEmpno(),res.getEname(),res.getJob(),res.getSal());
System.out.println(str);
}
break;
case 2: System.out.println(" 입력 페이지 ");
System.out.print("input empno : ");
int empno = sc.nextInt();
sc.nextLine();
System.out.print("input ename : ");
String ename = sc.nextLine();
System.out.print("input job : ");
String job = sc.nextLine();
System.out.print("input sal : ");
double sal = sc.nextDouble();
//객체에 담기
vo = new MyEmpVO(empno, ename, job, sal);
//biz로 보내서 결과를 리턴 받는다.
int res = new MyEmpBiz().my_emp_insert(vo);
if (res > 0) {
System.out.println("입력 성공이야.");
}
break;
case 3: System.out.println(" 수정 페이지 ");
System.out.print("input empno : ");
empno = sc.nextInt();
sc.nextLine();
System.out.print("input ename : ");
ename = sc.nextLine();
System.out.print("input job : ");
job = sc.nextLine();
System.out.print("input sal : ");
sal = sc.nextDouble();
vo = new MyEmpVO(empno, null, job, sal);
res = new MyEmpBiz().my_emp_insert(vo);
if (res > 0) {
System.out.println("입력 성공이야.");
}
break;
case 4: System.out.println(" 삭제 페이지 ");
System.out.print("input empno : ");
empno = sc.nextInt();
vo = new MyEmpVO();
vo.setEmpno(empno);
res = new MyEmpBiz().my_emp_insert(vo);
if (res > 0) {
System.out.println("입력 성공이야.");
}
break;
case 5:
System.out.println(" 검색 페이지 ");
System.out.print("input ename : ");
ename = sc.next();
vo = new MyEmpVO();
vo.setEname(ename);
all = new MyEmpBiz().getFindAll(vo);
for(MyEmpVO r : all) {
String str = String.format("%10d %10s %10s %5.1f \n",
r.getEmpno(),r.getEname(),r.getJob(),r.getSal());
System.out.println(str);
}
break;
case 6:
System.out.println("종료");
System.exit(0);
}
}while (no !=6);
}
}
중간자 역할인 controller와 보여주는 view가 한 클래스에 담겨있는 형식
Biz
package com.biz;
import java.sql.Connection;
import java.util.List;
import com.dao.MyEmpDao;
import com.dao.MyEmpDaoImple;
import com.vo.MyEmpVO;
import static common.JDBCTemplate.*;
// 컨트롤러로 부터 1) 검증된 데이터를 받아서 dao로 바로 연결할 건지,
// 2)계산된 클래스를 호출한 후 계산이 끝난 후의 데이터를 dao로 연결할 건지
// 3)아니면 계산된 클래스를 호출한 후 계산이 끝난 후에 컨트롤러에게 리턴할 것인지를 결정한다.
// 만일 1,2 번의 작업을 하게 되면 데이터베이스 연동하는 dao 즉dml,ddl,tcl을 구현하는 클래스의
// 메소드를 호출하기 때문에 connect, close를 구현한다.
public class MyEmpBiz {
public List<MyEmpVO> getSelectAll() {
Connection con = getConnection();
List<MyEmpVO> all = new MyEmpDaoImple(con).getSelectAll();
Close(con);
return all;
}
public int my_emp_insert(MyEmpVO vo) {
Connection con = getConnection();
int r = new MyEmpDaoImple(con).my_emp_insert(vo);
Close(con);
return r;
}
public int my_emp_update(MyEmpVO vo) {
Connection con = getConnection();
int r = new MyEmpDaoImple(con).my_emp_update(vo);
Close(con);
return r;
}
public int my_emp_delete(MyEmpVO vo) {
Connection con = getConnection();
int r = new MyEmpDaoImple(con).my_emp_delete(vo);
Close(con);
return r;
}
public List<MyEmpVO> getFindAll(MyEmpVO vo) {
Connection con = getConnection();
List<MyEmpVO> all = new MyEmpDaoImple(con).getFindAll(vo);
Close(con);
return all;
}
}
Controller와 Dao에게 정보를 주는역할(?)로 생각하자
Dao
package com.dao;
//SQL 쿼리문 사용 , 추상클래스, 상수
public interface MyEmpDao {
public static final String my_emp_selectall = "select * from myemp";
//public static final을 생략하여 사용가능하다.
String my_emp_insert = "insert into myemp values(?,?,?,?)";
//String my_emp_update = "update myemp set job=? ,sal=? where empno=?";
String my_emp_update = "{call GET_UPDATE(?,?,?)}";
String my_emp_delete = "delete from myemp where empno=?";
String my_emp_find = "select * from myemp where ename=?";
}
쿼리문을 DaoImple에게 가져다 주는 인터페이스
DaoImple
package com.dao;
import com.biz.*;
import java.util.*;
import java.sql.*;
import com.vo.*;
import static common.JDBCTemplate.*;
// DML or DDL or TCL
// view <-> controller <-> biz <-> dao
public class MyEmpDaoImple implements MyEmpDao {
private Connection conn;
public MyEmpDaoImple(Connection conn) {
this.conn = conn;
}
public List<MyEmpVO> getSelectAll(){
List<MyEmpVO> all = new ArrayList<>();
MyEmpVO vo = null;
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery(my_emp_selectall);
while(rs.next()) {
vo= new MyEmpVO(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getDouble(4));
all.add(vo);
}
} catch (SQLException e) {
System.out.println("select 쿼리 확인~");
}finally {
Close(rs);
Close(stmt);
}
return all;
}
public int my_emp_insert(MyEmpVO vo) {
int r = 0;
PreparedStatement pstm = null;
try {
pstm = conn.prepareStatement(my_emp_insert);
pstm.setInt(1, vo.getEmpno());
pstm.setString(2, vo.getEname());
pstm.setString(3, vo.getJob());
pstm.setDouble(4, vo.getSal());
r = pstm.executeUpdate();
if(r > 0) {
Commit(conn);
}
}catch (SQLException se) {
RollBack(conn); // catch에 rollback이 반드시 와야한다.
}finally {
Close(pstm); // 반드시 명령문을 닫아줘야한다.
}
return r;
}
public int my_emp_update(MyEmpVO vo) {
int r = 0;
CallableStatement pstm = null;
try {
pstm = conn.prepareCall(my_emp_update);
pstm.setString(1, vo.getJob());
pstm.setDouble(2, vo.getSal());
pstm.setInt(3, vo.getEmpno());;
r = pstm.executeUpdate();
System.out.println(r);
if(r > 0) {
Commit(conn);
}
}catch (SQLException se) {
RollBack(conn); // catch에 rollback이 반드시 와야한다.
}finally {
Close(pstm); // 반드시 명령문을 닫아줘야한다.
}
return r;
}
public int my_emp_delete(MyEmpVO vo) {
int r = 0;
PreparedStatement pstm = null;
try {
pstm = conn.prepareStatement(my_emp_delete);
pstm.setInt(1, vo.getEmpno());
r = pstm.executeUpdate();
if(r > 0) {
Commit(conn);
}
}catch (SQLException se) {
RollBack(conn); // catch에 rollback이 반드시 와야한다.
}finally {
Close(pstm); // 반드시 명령문을 닫아줘야한다.
}
return r;
}
public List<MyEmpVO> getFindAll(MyEmpVO empvo){
List<MyEmpVO> all = new ArrayList<>();
MyEmpVO vo = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
stmt = conn.prepareStatement(my_emp_find);
stmt.setString(1,empvo.getEname());
rs = stmt.executeQuery(my_emp_find);
while(rs.next()) {
vo= new MyEmpVO(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getDouble(4));
all.add(vo);
}
} catch (SQLException e) {
System.out.println("select 쿼리 확인~");
}finally {
Close(rs);
Close(stmt);
}
return all;
}
}
Dao를 implements 상속하여 연동
JDBCTemplate
package common;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
//DB Connection을 리턴 받고 반환하는 등의 기본적인 기능들을 모아둔 Util 클래스
public class JDBCTemplate {
// 1.Connection
public static Connection getConnection() {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Properties pro = new Properties();
pro.put("user", "scott");
pro.put("password", "TIGER");
Connection conn = null;
try {
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:Xe", pro);
conn.setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
// 1-2. DB와 Connet 되었는지 유무를 리턴
public static boolean isConnected(Connection conn) {
boolean validConnection = true;
try {
if (conn == null || conn.isClosed()) {
validConnection = false;
}
} catch (SQLException e) {
e.printStackTrace();
}
return validConnection;
}
// 2.Close _Connection
public static void Close(Connection conn) {
try {
if (isConnected(conn)) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
// 3.Close_statement
public static void Close(Statement stmt) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// 4.Close_ResultSet
public static void Close(ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// 5.RollBack() 트랜잭션 rollback
public static void RollBack(Connection conn) {
if (isConnected(conn)) {
try {
conn.rollback();
System.out.println("[JDBCTemplate.Rollback] : DB Successfully Rollbacked!"); // 테스트용 이런식으로도 사용한다~
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// 6.Commit()
public static void Commit(Connection conn) {
if (isConnected(conn)) {
try {
conn.commit();
System.out.println("[JDBCTemplate.Commit] : DB Successfully Committed!");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
Connection,Close,RollBack,Commit을 사용 db연동의 핵심
Author And Source
이 문제에 관하여(Day32), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jahommer/day32저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)