190610_DAY41 <기존 인메모리 코드에 DB연결 실습 및 연습>


package j0610;

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

public class JDBCTest
{
    //채시라 기억!
    Connection conn;
    Statement stmt;
    //----------------DML업무(insert,delete,update)

    ResultSet rs;//--->조회된 결과 행열을 저장하는 클래스!!
    //----------------DQL업무(select)

    public JDBCTest()
    {
try
{
    //        --JDBC연습--
    //    [1]드라이버 로딩 ( 제품군 선택)
    //        Class.forName("패키지명.클래스명");
            Class.forName("oracle.jdbc.driver.OracleDriver"); // ojdbc6.jar에 존재

    //    [2]Connection연결객체 생성
    //        conn = DriverManager.getConnection("url", "user", "password");
            conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "scott", "tiger");
            System.out.println("db연결 성공");
//            conn.setAutoCommit(false); 


    //    [3]Statement 실행객체 생성 ==> DML, DQL 요청
            stmt = conn.createStatement();
    /*
     * drop table emp3;
     * create table emp3
     * as select * from emp;
     * 
     * 문제1) 사원테이블(emp3)에 정보를 등록하시오.
     * ===> 7000, 홍길동, 2000, 10
     * ===> 7002, 길라임, 3000, 20
     * ===> 7004, 김주원, 4000, 30
     * 
     */

//        sql문 작성
            String sql = "insert into emp3(empno, ename, sal, deptno) values(7000, '홍길동', 2000, 10)";

            // sql문 실행(요청)!! --> execute()메소드 사용!
            // 만약 DML을 실행하고 싶다!! --> int stmt.executeUpdate(sql);
            // ===> 수정, 삭제된 행의 갯수 리턴!
            // 만약 DQL을 실행하고 싶다!! --> ResultSet stmt.executeQuery(sql);
            // ===> 조회된 행열데이터 저장

//            stmt.executeUpdate(sql); // 실행(요청) 시점! (프로그램내에서는 AutoCommit발생)

            //AutoCommit하고 싶지 않다면 수정을 해야 한다.
                        //[2]번의 conn 밑에 conn.setAutoCommit(false); 
            //기본값 : conn.setAutoCommit(false); 
            //프로그램내에서 DML에 대한 AutoCommit

            sql="insert into emp3 (empno, ename, sal, deptno) values "
                    + "(7002, '길라임', 3000, 20)";
//            stmt.executeUpdate(sql);//실행(요청) 시점!!

            sql="insert into emp3 (empno, ename, sal, deptno) values "
                                + "(7004, '김주원', 4000, 30)";
//            stmt.executeUpdate(sql);//실행(요청) 시점!!

            System.out.println("입력성공!");
            conn.commit();
//            conn.rollback();


            //문제2) 길라임 사원을 삭제
            sql = "delete from emp3 where ename = '길라임'";
            int t = stmt.executeUpdate(sql); //실행요청 --> DBMS에게 SQL문 전달
            System.out.println("DB삭제 성공! = >? " + t);

            //문제3) 김주원 사원을 10번 부서로 이동
            sql = "update emp3 set deptno = 10 where ename = '김주원'";
            //sql = "update emp3 set deptno = 10 where ename IN ('김주원', '홍길동')"; 심심해서 IN 써본...거
            int y = stmt.executeUpdate(sql);
            System.out.println("부서 이동 성공 ! =? " + y);

            //문제4) 전체 사원에 대한 정보(사우너번호, 사원명, 급여, 부서번호) 출력
            //[4] ResultSet객체 생성
            // =======> 순차적으로 1.rs.next(); 2.rs.get자료형(인덱스번호); 또는 rs.get자료형("컬럼명");
            sql = "select empno, ename, sal, deptno from emp3";
            //인덱스 번호        1        2    3        4        

            /*
             *     boolean b = rs.next();
             *     ==> b : 결과행이 있으면 true, 없으면 false
             */

            /*
             * 1. rs.next()    // select count(*) from emp;
             * 2. if(rs.next()){}    //select ename from emp where empno = 7788;
             * 3. while(rs.next()){} // select ename from emp;
             * 세개가 무슨 차이가 있을까?!
             * 1. 몇개인지 알때?
             * 2. 조건 where이 들어갈때?
             * 3. 총 몇행인지 모를때 
             */

            // 실행요청 rs 에는 조회된 행열 덩어리 데이터!
            rs = stmt.executeQuery(sql);

            System.out.println("<<전체 사원 정보>>");

            System.out.println("첫번째행 존재유무: "+ rs.next());//1행
            System.out.println("==> 첫번째 데이터: "+ rs.getInt(1)+", "+ rs.getString(2)
                                +", "+ rs.getInt(3) +", "+ rs.getInt(4));

            while(rs.next()) //2행부터
            {
//                rs.getInt(1) rs.getString(2) rs.getInt(3) rs.getInt(4) 이렇게도 가능하고

                int empno = rs.getInt("empno");
                String ename = rs.getString("ename");
                int sal = rs.getInt("sal");
                int deptno = rs.getInt("deptno");

                System.out.println("사원번호 : " + empno + ", 사원이름 : " + ename + ", 급여 :  " + sal + ", 부서번호 : " + deptno);
            }

            System.out.println("조회된 행 존재유무: "+ rs.next());
            System.out.println("==> 마지막 데이터에서 한번 더 넘어가면? : "+ rs.getInt(1)+", "+ rs.getString(2)
            +", "+ rs.getInt(3) +", "+ rs.getInt(4)); // 에러발생 결과집합을 모두 소모했음
            //행데이터를 얻지 못한 상태에서 rs.getInt(1)할 때 에러 발생!
            //java.sql.SQLException

} catch (ClassNotFoundException e)
{
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (SQLException e)
{
    // TODO Auto-generated catch block
    e.printStackTrace();
}


    }//생성자

