포스트

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

MyBatis

resultMap

  • 데이터베이스의 결과 셋을 Java 객체에 매핑할 때 사용한다.
  • sql의 컬럼과 java 객체의 필드값을 매핑 할 수 있다.
  • sql의 join 결과를 java에 리턴 할 수 있다.

association 옵션

  • 객체 간의 1대1 연관 관계를 매핑할 때 사용된다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
     <resultMap id="BoardMap" type="board">
        <id property="no" column="board_id" />
        <result property="title" column="title" />
        <result property="content" column="content" />
        <result property="createdDate" column="created_date" />
        <result property="viewCount" column="view_count" />
      
        <association property="writer" javaType="user">
            <id property="no" column="user_id" />
            <result property="name" column="name" />
        </association>
    </resultMap>
    

    image

collection 으로 join된 객체 삽입하기

  • 1대N 또는 N대N 관계를 매핑할 때 사용된다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    <resultMap id="ProjectMap" type="project">
      <id column="project_id" property="no"/>
      <result column="title" property="title"/>
      <result column="description" property="description"/>
      <result column="start_date" property="startDate"/>
      <result column="end_date" property="endDate"/>
      
      <collection property="members" ofType="user">
        <id column="user_id" property="no"/>
        <result column="name" property="name"/>
      </collection>
    </resultMap>
    

    image

