포스트

Day59 Java프로그래밍 기초(reflect), 실습프로젝트(Mybatis)

Reflection API

클래스로딩

  • 클래스를 동적으로 호출 할 때 필요하다. 주로 라이브러리 개발에 사용된다.
  • 클래스 로딩을 하면 스태틱 변수를 준비하고 스태틱 블록을 실행한다.
  • 객체를 인스턴스 하는 것이 클래스 로딩이며, 레퍼런스(배열 등)을 선언하는 것과는 다르다.
    1
    
      Class.forName("패키지를 포함한 전체 클래스명")
    


중첩클래스로딩

  • 상위 클래스를 로딩하는 것과 종속된 클래스를 로딩하는 것은 별개이다.
  • 상위 클래스가 종속 클래스를 사용하는 것이지 포함하는 것은 아니기 때문이다.
  • 종속 클래스는 상위 클래스의 한 기능을 담당하는 것이다.
  • 종속 클래스는 패키지.상위클래스$종속클래스의 경로로 로딩 가능하다.

클래스 로딩 방법

  • 클래스 로딩방법은 2가지가 있다.
    1
    2
    
      Class clazz1 = Class.forName("fully qualified class name")
      Class clazz2 = classNmae.class;
    
  • forName : 클래스를 로딩 시 스태틱변수 선언과 스태틱필드 실행
  • .class : 클래스 로딩 시 스태틱 미 실행, 실제 클래스 사용시 스태틱변수 선언과 스태틱필드 실행
  • .class를 사용하면 유지보수 측면에서 직접 클래스 명을 바꿔줘야한다.(유지보수에 불리하다.)
    1
    2
    3
    4
    5
    6
    
      // className만 변경하면 클래스 로딩 부분의 수정이 없다.
      String className;
      Class clazz1 = Class.forName(className);
        
      // class가 로딩되는 부분에서 모두 수정해야한다.
      className2.class
    


클래스 정보 추출

클래스 이름

  • getSimplName() : 클래스 이름만 추출
  • getName() : 클래스 전체 이름 추출
  • getCanonicalName() : “.”으로 정규화된 클래스 전체 이름 추출
  • getTypeName() : 클래스 타입을 기분으로 전체 이름 추출
  • 익명클래스의 경우 CanonicalName은 null 이지만 TypeName,Name은 $n으로 표시된다.

    1
    2
    3
    4
    5
    6
    
    class A {}
    Class<?> clazz = Class.forName("com.eomcs.reflect.ex02.Exam0110$A");
    System.out.println(clazz2.getSimpleName()); // A
    System.out.println(clazz2.getName()); // com.eomcs.reflect.ex02.Exam01$A
    System.out.println(clazz2.getCanonicalName()); // com.eomcs.reflect.ex02.Exam01.A
    System.out.println(clazz2.getTypeName()); // com.eomcs.reflect.ex02.Exam01$A
    