    public static void main(String[] args)
    {
        new JDBCTest();
    }

}
  • 이전에 만들었던 이름등록 프로그램에 DB를 연결하자!
//NameMenuTest
package j0610;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class NameMenuTest {
  public static void main(String[] args) throws IOException {
    //반복되는 메뉴출력(화면 뷰처리)
    //번호입력을 위한 read() 또는 readLine() 메인에서 사용  
    //이름입력을 위한 readLine() 메인에서 사용  

   BufferedReader in = new BufferedReader(new InputStreamReader(System.in));       
   NameMenu menu = new NameMenu();

   String no; 
  do {      
    System.out.println("<이름메뉴>");  
    System.out.println("1.추가 2.검색 3.수정 4.삭제 5.종료");  
    System.out.print("번호입력 ==> ");
     no= in.readLine();//no= "1"  "2"   "3"   "4"   "5"

     System.out.println();
     switch(no) {
       case "1": {
                  System.out.print("이름입력: ");
                  String name= in.readLine();
                  menu.add(name);
                 }
                  //메소드호출 : 메소드명( 데이터  );
                 break;
       case "2": menu.search();
                 break;

       case "3": System.out.print("기존이름입력: ");
                 String oldName= in.readLine();

                 System.out.print("변경이름입력: ");
                 String newName= in.readLine();

                 menu.update(oldName, newName);

                 break;
       case "4": System.out.print("삭제이름입력: ");
                 String delName = in.readLine();

                 menu.delete(delName);//메소드명( 데이터 );
     }//switch


     System.out.println();
   }while(!no.equals("5"));//번호에 1,2,3,4번 입력했다면

   System.out.println("-- END --");
 /* 
    <NOT연산자>
     - 부정연산자
     - 부호 '!' 사용
     - 사용:  !(논리데이터)

     예)   !true   ----> false
        !false  ----> true
  */        

  }//main
}
//NameMenu
package j0610;

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

public class NameMenu
{
    Connection conn;
    Statement stmt;
    ResultSet rs;