forEach 사용하기

  • mybatis xml에서 반복문을 제어하기 위해 사용하는 문법이다.

    1
    2
    3
    
    <foreach collection="members" item="member" separator=",">
        (#{projectNo}, #{member.no})
    </foreach>
    
  • java에서 members collection객체를 받는다.
  • foreach에서 사용할 변수명을 item에 설정한다.
  • 예제의 결과 user_id가 “,”로 구분되어 담긴다.
  • 해당 결과로 vaule(1,11,12…)와 같이 쿼리문에 전송된다.

typeAliases

  • java 클래스의 전체 이름(패키지 포함)을 짧게 별칭으로 정의하는 문법이다.
  • 두가지 방법으로 Aliases를 설정할 수 있다.

    1
    2
    3
    4
    5
    
    <!--typeAlias로 개별 설정하기-->
    <typeAlias type="bitcamp.myapp.vo.User" alias="user"/>
      
    <!--패키지명으로 설정하기-->
    <package name="bitcamp.myapp.vo"/>
    


annotation

annotation 정의

  • 클래스, 필드, 메서드, 로컬 변수 선언에 붙이는 특별한 주석이다.
  • 다른 주석과 달리 컴파일이나 실행할 때 추출할 수 있다.
  • ‘프로퍼티명=값’ 형태로 값을 다룰 수 있다.

annotation 사용

  • annotation의 사용위치는 다음과 같다.

    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
    
    @MyAnnotation // 클래스 선언에 붙일 수 있다.
    public class Exam0110 {
      
      @MyAnnotation // 필드에 붙일 수 있다.
      static int a;
      
      @MyAnnotation int b; // 필드 선언 바로 앞에 둘 수 있다.
      
      @MyAnnotation // 메서드 선언에 붙일 수 있다.
      void m1(
          @MyAnnotation 
          int p1, // 파라미터(로컬변수)에 붙일 수 있다. 
      
          @MyAnnotation String p2
          ) {
      
        @MyAnnotation int local; // 로컬변수 선언에 붙일 수 있다.
      
        //@MyAnnotation System.out.println("okok"); // 그러나 다른 일반 문장에는 붙일 수 없다.
      
        //@MyAnnotation // 다른 일반 문장에는 붙일 수 없다.
        for (int i = 0; i < 100; i++) {
          @MyAnnotation int a; // 로컬 변수 선언에 붙일 수 있다.
        }
      }
      
      @MyAnnotation  // static, non-static 상관없이 메서드 선언에 붙일 수 있다.
      static void m2() {
      
      }
    }
    
  • 어노테이션의 활용

    • 소스코드에서 주석을 읽어 다른 소스파일을 생성할 수 있다.
    • 컴팡일 할 때 주석을 추출하여 사용할수 있다.
    • 실행 중에 주석을 추출하여 사용할 수 있다.

annotation property 정의

  • 인터페이스에서 메서드 이름은 property(변수)로 작성한다.
  • 사용 할 때는 property를 호출하여 사용한다.

    1
    2
    3
    4
    
    public @interface MyAnnotation2 {
      String value(); // 애노테이션의 기본 프로퍼티이다.
      
    }
    
  • annotation을 사용시 값을 설정 해야한다.
  • default 옵션을 사용하면 값을 설정 하지 않고 사용할 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    public @interface MyAnnotation {
      String value(); 
      // default 값을 지정하지 않으면 필수 프로퍼티가 된다.
      // 즉 애노테이션을 사용할 때 반드시 값을 지정해야 한다.
    }
      
    public @interface MyAnnotation2 {
      String value() default "홍길동";
      // default 값이 있으면,
      // 애노테이션을 사용할 때 값을 지정하지 않아도 된다.
    }
    //@MyAnnotation // 필수 프로퍼티 값을 지정하지 않으면 컴파일 오류!
    @MyAnnotation(value="값") // OK!
      
    @MyAnnotation2 // 애노테이션의 프로퍼티 값을 지정하지 않으면 default 값이 사용된다.
    //@MyAnnotation2(value="물론 이렇게 프로퍼티 값을 지정해도 된다.")
      
      
    


RetentionPolicy

  • CLASS : .class파일 까지는 유지되지만, runtime에서는 메모리에 로딩되지 않는다.
  • SOURCE : 컴파일할때 제거된다. 소스파일에서 어노테이션 값을 추출하여 다른 소스를 생성할때 사용한다.
  • RUNTIME : runtime에 메모리에 로딩된다. 실행 중 어노테이션을 참조해야 할 경우에 많이 사용한다.
  • RetentionPolicy는 annotation을 만들때 설정한다.

    1
    2
    3
    4
    5
    6
    
    import java.lang.annotation.RetentionPolicy;
    //PolicySetting에 설정값을 넣는다.
    @RETENTION(value = RetentionPolicy."PolicySetting")
    public @interface annotationName{
      String value();
    }
    


property

  • property의 value가 하나일때 value를 생략하고 값을 할당 할 수 있다.

    1
    2
    3
    4
    5
    6
    
    public @interface MyAnnotation {
      String value(); // 필수 프로퍼티 
    }
      
    @MyAnnotation(value = "값") // OK
    @MyAnnotation("값2")        // OK
    
  • property가 여러개 일 경우 키와 값을 정확하게 명시해야한다.
  • 순서는 상관없다.

    1
    2
    3
    4
    5
    6
    7
    
    public @interface MyAnnotation3 {
      String value(); // 필수 프로퍼티
      String tel(); // 필수 프로퍼티
    }
      
    @Myannotation3(value="값",tel="tel") //OK
    @Myannotation3(tel="tel",value="값") //OK
    


property 추출

property 값 추출

  • annotation을 설정한다.

    1
    2
    3
    4
    5
    6
    
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation {
      String v1() default "가나다";
      int v2() default 100;
      float v3() default 3.14f;
    }
    
  • annotation을 사용할 class를 만들고 property를 설정한다.
  • annotation에 default 설정이 되어있다면 설정을 하지 않아도 된다.

    1
    2
    3
    
    @MyAnnotation
    public class MyClass {
    }
    
  • 클래스를 동적으로 호출하여 property값을 추출한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    public class Exam01 {
      
      public static void main(String[] args) {
        Class<?> clazz = MyClass.class;
        MyAnnotation obj = clazz.getAnnotation(MyAnnotation.class);
      
        System.out.println(obj.v1());  // 가나다
        System.out.println(obj.v2());  // 100
        System.out.println(obj.v3());  // 3.14
      
      }
    }
    

배열 property 추출

  • 배열도 동일하게 추출을 하지만, property의 리턴값이 배열이다.

    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation3 {
      //    String[] v1() default {"가나다"};
      //    int[] v2() default {100};
      //    float[] v3() default {3.14f};
      
      // 배열 값이 한 개일 경우 중괄호를 생략할 수 있다.
      String[] v1() default "가나다";
      int[] v2() default 100;
      float[] v3() default 3.14f;
    }
    //---------------------------------------------------------------------//
    @MyAnnotation3(
        // 배열 값을 지정할 때 중괄호를 사용한다.
        v1 = {"홍길동", "임꺽정", "유관순"},
        v2 = {1000, 2000, 3000, 4000, 5000},
        v3 = {1.12f, 2.23f, 3, 34f})
    public class MyClass4 {
    }
    //---------------------------------------------------------------------//
    public class Exam04 {
      
      public static void main(String[] args) {
        Class<?> clazz = MyClass4.class;
        MyAnnotation3 obj = clazz.getAnnotation(MyAnnotation3.class);
      
        printValues(obj.v1());
        System.out.println("----------------------");
      
        printValues(obj.v2());
        System.out.println("----------------------");
      
        printValues(obj.v3());
      }
      
      static void printValues(String[] values) {
        for (String value : values) {
          System.out.print(value + ",");
        }
        System.out.println();
      }
      
      static void printValues(int[] values) {
        for (int value : values) {
          System.out.print(value + ",");
        }
        System.out.println();
      }
      
      static void printValues(float[] values) {
        for (float value : values) {
          System.out.print(value + ",");
        }
        System.out.println();
      }
    }
    //---------------------------------------------------------------------//
    //        홍길동,임꺽정,유관순,
    //        ----------------------
    //        1000,2000,3000,4000,5000,
    //        ----------------------
    //        1.12,2.23,3.0,34.0,
      
      
    


target

  • @Target을 사용하여 애노테이션을 붙일 수 있는 범위를 제어할 수 있다.
  • @Target(value = {ElementType.TYPE}) // 클래스나 인터페이스 선언에만 붙일 수 있다.
  • @Target(value = ElementType.TYPE) // 한 개의 값만 설정할 경우 중괄호 생략 가능하다.
  • @Target(ElementType.TYPE) // 프로퍼티 이름이 ‘value’일 경우 이름 생략 가능하다
  • TargetType은 TYPE, FIELD, METHOD, LOCAL_VARIABLE, PARAMETER 등이 있다.

    1
    2
    3
    
    @Target(ElementType."TargetType") 
    public @interface MyAnnotation {
    }
    


TYPE

  • class, interface, enum에 붙일 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    // TYPE 타입(인터페이스와 클래스)에만 붙일 수 있다.
    @MyAnnotation // OK!
    public class MyClass {
      
      //  @MyAnnotation
      // int i; // 컴파일 오류!
      
      //  @MyAnnotation
      // public void m(/*@MyAnnotation*/ int p) { 컴파일 오류!
        /*@MyAnnotation 
        int a;  컴파일 오류!*/
      }
      
    }
    