배열의 타입 및 값의 타입

  • 배열은 [b 처럼 대괄호로 표현된다.

    1
    2
    3
    4
    5
    
    System.out.println(byte.class.getName());  // byte 타입
    System.out.println(byte[].class.getName()); // byte 배열 타입
    // result
    // byte
    // [B
    
  • 배열의 타입을 구하려면 getComponentType()을 통해 배열의 객체 타입을 받을 수 있다.

    1
    2
    3
    4
    5
    6
    7
    
    System.out.println(Date.class.getName());         
    System.out.println(Date[].class.getName());
    System.out.println(Date[].class.getComponentType().getName());
    // result
    // java.sql.Date
    // [Ljava.sql.Date;
    // java.sql.Date
    


Collection 값의 타입

  • Collection 값의 type을 추출하기 위해서는 값을 꺼내와 클래스 정보를 얻고 이름을 얻으면된다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    public class Test {
      public static void main(String[] args) throws Exception {
        ArrayList<Object> values = new ArrayList<>();
        values.add(100);
        values.add(100L);
        values.add(3.14f);
        values.add(314.55);
        values.add(true);
        values.add('A');
        values.add("Hello");
        values.add(new int[] {100, 200, 300});
        values.add(new String[] {"aaa", "bbb", "ccc"});
      
        for (Object value : values) {
           printTypeInfo(value.getClass());
        }
      }
      
      private static void printTypeInfo(Class<?> type) {
      
        if (type.getName().startsWith("[")) {
          System.out.printf("=> %s[]\n", type.getComponentType().getName());
        } else {
          System.out.printf("=> %s\n", type.getName());
        }
      }
    


수퍼클래스 정보

  • getSuperclass() : 수퍼 클래스의 클래스 정보를 가져온다.

    1
    2
    3
    
    Class<?> superClazz = clazz.getSuperclass();
    System.out.println(superClazz.getName());
    System.out.println(superClazz.getSuperclass().getName());
    


중첩클래스 정보

public 중첩클래스 호출

  • getClasses() : Class.forName으로 호출한 class에 중첩된 class 정보를 리턴한다.
  • public으로 공개된 중첩클래스 및 인터페이스를 가져온다.

    1
    2
    3
    4
    
    Class<?> clazz = Class.forName("com.eomcs.reflect.ex02.Exam0310$A");
      
    // public 으로 공개된 중첩 클래스 및 인터페이스 정보를 가져온다.
    Class<?>[] nestedList = clazz.getClasses();
    


모든 중첩클래스 호출

  • getDeclaredClasses() : 클래스 안에 선언된 모든 클래스 정보를 가져온다.
  • 클래스 안에 선언 메소드에 정의된 로컬 클래스는 대상이 아니다.

    1
    2
    3
    4
    5
    6
    7
    8
    
    Class<?> clazz = Class.forName("com.eomcs.reflect.ex02.Exam0320$A");
      
    // 접근 범위에 상관 없이 모든 중첩 클래스 및 인터페이스 정보를 가져온다.
    // => 메서드 안에 정의된 로컬 클래스는 대상이 아니다.
    Class<?>[] nestedList = clazz.getDeclaredClasses();
    for (Class<?> nested : nestedList) {
      System.out.println(nested.getName());
    }
    


구현인터페이스 정보

  • getInterfaces() : 해당 클래스가 구현한 인터페이스 정보를 가져온다.
  • 구현한 인터페이스의 수퍼 클래스 정보는 가져오지 않는다.

    1
    2
    3
    4
    5
    6
    7
    
    Class<?> clazz = Class.forName("com.eomcs.reflect.ex02.Exam0410$D");
      
    // 해당 클래스가 구현한 인터페이스 정보를 가져온다.
    Class<?>[] list = clazz.getInterfaces();
    for (Class<?> c : list) {
      System.out.println(c.getName());
    }
    


메소드 정보 추출

pulic 메서드

  • getMethods() : 해당 클래스에 선언된 public 메서드 + 상속받은 Public 메서드를 가져온다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    Class<?> clazz = Exam0110.class;
      
        // 클래스에서 메서드 정보를 추출하기
        // => 해당 클래스에 선언된 public 메서드 + 상속 받은 public 메서드
        Method[] list = clazz.getMethods();
        for (Method m : list) {
          System.out.println(m.getName());
        }
      }
      // Object메서드도 가져온다.
    


클래스에 선언한 메서드

  • getDeclaredMethods() : 현재클래스에 정의된 모든 메서드 정보를 가져온다.

    1
    2
    3
    4
    5
    6
    7
    
    Class<?> clazz = Exam0120.class;
      
      // => 현재 클래스에 정의된 모든 메서드
      Method[] list = clazz.getDeclaredMethods();
      for (Method m : list) {
        System.out.println(m.getName());
      }
    


특정 메서드만 추출

  • getMethod(“methodName”) : 현재클래스에서 가용한 public 메서드(상속받은 메서드 포함)중에 methodName의 메서드 정보를 가져온다.
  • getDeclaredMethod(“methodName) : 현재클래스에서 모든 메서드 중에 methodName의 메서드 정보를 가져온다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    Class<?> clazz = Exam0210.class;
      
    // 해당 클래스에 선언된 메서드와 상속 받은 메서드까지 포함하여
    // 파라미터가 없는 "m3" 이름을 가진 public 메서드 추출
    // Method m0 = clazz.getMethod("m3"); // public이 아니기 때문에 못 찾는다.
      
    Method m = clazz.getMethod("m1"); // OK!
    System.out.println(m.getName());
      
    System.out.println(clazz.getMethod("toString").getName());
    System.out.println("----------------------");
      
    // => public 이 아닌 메서드를 찾고 싶다면,
    m = clazz.getDeclaredMethod("m3"); // OK
    System.out.println(m.getName());
      
    // => 단 현재 클래스에 정의된 메서드를 찾는다.
    // => 상속 받은 메서드는 제외한다.
    System.out.println(clazz.getDeclaredMethod("toString")); // 예외 발생!
    // 상속 받은 메서드는 못찾는다.
    


  • 파라미터가 있는 경우 매개변수로 (“methodName”,”parmeterType*“)을 매개변수 순서에 맞춰서 넘겨야 method정보를 가져올 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    
     Class<?> clazz = Exam0220.class;
      
    // 파라미터가 없는 메서드를 찾을 때는 파라미터의 타입 정보를 넘기지 않는다.
    System.out.println(clazz.getMethod("m1").getName());
      
    // 파라미터가 있는 메서드를 찾을 때 그 파라미터의 타입 정보를 넘겨야 한다.
    // 타입정보 = 클래스 정보 = Class 객체
    Class<?> parameterType = String.class;
    Method m = clazz.getMethod("m2", parameterType);
    System.out.println(m.getName());
      
    // 위와 같다.
    Method m2 = clazz.getMethod("m2", String.class);
    System.out.println(m2.getName());
      
    m = clazz.getMethod("m2", Class.forName("java.lang.String"));
    System.out.println(m.getName());
      
    // primitive 타입도 클래스 정보가 있다.
    // int => int.class
    // byte,short,int,long,float,double,boolean,char 는 비록 클래스는 아니지만,
    // 일반 클래스처럼 타입 정보를 꺼낼 수 있도록 "class"라는 스태틱 변수를 제공한다.
    Class<?> intType = int.class;
    Class<?> stringType = String.class;
    m = clazz.getMethod("m3", stringType, intType);
    System.out.println(m.getName());
      
    m = clazz.getMethod("m3", String.class, int.class);
    System.out.println(m.getName());
      
    // 메서드의 파라미터 순서를 지켜야 한다.
    // m = clazz.getMethod("m3", int.class, String.class);
    // System.out.println(m.getName());
      
    System.out.println(clazz.getMethod("m3", String.class, int.class).getName());
    


메서드 호출

  • getMethod를 통해서 method 정보를 추출한다.
  • invoke() 메서드를 통해서 메서드를 동적으로 호출한다.

스태틱메서드 호출

  • invoke(null,parameter*) : 스태틱 메서드는 인스턴스 생성이 필요 없으므로 바로 호출 할 수 있다.\

    1
    2
    3
    
    Class<?> cls = ClassName.class;
    Method m = cls.getMethod("methodName",parameterType*);
    m.invoke(null,parameter*);
    


인스턴스메서드 호출

  • invoke(new Instance(),parameter*) : 인스턴스 메서드는 인스턴스 매개변수가 필요하다.
  • 인스턴스 없이 invoke를 호출하면 NullPointException 에러가 발생한다.
  • 객체를 미리 생성 할 수 도 있고, 매개변수에 직접 생성할 수도 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    Class<?> clazz = Exam0320.class;
      
    // 1) 인스턴스 메서드를 찾아 호출하기
    Method m = clazz.getMethod("minus", int.class, int.class);
      
    // => 인스턴스 메서드를 호출할 때는 반드시 인스턴스 주소를 넘겨야 한다.
    Exam0320 obj = new Exam0320();
    m.invoke(obj, 10, 20); // 리플렉션 API를 사용하여 인스턴스 메서드 호출
      
    // => 인스턴스 메서드를 호출하는 일반적인 방식
    obj.minus(10, 20);
    


메서드 파라미터

  • 파라미터를 new Objec[]{value, value, …}으로 전달 할 수도 있다.

    1
    2
    3
    4
    5
    
    // 파라미터 값을 낱개로 전달하기
    m.invoke(null, "홍길동", 100, 90, 80);
      
    // 파라미터 값을 배열에 담아서 전달할 수 있다.
    m.invoke(null, new Object[] {"홍길동", 100, 100, 100});
    
  • 배열의 파라미터인 경우는 배열에 담아서 전달해야한다.
  • 가변 파라미터의 경우에도 배열에 담아서 전달해야한다.

필드 정보 추출

  • getDeclaredFields() : 현재클래스의 필드정보 추출한다.
  • getDeclaredField(“FeildName”) : 현재클래스에서 FieldName의 필드를 추출한다.
  • fieldName.setAccessible([truefalse]) : 필드의 접근을 동적으로 제어한다.
  • setAccessible(true) : 모든 modifier에 접근가능하다

    필드에 직접적으로 접근하는 것은 객체지향의 개념에 어긋나는 행위이다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
      Class<?> clazz = Car.class;
      
      Field[] fields = clazz.getDeclaredFields();
      for (Field f : fields) {
        System.out.printf("%s:%s\n", f.getName(), f.getType().getName());
      }
      
      
      Constructor<Car> defaultConst = (Constructor<Car>) clazz.getConstructor();
      Car car = defaultConst.newInstance();
      
      // 1) private 필드는 일반적인 방식으로 접근할 수 없다.
      //    car.maker = "비트자동차"; // 컴파일 오류!
      
      // 2) 다음과 같이 Reflection API를 사용하면 private 필드에 접근할 수 있다. 
      Field makerField = clazz.getDeclaredField("maker");
      
      // private modifier로 선언된 필드라 하더라도
      // 다음 메서드를 통해 접근 가능하도록 만들 수 있다.
      makerField.setAccessible(true);
      
      // private 필드에 값 넣기
      // 가능해?
      makerField.set(car, "비트자동차");
    


생성자 정보 추출

생성자 및 파라미터

  • getConstructors() : 생성자의 정보들을 가져온다.
  • getParameterCount() : 메서드의 파라미터 갯수를 카운트 한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    public class Exam01 {
      
      public Exam01() {}
      
      public Exam01(int i) {}
      
      public Exam01(String s, int i) {}
      
      public static void main(String[] args) {
        Class<?> clazz = Exam01.class;
      
        // 생성자 목록 가져오기
        Constructor<?>[] list = clazz.getConstructors();
        for (Constructor<?> c : list) {
          System.out.printf("%s(%d)\n", c.getName(), c.getParameterCount());
        }
      
      }
      
    }
    


생성자 호출

  • 객체를 생성하기 위해서는 클래스호출, 생성자 호출, 인스턴스호출 순으로 이루어진다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    public class Exam03 {
      int value;
      
      public Exam03(int i) {
        this.value = i;
      }
      
      public void print() {
        System.out.printf("value=%d\n", this.value);
      }
      
      public static void main(String[] args) throws Exception {
        Class<?> clazz = Exam03.class;
      
        // newInstance()는 객체를 생성한 후 기본 생성자를 호출한다.
        // Exam03은 기본 생성자가 없기 때문에 실행 오류가 발생한다!
        //    Exam03 obj0 = (Exam03) clazz.newInstance(); // 실행 오류!
      
        // 해결=> 생성자를 준비한다.
        Constructor<?> c = clazz.getConstructor(int.class);
      
        // 생성자 객체를 통해 인스턴스를 생성해야 한다.
        Exam03 obj = (Exam03) c.newInstance(200);
        obj.print();
      }
      
    }
    


타입정보 추출

파라미터 타입

  • getParameters() : 메서드의 파라미터들의 정보를 가져온다.
  • getType() : 파라미터의 타입정보를 가져온다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    Class<?> clazz = Exam0110.class;
      
    // 해당 클래스에 정의된 메서드를 모두 가져온다.
    Method[] methods = clazz.getDeclaredMethods();
    for (Method m : methods) {
      System.out.printf("%s:\n", m.getName());
      
      // 메서드의 파라미터 정보를 가져온다.
      Parameter[] parameters = m.getParameters();
      for (Parameter p : parameters) {
        System.out.printf(" %s : %s\n", p.getName(), p.getType().getName());
      }
    


리턴 타입

  • getReturnType() : 메서드의 리턴 타입정보를 가져온다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    Class<?> clazz = Exam0210.class;
      
    // 클래스에 정의된 메서드를 모두 가져온다.
    Method[] methods = clazz.getDeclaredMethods();
    for (Method m : methods) {
      System.out.printf("%s:\n", m.getName());
        
      // 메서드의 리턴 타입 가져오기
      Class<?> returnType = m.getReturnType();
      System.out.printf("    리턴: %s\n", returnType.getName());
    }
    


제네릭 타입

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  public class Exam0220 {
  
    public String m1(String name, int age) {
      return null;
    }
  
    public char[] m2() {
      return null;
    }
  
    public ArrayList<String> m3(File file, String name) {
      return null;
    }
  
    public void m4() {}
  
    public Map<String,File> m5() {
      return null;
    }
  
    public static void main(String[] ok) {
      Class<?> clazz = Exam0220.class;
  
      // 클래스에 정의된 메서드를 모두 가져온다.
      Method[] methods = clazz.getDeclaredMethods();
      for (Method m : methods) {
        System.out.printf("%s:\n", m.getName());
  
        // 메서드의 제네릭 리턴 타입 가져오기
        Type returnType = m.getGenericReturnType();
        System.out.printf("    리턴: %s\n", returnType.getTypeName());
        if (returnType instanceof ParameterizedType) {
          Type[] actualTypes = ((ParameterizedType) returnType).getActualTypeArguments();
          System.out.print("         => ");
          for (Type actualType : actualTypes) {
            System.out.print(actualType.getTypeName() + ", ");
          }
          System.out.println();
        }
      }
    }
  
  }


modifier 타입 (public, static, protected)

  • public, static, protected에 할당된 비트와 호출한 객체와 비트 연산(&)을 통해 해당 객체의 modifier타입을 추출한다.
  • reflect에 내장된 isModifier()를 통해 modifier타입을 추출한다.
  • 비트 연산자가 속도 측면에서 유리하고 내장함수가 시인성 측면에서 유리하다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    
     public static void main(String[] ok) {
        Class<?> clazz = String.class;
      
        // 클래스에 정의된 메서드를 모두 가져온다.
        Method[] methods = clazz.getDeclaredMethods();
        for (Method m : methods) {
          System.out.printf("%s() => ", m.getName());
      
          int modifiers = m.getModifiers();
      
          System.out
              .println(String.format("%32s", Integer.toBinaryString(modifiers)).replace(' ', '0'));
      
          if (Modifier.isPublic(modifiers)) { // (modifiers & Modifier.PUBLIC) == Modifier.PUBLIC)
            System.out.print(" public");
          } else if ((modifiers & PROTECTED) != 0) {
            System.out.print(" protected");
          } else if ((modifiers & PRIVATE) != 0) {
            System.out.print(" private");
          }
      
      
          // if ((modifiers & STATIC) != 0)
          if (Modifier.isStatic(modifiers)) {
            System.out.print(" static");
          }
      
          if ((modifiers & FINAL) != 0) {
            System.out.print(" final");
          }
      
          System.out.println();
        }
      }
      
    }
    


MyBatis

Persistence Framework

  • SQL Mapper : 개발자가 직접 쿼리문을 만들고 프레임워크에서 결과를 리턴 받는다
  • OR Mapper : 쿼리문을 자동으로 생성해서 결과를 리턴 받는다. image

사용준비

DTD

  • 태그 사용규칙을 담은 문서이다.
  • XML파일을 만들때 해당 규칙을 통해 작성을 해야한다. image

XML(Extensible Markup Language)

  • 데이터를 구조화 시켜 저장하는 파일로 데이터 끼리 상관관계를 표현 할 수 있다.
  • Markup 언어는 <tag> value </tag> tag로 시작해서 끝나는 언어이다.
  • XML은 Markup언어의 사용규칙을 준수하여 만들 파일이다.

    설정파일 준비

  • https://mybatis.org/mybatis-3/ko/getting-started.html 접속
  • xml 파일 만들기 image
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE configuration
              PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
              "https://mybatis.org/dtd/mybatis-3-config.dtd">
      <configuration>
          <!-- DBMS 접속정보 -->
          <properties resource="jdbc.properties"/>
        
          <!-- SQL문 파일 위치 -->
          <environments default="development-local">
        
              <!-- 개발하는 동안 사용할 DBMS 접속 정보 -->
              <environment id="development-local">
                  <transactionManager type="JDBC"/>
                  <dataSource type="POOLED">
                      <property name="driver" value="${jdbc.driver}"/>
                      <property name="url" value="${jdbc.url}"/>
                      <property name="username" value="${jdbc.username}"/>
                      <property name="password" value="${jdbc.password}"/>
                  </dataSource>
              </environment>
        
          </environments>
        
          <mappers>
              <mapper resource="UserDaoMapper.xml"/>
              <mapper resource="BoardDaoMapper.xml"/>
          </mappers>
      </configuration>
    


사용하기

Dao 기능분리

  • 기존 Dao 소스는 java상에서 JDBC를 활용하여 쿼리문을 전송하고 결과를 리턴 받는다.
  • 유지보수 측면에서 Java코드와 SQL쿼리가 혼재되어 불리하다.
  • Mybatis를 사용해서 JDBC API의 역할을 이전하고 소스에서는 자바코드만 작성한다.

    image

SqlSession 객체 생성

  • SqlSession을 인스턴스하기 위해서는 SqlSessionFactory 객체가 필요하다.
  • SqlSessionFactory를 인스턴스하기 위해서는 SqlSessionFactoryBuilder 객체가 필요하다.
  • SqlSessionFactoryBuilder가 xml파일을 읽어 Factory 객체를 인스턴스해야한다.

    image

    1
    2
    3
    4
    
      InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
      SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
      SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
      SqlSession sqlSession = sqlSessionFactory.openSession(false);
    


selectList()

  • java에서는 XML에 태그를 넘기면서 sqlSession의 메서드를 호출한다.
  • 리턴된 List타입을 List객체에 저장한다.

    1
    
      sqlSession.selectList("aaa.sql1");
    
  • java에서 받은 id를 찾아서 쿼리문을 실행한다.
  • 쿼리문을 실행해서 나온 테이블을 resultType에서 받아온 User 객체를 생성하고 담는다.
  • User객체들을 List에 add한고 List를 리턴한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
      <select id="sql1" resultType="bitcamp.myapp.vo.User">
          select
              user_id as no,
              name,
              email
          from
              myapp_users
          order by
              user_id asc
      </select>
    

    image

insert()

  • java에서는 XML에 태그를 넘기면서 sqlSession의 메서드를 호출한다.

    1
    
      sqlSession.insert("aaa.sql2", user);
    
  • java에서 받은 id를 찾아서 쿼리문을 실행한다.
  • 파라미터로 받은 User타입에서 getter메서드를 찾는다.
  • xml에 작성된 #{property}을 getPorperty()으로 변환을 한다.
  • 파라미터로 받은 user에서 user.getProperty()를 하여 sql구문을 완성한다.
  • 완성된 sql구문을 sql서버에 전송한다.

    1
    2
    3
    4
    
      <insert id="slq2" parameterType="bitcamp.myapp.vo.User">
          insert into myapp_users(name, email, pwd, tel)
          values (#{name}, #{email}, sha1(#{password}), #{tel})
      </insert>
    

    image

selectOne()

  • java에서는 XML에 태그를 넘기면서 sqlSession의 메서드를 호출한다.
  • 리턴된 객체 정보를 저장한다.
  • 리턴된 객체는 반드시 1개여야 한다.

    1
    
      sqlSession.selectOne("sql3.findBy", no);
    
  • java에서 받은 parmeter로 sql구문을 실행한다.
  • primitive 타입의 property name은 없기때문 사용자가 임의로 작성 가능하다.
  • sql 서버에서 받은 table의 컬럼 정보로 property name을 생성한다.
  • resultType에서 setProperty(Object obj)를 호출하여 객체에 정보를 넣는다.
  • 완성된 객체를 java에 넘겨준다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
      <select id="sql3" resultType="bitcamp.myapp.vo.User" parameterType="int">
      select
          user_id as no,
          name,
          email,
          tel
      from
          myapp_users
      where
          user_id = #{ok}
      </select>
    

    image

update()

  • java에서는 XML에 태그를 넘기면서 sqlSession의 메서드를 호출한다.

    1
    
    sqlSession.update("UserDao.update", user);
    
  • java에서 user객체를 받는다.
  • user의 property name으로 getProperty() 메서드를 통해 값을 얻어 sql구문을 call한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
      <update id="update" parameterType="user">
        update myapp_users set
          name=#{name},
          email=#{email},
          pwd=sha1(#{password}),
          tel= #{tel}
        where
          user_id=#{no}
      </update>
    

    image

delete()

  • java에서는 XML에 태그를 넘기면서 sqlSession의 메서드를 호출한다.

    1
    
    sqlSession.delete("UserDao.delete", no);
    
  • java에서 받은 parmeter로 sql구문을 실행한다.
  • primitive 타입의 property name은 없기때문 사용자가 임의로 작성 가능하다.

    1
    2
    3
    4
    
    <delete id="delete" parameterType="int">
        delete from myapp_users
        where user_id=#{ok}
    </delete>
    

    image

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.