    public NameMenu()
    {

        try
        {
            Class.forName("oracle.jdbc.driver.OracleDriver");
        } catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }

    }

    public void add(String name)
    {// DB에 이름 저장 Create
        try
        {
            //연결
            conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "scott", "tiger");

            //sql실행(요청)
            stmt = conn.createStatement();
            String sql = "insert into names (name) values ('"+ name + "')";
            System.out.println("추가되는 SQL : " + sql);
            stmt.executeUpdate(sql);
        } catch (SQLException e)
        {
            e.printStackTrace();
        } finally 
        {
            try
            {
                //DB자원 : Connection생성 --> Statement생성 --> ResultSet생성
                //DB자원반환은 역순! rs.close() stmt.close() conn.close()
                if( rs != null ) rs.close();
                if( stmt != null )stmt.close();

                //연결 끊기, 반드시 끊어주어야 한다.
                if( conn != null )conn.close(); // DB는 데이터 공유를 위해 사용!
                //Connection 은 유한개 --> 다른 사람을 위해 사용한 연결객체는 반환!
            } catch (SQLException e)
            {
                e.printStackTrace();
            }
        }
    }// add

    public void search()
    {// 현재 DB내의 이름들 조회 Read
        try
        {
            //연결!
            conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "scott", "tiger");

            System.out.println("#이름목록");
            //sql(조회) 요청
            stmt = conn.createStatement();
            String sql = "select name from names";
            rs = stmt.executeQuery(sql); //조회요청!
            //rs.next() --> rs.get자료형(컬럼인덱스 또는 "컬럼명" 또는 "별명")
            while(rs.next())//조회된 행이 존재한다면
            {
                System.out.println(" " + rs.getString(1));
                //혹은 rs.getString("name");
            }
        } catch (SQLException e)
        {

            e.printStackTrace();
        } finally
        {
            //Connection만 끊어도 충분!
            try
            {
                if(conn != null) conn.close();
            } catch (SQLException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }


        //연결끊기(자원반환)
    }

    public void update(String oldName, String newName)
    {// 배열에 저장된 이름을 변경 Update
        connect();
        try
        {
            //실행객체 생성
            stmt = conn.createStatement();

            //sql실행 요청
            String sql = "update names set name = '" + newName +"' where name = '" +oldName + "'"; 
            stmt.executeUpdate(sql);

        } catch (Exception e)
        {
            // TODO: handle exception
        }finally
        {
            disconnect();            
        }
    }// update

    public void delete(String delName)
    {// 배열에 저장된 이름을 삭제 Delete
        connect();
        try
        {
            //실행객체 생성
            stmt = conn.createStatement();

            //sql실행 요청
            String sql = "delete from names where name = '"+ delName + "'"; 
            stmt.executeUpdate(sql);

        } catch (Exception e)
        {
            // TODO: handle exception
        }finally
        {
        disconnect();
        }
    }// delete

    private void connect()
    {
        try
        {
            conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "scott", "tiger");
        } catch (SQLException e)
        {
            e.printStackTrace();
        }
    }

    private void disconnect()
    {
        try
        {
            if (conn != null) conn.close();
        } catch (SQLException e)
        {
            e.printStackTrace();
        }
    }
}// class NameMenu

<JDBC.>

  1. 드라이버 로딩 (DB제품군 선택)

       Class.forName("클래스명");
       Class.forName("패키지명.드라이버클래스명");
  2. Connection객체 생성( 특정 DB서버 연결)

    Connection conn = DriverManager.getConnection("url정보","user정보","pwd정보");
    
        url : 접속DB서버 ip, port번호, sid
                                      //---- 서비스 id, 데이터베이스명
        user : 접속계정
        pwd  : 접속계정에 대한 비밀번호
  3. Statement객체생성 (execute("sql문") - DB에게 SQL문 전달!!)

      Statement stmt = conn.createStatement();
    
      int i = stmt.executeUpdate("전달하고자 하는 SQL(DML)문");
       // i ---> 수정 또는 삭제된 행의 갯수
    ------------------------- DML업무 ---------------------------------------
    
       ResultSet rs =  stmt.executeQuery("전달하고자 하는 SQL(DQL)문");
       //        rs ----> 조회된 행과 열의 덩어리 데이터(3행 3열, 3행1열,  1행1열) 
  4. ResultSet객체생성( 조회된 행열데이터를 저장)

       ResultSet rs =  stmt.executeQuery("전달하고자 하는 SQL(DQL)문");
         4_1
           boolean b =  rs.next();// 덩어리 데이터 중 맨 위에서 부터 한 행을 얻어오기.
                   b: 가져온 행이 있으면 true
    
            rs.next()는 보통 if 또는 while과 많이  사용!!
              if()는 where절에 primary key 비교      
              while()은 조회된 행의 갯수가 2행 이상이 예상 되어질때
    
         4_2
            rs.get자료형(int 인덱스1~);    rs.get자료형(String 컬럼명,별명);
    
                 예) select empno,         ename,          hiredate   hire  from emp;
              인덱스:         1              2                3
    
               rs.getInt(1);      
               rs.getInt("empno");      
                                 rs.getString(2);
                                 rs.getString("ename");
                                                    rs.getDate(3);
                                                    rs.getDate("hire");      (O)
                                                    rs.getDate("hiredate");  (X)
    
    