FIELD

  • 필드 타입에만 가능하다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    // TYPE 타입(인터페이스와 클래스)에만 붙일 수 있다.
    @MyAnnotation // OK!
    public class MyClass {
      
      //  @MyAnnotation
      // int i; // 컴파일 오류!
      
      //  @MyAnnotation
      // public void m(/*@MyAnnotation*/ int p) { 컴파일 오류!
        /*@MyAnnotation 
        int a;  컴파일 오류!*/
      }
      
    }
    


METHOD

  • 메서드 타입만 가능하다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    // @MyAnnotation3는 메서드에만 붙일 수 있다.
    //@MyAnnotation3
    public class MyClass3 {
      
      /*@MyAnnotation3*/ int i;
      /*@MyAnnotation3*/ static int i2;
      
      
      @MyAnnotation3
      public void m(/*@MyAnnotation3*/ int p) {
        /*@MyAnnotation3*/ int a;
      }
      
    }
    


LOCAL_VARIABLE

  • 지역변수만 사용 가능하다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    // @MyAnnotation4는 로컬 변수에만 붙일 수 있다.
    //@MyAnnotation4
    public class MyClass4 {
      
      /*@MyAnnotation4*/ int i;
      /*@MyAnnotation4*/ static int i2;
      
      
      //@MyAnnotation4
      public void m(/*@MyAnnotation4*/ int p) {
        @MyAnnotation4 int a;
      }
      
    }
    


PARAMETER

  • 매개만 사용 가능하다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    // @MyAnnotation5는 로컬 변수, 파라미터, 필드에만 붙일 수 있다.
    /*@MyAnnotation5*/
    public class MyClass5 {
      
      /* @MyAnnotation5*/ int i;
      /* @MyAnnotation5*/ static int i2;
      
      
      /* @MyAnnotation5*/
      public void m(@MyAnnotation5 int p) {
        /* @MyAnnotation5*/ int a;
      }
      
    }
    



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