```

------------------------- DQL업무 ---------------------------------------


------

- test.properties

```java
# FileName ==> test.properties   
# Expression  ==>  propertyName=propertyValue
#                      variable=data
# Line Delimiter!!

name=gildong
age=13
job=\uD559\uC0DD
  • PropertiesTest.java
package j0610;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;

public class PropertiesTest
{
    public static void main(String[] args)
    {
        //Property : 속성
        Properties pro = new Properties(); // 속성 데이터 (문자열, text)를 담는 클래스

        //데이터 저장(입력)
        //pro.setProperty(String key, String value);
        //key : 저장 또는 검색을 위한 값( 유일한 값 )
        //value : 저장하고자 하는 문자열(text) 데이터.

        pro.setProperty("k1", "길동"); // k1키로 "길동"데이터 저장!
        pro.setProperty("k2", "라임");
        pro.setProperty("k3", "주원");

        pro.setProperty("k3", "유신");

        //데이터 출력 (조회)
        System.out.println("k1에 저장되어있는 데이터는 누구 ?! " + pro.getProperty("k1"));
        System.out.println("k2에 저장되어있는 데이터는 누구 ?! " + pro.getProperty("k2"));
        System.out.println("k3에 저장되어있는 데이터는 누구 ?! " + pro.getProperty("k3")); // 주원이 안나오고 마지막 저장한 유신이 나옴!

        System.out.println("==========================================");
        //만약 키값을 모르는 경우?!

        Enumeration enu = pro.propertyNames();
        //Enumeration : 열거형 인터페이스
        //enu = [k1, k2, k3]

        while(enu.hasMoreElements())
        {
            Object key = enu.nextElement();
            System.out.println(key + " : " + pro.getProperty(key.toString()));
        }

         //test.properties파일로 부터 속성데이터 얻어오기!!
         /*
             <properties파일작성>
             - 형식) 속성이름=속성데이터
             - 구분자)  서로 다른 속성을 라인으로 구분
             - 주의)  '=' 보통 등호 앞과 뒤에 공백을 주지 않는다!!
          */


        System.out.println("==========================================");
        try
        {
            pro.load(new FileReader("src/j0610/test.properties"));
        }catch (IOException e)
        {
            e.printStackTrace();
        }
         System.out.println("이름 : "+ pro.getProperty("name"));
         System.out.println("나이 : "+ pro.getProperty("age"));
         System.out.println("직업 : "+ pro.getProperty("job"));
         System.out.println("etc : "+ pro.getProperty("etc"));

    }
}

<미션2>
==> Person GUI에 JDBC적용하기!!

  1. person패키지의 내용 복사하기

    model.dao

    • Model ===> PersonDAO

      ​ Data(Base), Access, Object => DB전담 클래스!

model.dto

-   Person ===> 그대로 사용 또는 PersonDTO, PersonVO, PersonBean

    ​ DTO = Data Transfer Object

    ​ VO = Value Object


j0610.view

-   InputForm, MainView, UpForm 그대로 사용

com.encore.j0610.control

-   Controller 새로작성
  1. Person 테이블 생성하기

    create table person
    (
        no number constraint person_no_pk primary key,
        name varchar2(15) not null,
        age number not null,
        job varchar2(15) not null
    );
    
    drop sequence person_seq;
    create sequence person_seq
            start with 1
            increment by 1
            nocycle
            nocache; 
            --person.sql
            --이렇게 설정 안하면 2부터 시작된다!

     <컨트롤러의 역할 ★> - 전체 프로그램에 대한 흐름 제어!!
     1. 사용자 요청 분석(예 : 어떤 버튼을 눌렀는지)
     2. 사용자 입력 데이터 얻어오기 ( 예 : 입력폼 또는 수정폼을 통해 입력된 데이터)
     3. ★모델객체 생성(예 : personDAO)
         - 메소드 호출
          - 결과값 (리턴값) 얻기, 저장, 판단
     4. 페이지(뷰) 이동 (예 : 메인(JTable) ---> 입력폼)
    
     선택사항) 유효성 검사 (valid check) <== 사용자가 입력한 데이터에 대한 올바른 데이터인지 아닌지 판단!

Person 사람등록 프로그램 DB연결

Model

  • DAO
package j0610.model.dao;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Properties;

import j0610.model.dto.Person;

public class PersonDAO
{// ★DAO : Data(Base) Access Object
    // 데이터 베이스 전용 객체(DB관련된 일 전담!!)
    // ----> CRUD 작성 (Create, Read, Update, Delete)
    // insert select update delete

    Connection conn;
    Statement stmt;

    // conn.properties파일 ==> DB연결정보 저장!!
    Properties pro;

    public PersonDAO()
    {
        try
        {
            pro = new Properties(); // 속성 무
            pro.load(new FileReader("conn/conn.properties"));// 속성 4개 적재
            Class.forName(pro.getProperty("driver"));

        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }// 생성자

    // public boolean insert(자바빈즈) {}
    public boolean insert(Person p)
    {
        // 또는public void insert(Person p) {}
        connect();

        try
        {
            stmt = conn.createStatement();
            String sql = "insert into person (no,name,age,job) values "
                    // + "(1, '홍길동' , 13 , '학생' )";
                    + "(person_seq.nextval, '" + p.getName() + "' , " + p.getAge() + " , '" + p.getJob() + "' )";
            System.out.println("추가SQL==> " + sql);
            stmt.executeUpdate(sql);// DB에게 입력요청
            return true;
        } catch (SQLException e)
        {
            e.printStackTrace();
        } finally
        {
            disconnect();
        }

        return false;

    }// insert

    // 또는 public boolean update(자바빈즈) {}
    public void update(Person p)
    {
    }
    // 또는 public boolean update(Person p) {}

    // public void delete(프라이머리 키) {}
    public void delete(int no)
    {
    }
    // 또는 public boolean delete(int no) {}

    // public void select(프라이머리 키) {}
    public Person select(int no)
    {// 한 개의 Person정보 얻어오기 --> 수정폼
        return null;
    }

    public ArrayList<Person> selectAll()
    {// 모든 Person 정보 얻어오기
        return null;
    }

    private void connect()
    {
        try
        {
            conn = DriverManager.getConnection(pro.getProperty("url"), pro);
            // pro.getProperty("user"),
            // pro.getProperty("pwd"));

        } catch (SQLException e)
        {
            e.printStackTrace();
        }
    }// connect

    private void disconnect()
    {
        try
        {
            // 연결끊기(DB자원반환)
            if (conn != null)
                conn.close();
        } catch (SQLException e)
        {
            e.printStackTrace();
        }
    }// disconnect

}// PersonDAO
  • DTO
package j0610.model.dto;

public class Person {
   //속성정의
    private int no;
    private String name;
    private int age;
    private String job;

    public Person() {

    }

    public Person(int no, String name, int age, String job) {
        this.no = no;
        this.name = name;
        this.age = age;
        this.job = job;
    }

    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 int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    @Override
    public String toString() {
        return "Person [no=" + no + ", name=" + name + ", age=" + age + ", job=" + job + "]";
    }

//    @Override
//    public String toString() {        
//        return no+": ["+name+","+age+","+job+"]";
//    }
}//class Person

View

뷰는 딱히...

Controller

package j0610.control;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import j0610.model.dao.PersonDAO;
import j0610.model.dto.Person;
import j0610.view.InputForm;
import j0610.view.MainView;
import j0610.view.UpForm;

public class Controller implements ActionListener
{
    /*
     * <컨트롤러의 역할 ★> - 전체 프로그램에 대한 흐름 제어!!
     * 1. 사용자 요청 분석(예 : 어떤 버튼을 눌렀는지)
     * 2. 사용자 입력 데이터 얻어오기 ( 예 : 입력폼 또는 수정폼을 통해 입력된 데이터)
     * 3. ★모델객체 생성(예 : personDAO)
     *     - 메소드 호출
     *     - 결과값 (리턴값) 얻기, 저장, 판단
     * 4. 페이지(뷰) 이동 (예 : 메인(JTable) ---> 입력폼)
     * 
     * 선택사항) 유효성 검사 (valid check) <== 사용자가 입력한 데이터에 대한 올바른 데이터인지 아닌지 판단!
     * 
     */

    //뷰등록
    MainView mainView;
    InputForm form;
    UpForm upForm;

    public Controller()
    {
        mainView = new MainView();
        form = new InputForm();
        upForm = new UpForm();

        eventUp();
    }// 생성자

    private void eventUp() 
    {
        mainView.bt_insert.addActionListener(this);
        mainView.bt_update.addActionListener(this);
        mainView.bt_del.addActionListener(this);
        mainView.bt_exit.addActionListener(this);
          //입력폼
           form.bt_submit.addActionListener(this);
          //수정폼
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        Object ob = e.getSource();//action이벤트를 발생시킨 이벤트 소스의 주소 얻기

         if(ob==mainView.bt_insert) 
        {
             //4.메인뷰 : 입력버튼
             mainView.setVisible(false);
             form.setVisible(true);
        }else if (ob == form.bt_submit) //1. 입력폼 : 입력버튼 ==> 분석 : DB분석 요청
        {
            //2. 입력데이터 얻기
            String name = form.tf_name.getText();
            String age = form.tf_age.getText();
            String job = form.tf_job.getText();

            //세 개의 변수를 p변수로 정의하기( 한개의 변수명으로 정의하기 )
            Person p = new Person(0, name, Integer.parseInt(age), job);

            //3. 모델 객체 생성
            PersonDAO dao = new PersonDAO();
            dao.insert(p);
        }
    }

    public static void main(String[] args)
    {
        new Controller();
    }
}
궁금상자
- DAO, DTO
    DAO : Data Access Object, Database의 data에 접근하기 위한 객체, 
        커넥션은 많이 발생하게 된다 이는 비효율적인 방식인데 ConnectionPool이란 Connection 객체를 미리 만들어 놓고 그것을 쓰는것이 DAO, 
        효율성을 위해 DB에 접속하는 객체를 전용으로 하나만 만들고, 
        모든 페이지(접근)에서 그 객체를 호출해서 사용하는 것, 
        DB를 사용해 데이터를 조회하거나 조작하는 기능을 전담하도록 만든 오브젝트, 
        사용자는 Interface를 DAO에 던지고 DAO는 이 인터페이스를 구현한 객체를 사용자가 편하게 쓰도록 반환.
    ======================================================
    DTO : Data Transfer Object는 Value Object로 바꿔 말할 수 있다. 
        계층 간 데이터 교환을 위한 자바빈즈! , 
        일반적으로는 로직이 없는 순수한 데이터 객체, 
        속성과 그 속성에 접근하기 위한 getter, setter 메소드로만 이루어진 클래스!
궁금상자
- DTO랑 VO랑 같은거라고? Beans와의 차이는?
    자바 빈은 특정 형태의 클래스
    VO는 계층형 구조에서 계층간 값을 전달하기 위해 자바 빈의 형태로 구현한 클래스
    DTO는 한 시스템에서 다른 시스템으로 작업을 처리하는 것

    VO는 특정한 비지니스 값을 담는 객체, 값이 같으면 동일 오브젝트
    VO a = VO(1); Vo b = VO(1); a == b
    DTO는 레이어간의 통신용도로 오가는 객체, 값이 같아도 다른 오브젝트
    DTO a = DTO(1); DTO b = DTO(1); a != b 
    이런 차이가 있다.
    그런데 대부분의 사람들은 같은 개념으로 이야기 한다.

    원래 자바 빈은 컴포넌트처럼 서드파티나, 응용프로그램에서 가져다 쓸 수 있는 개념이었으나, 
    본래의 의미는 없어지고 퍼블릭 생성자와 속성을 갖는 클래스 정도로 바뀜?! POJO와 비슷한 개념이라고 함
궁금상자
- POJO는 또 뭔데...?
    Plain Old Java Object
    어디서는 POJO = Java Bean이라고 하네...
    깡통 빈 클래스를 통해서 생성된 객체!
    어디서도 명쾌하게 답을 알려주진 않지만
    getter setter를 가진 단순한 자바 오브젝트 가 아니라
    getter setter를 가진 단순한 자바 오브젝트 는 POJO 이다가 가장 맞는 설명인듯?!
    EJB를 대체하게 되었다고 한다, 그럼...  EJB는 또 뭐야
궁금상자
- EJB
    서버를 관리하고 프로그램 관련 문제 처리 프로그램?...
    속도는 JSP Beans사용보다 느리지만 안정적인 분산시스템, 공공기관, 금융권 같은 접속자 많은곳에서 사용한다고 한다.
    그런데 복잡하고, 생산성이 떨어짐.

+ Recent posts