강의 수강완료
1  DevOps와 CI/CD의 이해 2022.10.26
2 Jenkins를 이용한 CI/CD 자동화 도구 사용  

 

'CICD > Jenkins + CI&CD' 카테고리의 다른 글

Jenkins를 이용한 CI/CD 자동화 도구 사용  (0) 2022.10.26
DevOps와 CI/CD의 이해  (0) 2022.10.18

목차

    JPA는 다양한 쿼리 방법을 지원

    • JPQL (실무에서는 대부분 여기서 해결 됨)
    • JPA Criteria (망한 스펙 절대 안씀)
    • QueryDSL (실무 사용 권장)
    • 네이티브 SQL
    • JDBC API 직접 사용, MyBatis, SpringJdbcTemplate 함께 사용

    JPQL 소개

    • 가장 단순한 조회 방법
      • EntityManager.find()
      • 객체 그래프 탐색(a.getB().getC())
    • JPA를 사용하면 엔티티 객체를 중심으로 개발
    • 문제는 검색 쿼리
    • 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색
    • 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능
    • 애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요

    JPQL 문법

    String jpql = "select m From Member m where m.name like '%hello%'";
    	List<Member> result = em.createQuery(jpql, Member.class).getResultList();
    List<Member> result = em.createQuery("select m From Member m where m.username like '%hello%'"
                Member.class).getResultList();

    JPQL의 문제점(동적 쿼리)

    *동적 쿼리 : 필요에 의해 직접 붙히거나 짜르는 쿼리

    String qlString = "select m From Member m";
    
    String username;
    if(username != null){
    	String where ="where m.username like '%kim%'";
        qlString + where;
    }

    위의 코드의 문제점

    • 복잡하다.
    • 휴먼에러가 발생하기가 쉽다.
      • qlString 과 where 의 문자열이 띄어쓰기가 된 건지 여부까지 체크해줘야한다. (오타는 당연하고)

    QueryDSL 소개

    다음과 같이 작성할 수 있다. 위의 단점을 해결 할 수 있다.

    • 기본 코드
    QMember m = QMember.member;
    List<Member> result = queryFactory
    					  .select(m)
                          .from(m)
                          .where(m.name.like("kim")
                          .fetch();
    • 동적 쿼리 사용 코드
    public List<Order> findAllByQuerydsl(OrderSearch ordersearch){
    	return queryFactory
        	   .select(order)
               .from(order)
               .join(order.member, member)
               .where(statusEq(orderSearch), memberNameEq(orderSerarch))
               .fetch();           
    }
    private BooleanExpression memberNameEq(OrderSearch oderSearch){
    	return hasText(orderSearch.getMemberName()) ? member.name.eq(orderSearch.getMemberName)): null;
    }
    
    private BooleanExpression statusEq(OrderSearch oderSearch){
    	return orderSearch.getMemberName() != null ? order.status.eq(orderSearch.getOrderStatus()):null;
    }

    'Back-end > JPA' 카테고리의 다른 글

    도메인 분석 설계 (N:N 뿌시기)  (0) 2022.11.19
    연관관계 매핑 기초  (0) 2022.08.22
    엔티티 매핑  (0) 2022.08.06
    [JPA] JPA 영속성 컨텍스트  (0) 2022.05.05
    [JPA] Batch Insert  (0) 2022.05.05

    목차

      연관관계 매핑

      객체와 테이블 연관관계 차이를 이해

      객체의 참조와 테이블의 외래 키 매핑

      용어 이해

      • 방향(Direction) : 단방향, 양방향
      • 다중성(Multiplicity) : 다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(N:M) 이해
      • 연관관계의 주인(Owner) : 객체 양방향 연관관계는 관리가 필요(가장 까다로움)

      연관관계가 필요한 이유

      객체지향 설계의 목표는 자율적인 객체들의 협력 공동체를 만드는 것이다.

      예제 시나리오

      • 회원과 팀이 있다.
      • 회원은 하나의 팀에만 소속될 수 있다.
      • 회원과 팀은 다대일 관계이다. (회원은 여러명이고, 팀은 1개이다.)

      객체를 테이블에 맞추어 모델링

      (연관관계가 없는 객체)

      Member는 N이며 TEAM은 1이다.

      @Entity
      public class Member {
      	@Id
      	@Column(name = "MEMBER_ID")
      	private String id;
      	private String username;
      	
      	//연관관계 매핑
      	@ManyToOne
      	@JoinColumn(name="TEAM_ID")
      	private Team team;
      	
      	//연관관계 설정
      	public void setTeam(Team team) {
      		this.team = team;
      	}
      	//Getter, Setter ...
      }
      @Entity
      public class Team {
      	@Id
      	@Column (name = "TEAM_ID")
      	private String id;
      	
      	private String name;
      	//Getter, Setter ...
      }
      Team team = new Team();
      team.setName("TeamA");
      em.persist(team);
      
      //Member
      Member member = new Member();
      member.setUsername("member1");
      member.setTeamId(team.getId()); //여기서 이상함
      em.persist(member);
      
      //문제가 많은 find하기
      Member findMember = em.find(Member.class, member.getId());
      Long findTeamId = findMember.getTeamId();
      Team findTeam = em.find(Team.class, findTeamId);

      위의 코드에서 문제점은 findMember를 memberId로 조회하고 그 조회한 내용 중에 TeamId를 가져와서 Team을 또 조회한다.

      Join으로 협력관계가 있는게 아닌 Select를 두 번 하는 꼴

      객체를 테이블에 맞추어 데이터 중심으로 모델링하면, 협력 관계를 만들 수 없다.

      객체 지향 모델링

      위의 모델링과 다른 점은 TeamId가 아닌 Team을 모델링 했다는 점이다.

      @Entity
      public class Member {
      	@Id
      	@Column(name = "MEMBER_ID")
      	private String id;
      	private String username;
      	
      	//연관관계 매핑
      	@ManyToOne
      	@JoinColumn(name="TEAM_ID")
      	private Team team; //가장 중요
      	
      	//연관관계 설정
      	public void setTeam(Team team) {
      		this.team = team;
      	}
      	//Getter, Setter ...
      }

      @ManyToOne

      Member 입장 에서 N이고 Team이 1이기 때문에 ManyToOne이다. 

      Team team = new Team();
      team.setName("TeamA");
      em.persist(team);
      
      //Member
      Member member = new Member();
      member.setUsername("member1");
      //member.setTeamId(team.getId()); //여기서 이상함
      member.setTeam(team);
      em.persist(member);
      
      //문제가 많은 find하기
      Member findMember = em.find(Member.class, member.getId());
      //Long findTeamId = findMember.getTeamId();
      //Team findTeam = em.find(Team.class, findTeamId);
      Team findTeam = findMember.getTeam();

      위의 findMember는 select 문이 join문으로 알아서 해준다.

      'Back-end > JPA' 카테고리의 다른 글

      도메인 분석 설계 (N:N 뿌시기)  (0) 2022.11.19
      객체지향 쿼리 언어1 - 기본 문법  (0) 2022.09.24
      엔티티 매핑  (0) 2022.08.06
      [JPA] JPA 영속성 컨텍스트  (0) 2022.05.05
      [JPA] Batch Insert  (0) 2022.05.05

      메인으로 가기

      목차

        집약형 아키텍처

        • 대형 컴퓨터를 이용해서 모든 업무 처리 (집중형)
        • 장점
          - 한 대의 대형 컴퓨터만 있으면 되므로 구성이 간단
        • 단점
          - 대형 컴퓨터의 도입 비용과 유지 비용이 비쌈
          - 확장성에 한계

        분할형 아키텍처

        • 여러 대의 컴퓨터를 조합해서 하나의 시스템을 구축
        • 장점
          - 낮은 비용으로 시스템을 구축
        • 단점
          • 대수가 늘어나면 관리 구조 복잡
          • 한 대가 망가지면 영향 범위를 최소하기 위한 구조 검토

        .

        서버란?
        물리서버와 논리 서버로 구성
        컴퓨터 자체(하드웨어)를 가리크는 물리 서버
        컴퓨터에서 동작하고 있는 소프트웨어 논리 서버 (웹서버, DB서버)

        분할형 아키텍처는 역할 분담에 따라 구분

        • 수직 분할형 아키텍처
        • 수평 분할형 아키텍처

        수직 분할형 아키텍처

        • 역할에 따라 위 또는 아래 계층으로 나뉨
        • 2가지 존재
          - 클라이언트-서버형 아키텍처
          - 3계층형 아키텍처

        클라이언트-서버형 아키텍처

        • 서버 1개에서 모든 클라이언트 처리를 접수한다.
        • 클라이언트 측에 전용 소프트웨어를 설치해야 한다.
        • 서버 처리에 집중되면 확장성에 한계 발생
        • 이런 단점을 극복하고자 3계층형 아키텍처가 나옴

        3계층형 아키텍처

        • 클라이언트-서버형을 발전 시킴
        • 프레젠테이션 계층 / 애플리케이션 계층 / 데이터 계층 3층 구조로 분할하여 서버 부하 집중을 개선
        • 스프링의 MVC와 비슷
        • 프레젠테이션 계층 : 사용자의 요청을 받아서 화면에 표시(웹 서버)
        • 애플리케이션 계층 : 무엇을 할지 판단해서 필요한 경우 데이터 계층에 질의 (애플리케이션(AP)서버)
        • 데이터 계층 : 데이터 입출력을 담당한다.(DB서버)

        수평 분활형 아키텍처

        • 수직 분활형 아키텍처를 하나 더 늘려 확장성, 안정성을 향상시키는 것
        • 단순 수평 분할형 아키텍처 & 공유형 아키텍처로 나뉨

        단순 수평 분할형 아키텍처

        • 샤딩 또는 파티셔닝이라고 불린다.
        • 잘 안쓰임 (본사, 동탄 따로 서버쓰는 꼴) -> 공유형 아키텍처
        • 장점
          • 수평으로 서버를 늘리기 때문에 확장성이 향상된다.
          • 분할한 시스템이 독립적으로 운영되므로 서로 영향을 주지 않는다.
        • 단점
          • 데이터를 일원화해서 볼 수 없다.
          • 애플리케이션 업데이트는 양쪽을 동시에 해 주어야 한다.
          • 처리량이 균등하게 분할돼 있지 않으면 서버별 처리량에 치우침이 생긴다.

        공유형 아키텍처

        공유형은 단순형과 달리 일부 계층에서 상호 접속이 이루어진다.

        • 장점
          • 수평으로 서버를 늘리기 때문에 확장성이 향상된다.
          • 분할한 시스템이 서로 다른 시스템의 데이터를 참조할 수 있다.
        • 단점
          • 분할한 시스템 간 독립성이 낮아진다.
          • 공유한 계층의 확장성이 낮아진다.
        아키텍처 트랜드
        오픈화(분산) -> 가상화/클라우드(집중) -> 엣지 컴퓨팅(분산)
        * 엣지 컴퓨팅 : 최신 키워드, 지리적으로 가까운 위치에 있는 서버로 처리하고, 처리 결과만 중앙으로보내는 아키텍처
        엣지 컴퓨팅에서는 관리를 위한 수고를 줄이면서, 서버를 분산하는 것이 중요하다.

        지리 분할에 따른 아키텍처

        • 스탠바이형 아키텍처와 재해 대책형 아키텍처

        스탠바이형 아키텍처

        • 액티브 - 스탠바이로 구성
        • 액티브 측이 고장나면 스탠바이를 이용
        • 단점은 한 쪽이 계속 놀고 있는 상태가 되기 때문에 양쪽 서버로를 교차이용 하는 경우도 많음

        재해 대책형 아키텍처

        • DR (Disater Recovery) 구성으로 재해용 서버를 똑같이 구성함
        • 평상시에는 일반적인 데이터 서버를 이용하고 재해가 발생하였을대 부산 측 시스템을 이용

        'Back-end > Infra' 카테고리의 다른 글

        그림으로 공부하는 IT 인프라 구조  (0) 2022.08.10
        도커란?  (0) 2022.03.13
        그림으로 공부하는 IT 인프라 구조 중에 필요한 부분만 찍먹 해보자.
          공부 일시
        1.1 인프라란 무엇인가? 2022.08.10(수)
           

         

        'Back-end > Infra' 카테고리의 다른 글

        [그림으로 공부하는 IT 인프라 구조] 인프라란 무엇일까?  (0) 2022.08.10
        도커란?  (0) 2022.03.13

        목차

        JPA를 사용하는 데 가장 중요한 일은 엔티티와 테이블을 정확히 매핑하는 것이다.
        • 객체와 테이블 매핑 : @Entity, @Table
        • 기본 키 매핑 : @Id
        • 필드와 컬럼 매핑 : @Column
        • 연관관계 매핑 : @ManyToOne, @JoinColumn

        객체와 테이블 매핑

        @Entity

        • @Entity가 붙은 클래스는 JPA가 관리, 엔티티라 한다.
        • JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 필수이다.
        • 주의
          • 기본 생성자 필수(파라미터가 없는 public 또는 protected 생성자)
          • final 클래스, enum, interface, inner 클래스 --> 사용x
          • 저장할 필드에 final 사용 x

        @Table, enumtype

        • @Table은 엔티티와 매핑할 테이블을 지정한다. 생략하면 매핑한 엔티티 이름을 테이블 이름으로 사용한다.
        • createdDate, lastModifiedDate : 자바의 날짜 타입은 @Temporal을 사용해서 매핑한다.
        • roleType : 자바의 enum을 사용하려면 @Enumerated 어노테이션으로 매핑해야한다.
        • 회원을 설명하는 필드는 길이 제한이 없다. 따라서 데이터 베이스의 VARCHAR 타입 대신 CLOB 타입으로 저장해야 한다. @Lob을 사용하면 CLOB, BLOB 타입을 매핑할 수 있다.
        package jpabook.start; 
        import javax.persistence.*; 
        import java.util.Date; 
        
        @Entity 
        @Table (name="MEMBER") 
        public class Member { 
        	
        	@Id 
        	@Column (name = "ID") 
        	private String id; 
        	
        	@Column (name - "NAME") 
        	private String username; 
        	
        	private Integer age; 
        
        	//== 추가 == 
        	@Enumerated (EnumType. STRING) 
        	private RoleType roleType; // 1
        
        	@Temporal (TemporalType. TIMESTAMP) 
        	private Date createdDate; // 2
        
        	@Temporal (TemporalType. TIMESTAMP)  
        	private Date lastModifiedDate; // 2
         
        	@Lob 
        	private String description; //3
        }
        
        //Getter, Setter 
        package jpabook.start; 
        
        public enum RoleType { 
        	ADMIN, USER
        }

        DDL 생성 기능

        • 제약조건 추가 : 회원 이름 필수, 10자 초과 X
        @Column(nullable = false, length =10)
        • 유니크 제약조건 추가
        @Table(uniqeConstraints = (@UniqueConstraint(name = "NAME_AGE_UNIQUE", columnNames ={"NAME", "AGE"})))
        • DDL 생성 기능은 DDL을 자동 생성할 때만 사용되고 JPA의 실행 로직에는 영향을 주지 않는다.

        @Column

        옵션
        설명
        name 필드와 매핑할 테이블의 컬럼 이름
        insertable, updatable 등록, 변경 가능 여부 (기본 값 : TRUE)
        nullable(DDL) null 가능 여부, false 설정하면 DDL 생성 시에 Not Null 조건이 붙다.
        unique(DDL) @Table의 uniqueConstraints와 같지만 한 컬럼에 간단한 유니크 제약조건을 걸 때 사용한다.
        columnDefinition(DDL) 데이터베이스 컬럼 정보를 직접 줄 수 있다.
        ex) varchar(100) default 'EMPTY'
        length(DDL) 문자 길이 제약 조건, String 타입에만 사용 (기본 값 : 255)
        precision, scale(DDL) 소수의 자릿수 설정 (기본 값 : precision=19)

        @Enumerated

        • 자바 enum 타입을 매핑 할 때 사용
        • 주의 ORDINAL 사용 X
          • EnumType.ORDINAL : enum 순서를 데이터 베이스에 저장
            • enum의 순서대로 0,1,2,3... 저장 된다.(Integer값 저장)
              • 따라서 엄청난 혼란을 줄 수 있다. 예를 들면 ADMIN이 0번 이었는데, GUEST가 0번으로 바뀌면 이전에 저장 되어있던 0번 값(=ADMIN)과 새로 저장된 값 GUEST(=0번 값)이 헷갈리게 된다.
          • EnumType.STRING : enum 이름을 데이터베이스에 저장 (*항상 이렇게 사용)
            • enum 설정 값 이름 그대로를 저장한다.

        @Temporal

        날짜 타입(java.util.Date, java.util.Calendar) 매핑할 때 사용한다.

        • 참고 : LocalDate, LocalDateTime을 사용할 때는 생략 가능(최신 하이버네이트 지원)
        • TemporalType.DATE : 날짜, 데이터베이스, date 타입과 매핑 (예 : 2013-10-11)
        • TemporalType.TIME : 시간, 데이터베이스, time 타입과 매핑 (예 : 11:11:11)
        • TemporalType.TIMESTAMP : 날짜와 시간, 데이터베이스, timestamp 타입과 매핑(예 : 2013-10-11 11:11:11)

        아래와 같이 적으면 어노테이션이 필요없다!

        private LocalDate localDate;
        private LocalDateTime localDateTime;

        @Lob

        데이터베이스 BLOB, CLOB 타입과 매핑

        @Lob에는 지정할 수 있는 속성이 없고, 대신에 매핑하는 필드 타입이 문자면, CLOB으로 매핑하고 나머지는 BLOB로 매핑한다.

        @Transient

        객체 임시로 어떤 값을 넣고 싶을 때 사용하고 데이터베이스에는 반영이 안된다.

        데이터 베이스 스키마 자동 생성

        사실상 운영에선 사용하진 않고, 개인적으로 개발할때 정도 사용한다.
        • DDL을 애플리케이션 실행 시점에 자동 생성
        • 테이블 중심 -> 객체 중심
        • 데이터베이스 방언을 활용해서 데이터베이스에 맞는 적절한 DDL 생성

        xml 다음과 같이 입력하면 초기 실행 시 자동으로 테이블을 생성한다.

        <property name="hibernate.hbm2ddl.auto" value ="create"/>

        위의 value 속성은 개발 단계마다 다르게 생성할 수있다.

        • 개발 초기 단계에는 create 또는 update
        • 테스트 서버는 update 또는 validate(엔티티와 테이블이 정상 매핑되었는지만 확인)
        • 스테이징과 운영서버는 validate 또는 none
        • 운영 장비에는 절대 create, create-drop, update 사용하면 안된다.

        기본 키 매핑

        기본 키 매핑 어노테이션

        • @Id
        • @GeneratedValue
        @Id @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;

        기본 키 매핑 방법

        데이터베이스마다 기본 키를 생성하는 방식이 서로 다르므로 이 문제를 해결하기는 쉽지 않다. JPA는 이런 문제들을 어떻게 해결하는지 알아보자
        • 직접 할당 : @Id만 사용
        • 자동 생성(@GeneratedValue)
          • IDENTITY : 데이터베이스에 위임(DB에 따라서 알아서(임의로) 해줌), MYSQL, PostgreSQL, SQL Server, DB2에서 사용
            • MySQL의 AUTO_INCREMENT
          • SEQUENCE : 데이터베이스 시퀀스 오브젝트 사용, ORACLE
            • @SequenceGenerator 필요
          • TABLE : 키 생성용 테이블 사용, 모든 DB에서 사용
            • @TableGenerator 필요

        기본 키 직접 할당 전략

        @Id 적용 가능 자바 타입

        • 자바 기본형
        • 자바 래퍼wrapper형
        • String
        • java.util.Date
        • java.sql.Date
        • java.math.BigDecimal
        • java.math.BigInteger
        SEQUENCE 전략

        sequenceName 속성의 이름으로 BOARD_SEQ 를 지정했는데 JPA는 이 시퀸스 생성기를 실제 데이터베이스 BOARD_SEQ 시퀀스와 매핑한다. sequenceName을 따로 설정하지 않으면 hibernate_sequence와 같이 자동으로 설정된다.

        @Entity
        @SequenceGenerator(
        	name = "BOARD_SEQ_GENERATOR".
        	sequenceName = ”BOARD_SEQ”, //매핑할 데이터베이스 시퀀스 이름
        	initialvalue = 1, 
        	allocationsize = 1)
        public class Board {
        
        	@IdQGeneratedValue(
        	strategy = GenerationType.SEQUENCE,
        	generator = "BOARD_SEQ_GENERATOR")
        	private Long id;
        	...
        }

        call next value for MEMBER_SEQ란?
        영속성 컨텍스트에 의해 JPA는 항상 PK값을 알아야한다. 그래서 MEMBER_SEQ값에서 id값을 조회한다. 그러고 나서 em.persist를 해준다.

        commit 하는 시점에 insert쿼리가 날라간다.
        SquenceGenerator.allocationSize의 기본값이 50인 이유는 최적화 때문이다 allocationSize 값이 50이면 시퀀스를 한 번에 50 증가 시킨 다음에 1~50까지는 메모리에서 식별자를 할당한다. 이 최적화 방법은 시퀀스 값을 선점 하므로 여러 JVM이 동시에 동작 해도 기본 키 값이 충돌하지 않는 장점이 있다. 반면에 데이터베이스에 직접 접근해서 데이터를 등록할 때 시퀀스 값이 한번에 많이 증가한다는 점을 염두해 두어야 한다. 참고로 앞서 설명한 hibernate.id.new_generator_mappings 속성을 true로 설정해야 지금까지 설명한 최적화 방법이 적용된다.

        TABLE 전략(운영에서 잘 쓰이지 않음)

        TABLE 전략은 키 생성 전용 테이블을 하나 만들고 여기에 이름과 값으로 사용할 컬럼을 만들어 데이터베이스 시퀀스를 흉내내는 전략이다.
        • 장점 : 모든 데이터베이스에 적용 가능
        • 단점 : 성능
        @Entity
        @TableGenerator(
        	name = "BOARD_SEQ_GENERATOR",
        	table = ”MY_SEQUENCES",
        	pkColumnValue = ”BOARD_SEQ”, 
        	allocationsize = 1)
        public class Board {
        	@Id
        	@GeneratedValue(
        		strategy = GenerationType.TABLE,
        		generator = '' BOARD_SEQ_GENERATOR''
        	)
        	private Long id;
        	...
        }
        TABLE 전략과 최적화 TABLE 전략은 값을 조회하면서 SELECT 쿼리를 사용하고 다음 값으로 증가시키기 위해 UPDATE 쿼리를 사용한다. 이 전략은 SEQUENCE 전략과 비교해서 데이터베이스와 한번 더 통신하는 단점이 있다. TABLE 전략을 최적화하려면 TableGenerator.allocationSize를 사용하면 된다.

        권장하는 식별자 전략

        • 기본 키 제약 조건 : null 아님, 변하면 안된다.
        • 미래까지 이 조건에 만족하는 자연키는 찾기 어렵다. 대리키(대체키)를 사용하자.
        • 예를 들어 주민등록번호도 기본 키로 적절하지 않다.
        • 권장 : Long형 + 대체키 + 키 생성전략 사용

        AUTO 전략

        GenerationType.AUTO는 선택한 데이터베이스 방언에 따라 IDENTITY, SEQUENCE, TABLE 전략 중 하나를 자동으로 선택한다. AUTO 전략의 장점은 데이터베이스를 변경해도 코드를 수정할 필요가 없다는 것이다. AUTO를 사용할 때 SEQUENCETABLE 전략이 선택되면 시퀀스나 키 생성용 테이블을 미리 만들어 두어야 한다.

        IDENTITY 전략

        기본 키 생성을 데이터베이스에 위임

        IDENTITY 전략은 지금 설명한 AUTO INCREMENT를 사용한 예제처럼 데이터베이스에 값을 저장하고 나서야 기본 키 값을 구할 수 있을 때 사용한다.

        private static void logic (EntityManager em) { 
        	Board board = new Board(); em.persist (board); 
        	System.out.println("board.id = " + board.getId()); 
        }
        //출력: board.id = 1
        문제점 : IDENTITY 전략은 데이터를 데이터베이스에 INSERT한 후에 기본 키 값을 조회할 수 있다.
        티티가 영속 상태가 되려면 식별자가 반드시 필요하다. 그런데 IDENTITY 식별자 생성 전략은 엔티티를 데이터베이스에 저장해야 식별자를 구할 수 있으므로 em.persist()를 호출하는 즉시 INSERT SQL 이 데이터베이스에 전달된다. 따라서 이 전략은 트랜잭션을 지원하는 쓰기 지연이 동작하지 않는다. 왜냐하면 JPA는 보통 트랜잭션 커밋 시점에 INSERT SQL 실행합니다. 그리고 AUTO_INCREMENT는 데이터베이스에 INSERT SQL을 실행한 이후에 ID 값을 알 수 있습니다.

        'Back-end > JPA' 카테고리의 다른 글

        객체지향 쿼리 언어1 - 기본 문법  (0) 2022.09.24
        연관관계 매핑 기초  (0) 2022.08.22
        [JPA] JPA 영속성 컨텍스트  (0) 2022.05.05
        [JPA] Batch Insert  (0) 2022.05.05
        JPA 소개  (0) 2022.03.14

        목차

          닷넷(.NET) 이란?

          닷넷 프레임워크(.NET Framework)는 마이크로소프트사에서 제공하는 윈도우 프로그램 개발 및 실행환경입니다. 네트워크 작업, 인터페이스 등의 많은 작업을 캡슐화하여 코딩의 효율성을 증대시켰습니다. .NET의 특징은 CLS(닷넷 프레임워크의 언어가 반드시 지켜야 하는 언어 스펙)을 따르는 언어라면 어떠한 언어라도 닷넷 프레임워크에서 실행 가능하며 CLR이라는 가상 기계 위에서 작동하기 때문에 플랫폼에 독립적이며 궁극적으로 프로그래머가 코딩(특히 윈도우 프로그램)을 하는데 더 편한 환경을 제공해줍니다.

          닷넷(.NET)이 나온배경 

          2000년대 들어서며 썬마이크로시스템즈(현오라클)의 자바가 새로운 차세대 언어로 각광받으면서 마이크로소프트측에서도 자바의 장점을 수용하여 새로운 언어를 만들었는데요. 이것이 바로 C#이라는 언어입니다. C#이라는 언어와 .NET이라는 개발 프레임워크를 한데 묶어 자바진영에 대항하려고 했던것이죠. 결론적으로는 절반의 성공을 이루었지만 결과적으로 자바진영을 이기는데는 실패하였습니다.

          현시대에서의 닷넷(.NET)과 C#언어 

          마이크로소프트에서 배포한 C# 언어가 현시대에서는 많이 소외된 부분이 있는점은 사실입니다. 이미 자바가 웹으로는 JSP, 모바일에서는 Android등 여러방면에서 압도하고 있는점이 사실이죠. 파이썬이 인공지능등의 4차혁명이슈를 타고 최근 급격히 상승세인 점도 큰 부담일 것입니다. 더 입지가 좁아들 수 밖에 없죠 하지만! C#의 장점도 물론 있습니다. 바로 윈도우 프로그램 개발에 있어 최적화 되어있다는 점이죠. 현시대 대부분의 컴퓨터 OS는 윈도우를 사용합니다. 윈도우는 마이크로소프트사에서 제작하였고 그렇기에 C#는 윈도우 프로그램개발에있어 최적의 효율을 자랑합니다. 대부분의 윈도우 프로그램개발자들이 .NET프레임워크를 사용하고 있습니다. C#언어의 입지가 좁아짐에 따라 C#개발자들의 입지도 좁아진것도 사실이긴 하나 그와 동시에 요새 프로그래밍 교육과정도 대부분 자바중심으로 이루어져있어 자바 개발자들이 공급이 많이 되는 추세입니다. 윈도우를 이길만한 OS가 나오지 않는 이상 C#의 사용처는 분명히 있을것입니다. 앞으로는 자바개발자들이 분명 더 경쟁력이 있는 것은 부정할 수 없으나 C#개발자들이 희소성이 생기는 시점도 분명히 올 것 이라고 저는 생각하고 있습니다.

           

          그렇다면 C# 이란?

          마이크로소프트는 닷넷 프레임워크를 출시하면서 잘 표현할 수 있는 언어가 필요했고, 그에 따라 탄생한 언어가 C#입니다.
          C#은 닷넷을 위해 태어났고, 닷넷과 함께 발전해 나갑니다. C#의 시작은 Visual Studio.Net 2002,와 함께 릴리즈된 C# 1.0 입니다. 현재는 C# 8.0 까지 나온 상태입니다.
           
          C#은 닷넷 프레임워크를 기반으로 IL코드(C#코드와 기계어 사이의 중간언어)를 생성하는 컴파일러에 불과합니다. 따라서 '문법적인 요소'를 제외하고는 닷넷 프레임워크의 영역에 해당하기 때문에 C#을 배운다는 것은 즉, 닷넷 프레임워크를 배운다는 의미입니다. 이말은 C#을 배우면 응용 프로그램의 유형에 따라 다양한 선택권을 가지게 됩니다.

          닷넷 프레임워크 - Windows Form, WPF
          닷넷 코어 - 콘솔, 웹 앱, 클라우드, 윈도우 폼
          자마린 플랫폼 - 모바일(IOS, Android) 앱, 윈도우 스토어 앱
          Unity 게임 엔진 플랫폼 - 모바일 게임 개발

          .NET Framework 구조

          • ASP.NET Web Forms Web Services : Web service, Web apps 개발
          • Windows Forms : 윈도우용 응용 프로그램 개발
          • ADO .NET and XML : XML 및 데이터베이스 활용
          • Base Class Library : CLR 지원을 위한 핵심 클래스 라이브러리

          Common Language Runtime(CLR)

          .NET 언어로 작성된 프로그램을 실행하고 관리하는 실행환경이며 Java의 Virtual machine과 비슷합니다.

          CLR은 .NET에서 동작하는 프로그램을 적재하고, 프로그램의 동적 컴파일, 프로그램의 실행, 메모리관리 (Garbage Collection), 프로그램의 예외처리, 언어 간의 상속 지원, COM과의 상호 운영성 지원 등을 가능하게 합니다. .NET 언어 즉, C#뿐만 아니라 위에서 나열하였던 VB .NET 등 .NET 표준을 따르는 다양한 언어들은 CLR을 통해 프로그램을 실행할 수 있게 됩니다.

          이것이 가능한 이유는 Intermediate Language (IL, 중간언어) 라는 기계어로 변환하기 쉬운 중간 단계의 언어로 .NET에서 실행되기 위해 IL 형태로 컴파일을 하는데 IL을 기계어로 바꾸는 번역기만 제공되면 어떤 플랫폼에서도 실행가능합니다. JIT (Just-In-Time) 컴파일러를 통해 IL을 동적으로 컴파일하는데 .NET 에서는 이와같이 프로그램을 2번 컴파일 합니다. Assembly는 이 때 IL로 컴파일된 결과 파일들을 패키징 한 것을 말합니다.

           

          또 .NET 언어가 지켜야 하는 스펙으로 Common Language Specifications (CLS)로 다른 .NET 언어로 작성된 것도 호환되어 동작 가능하게 합니다. 이 과정에서 Common Type System(CTS)라는 .NET 언어마다 Data type이 다를 수 있는데 이를 언어나 시스템 환경에 관계없이 동일한 Data type을 유지하기 위한 규약이 사용되기도 합니다.

          간단히 요약하면, C# 컴파일러는 우리가 작성한 코드를 IL로 작성된 실행파일을 만들게 되고, 이 파일을 실행시키면 CLR이 IL을 읽어 다시 OS에 이해할수 있는 코드로 컴파일하여 실행시킵니다. 이렇게 서로 다른 언어가 만나는 지점이 IL언어이고, CLR이 다시 자신이 설치되어 있는 플랫폼에 최적화시켜 컴파일한 후 실행하게 됩니다. 이를 통해 플랫폼에 최적화된 코드를 만들어 내는 장점이 있으나, 실행시에 이루어지는 컴파일이 부담일 수 있습니다.

           

           

          Referece

          출처: https://2-nan.tistory.com/40 [이난의 개발자 블로그:티스토리]

          https://laboputer.github.io/csharp/2018/06/07/create-a-installer/

          목차

            결합 인덱스란?

            결합 인덱스란 두 개 이상의 컬럼을 합쳐서 인덱스를 만드는 것을 말합니다. 주로 단일 컬럼으로는 나쁜 분포도를 가지지만 여러 개의 컬럼을 합친다면 좋은 분포도를 가지고, Where절에서 AND 조건에 많이 사용되는 컬럼들을 결합 인덱스로 구성합니다.

            결합 인덱스 컬럼 선택

            1. where절에서 and 조건으로 자주 결합되어 사용되면서 각각의 분포도 보다 두 개 이상의 컬럼이 결합될 때 분포도가 좋아지는 컬럼들 

            2. 다른 테이블과 조인의 연결고리로 자주 사용되는 컬럼들

            3. order by에서 자주 사용되는 컬럼들

            4. 하나 이상의 키 컬럼 조건으로 같은 테이블의 컬럼들이 자주 조회될 때

            결합 인덱스의 컬럼 순서 결정

            결합 인덱스를 만들 때 결합 인덱스를 구성하는 컬럼들의 배열 순서는 아주 중요하기에 신중하게 결정하여야 합니다. 컬럼의 순서를 잘못 배열하면 결합 인덱스의 발동 확률이 매우 낮아질 수 있기 때문입니다. 만약 select 문의 where절에 결합 인덱스의 첫 번째 컬럼을 조건에 사용하였다면 그 질의문은 결합 인덱스를 사용할 수 있습니다. 하지만 개발자가 결합 인덱스의 두번째 컬럼만을 where 절에 조건으로 사용하고 결합 인덱스를 사용하고자 했다면 실행계획은 인덱스를 사용하지 못합니다. 따라서 쿼리문 작성 시 결합 인덱스를 사용하고자 한다면 반드시 결합 인덱스의 컬럼 중 선행하는 컬럼부터 조건에 지정하여 사용하여야 합니다. 조건은 컬럼 전체를 순서대로 사용할 수도 있고, 아니면 선행하는 일부 컬럼을 순서대로 사용할 수 있습니다. 

            결합 인덱스 컬럼의 설정 시 고려해야 할 우선순위

            1. where절 조건에 많이 사용되는 컬럼이 우선시

            2. Equal('=')로 사용되는 컬럼 우선

            3. 분포도가 좋은 컬럼을 우선

            4. 자주 이용되는 순서대로 결합 인덱스 컬럼의 순서 결정

             

            결합 인덱스 사용 예시

            결합 인덱스 생성

            create index emp_pay_idx on emp_pay(급여년월, 급여코드, 사원번호);

            emp_pay 테이블에서 급여년월, 급여코드, 사원번호 컬럼으로 emp_pay_idx라는 결합 인덱스를 생성하였습니다.

            select * from emp_pay where 급여년월 = '202107';
            select * from emp_pay where 급여년월 = '202107' and 급여코드 ='정기급여';
            select * from emp_pay where 급여년월 = '202107' and 급여코드 = '정기급여' and 사원번호 = '20210401';

            select 문장의 where 절에서는 다음과 같은 조건 조합에서 인덱스가 사용되게 됩니다.

            결합 인덱스의 효율성이 떨어지는 경우

            결합 인덱스도 일반적인 인덱스와 마찬가지로 데이터들이 정렬되어 보관되기 때문에 소수의 데이터를 빠르게 찾는 것에는 유리하지만 아래와 같이 스캔이 많이 생기게 된다면 효율성이 떨어지게 됩니다. 아래의 예시들은 emp_pay_idx 인덱스를 사용하기는 하지만 스캔이 많이 생기는 경우로 인덱스의 효율성이 떨어지는 경우들의 예시입니다.

            select * from emp_pay where 급여년월 LIKE '2021%' and 급여코드 = '정기급여';

            위 조건절의 경우 결합 인덱스의 첫 번째 컬럼인 급여년월의 조건이 있더라도 Equal(=)이 아닌 범위 연산자인 LIKE '2021%' 조건을 사용했으므로, 세개의 칼럼이 모두 필요한 emp_pay_idx 인덱스를 찾을 때 두번째 칼럼인 급여코드에 대한 조건을 B*Tree에서 쉽게 찾을수가 없게 됩니다. 이는 결합 인덱스가 각 칼럼별로 정렬이 되어 있는 것이 아니라 첫번째, 두번째, 세번째 칼럼이 결합이 되어 정렬이 되어있기 때문입니다. 이때 급여코드에 대한 조건은 인덱스를 찾아가는 검색조건이 아니라 인덱스 값이 조건에 맞는지 여부를 검증하는 체크 조건이 됩니다.

            select * from emp_pay where 급여년월 = '202107' and 사원번호 = '20210401';

            위 조건절의 경우는 결합 인덱스의 첫번째 칼럼인 급여년월의 조건이 equal(=)이더라도 두번째 컬럼인 급여코드에 대한 조건이 없으므로 세번째 칼럼인 사원번호 조건을 검색 조건이 아닌 체크 조건으로 밖에 사용할 수 없게 됩니다. 즉 결합 인덱스에서 급여년월인 모든 데이터를 찾아서 사원번호 조건에 맞는지 일일이 확인하는 풀 테이블 스캔이 일어나고 있는 셈입니다.

            'Back-end > DB' 카테고리의 다른 글

            [DB] Dababase Sharding 이란?  (0) 2022.05.05
            인덱스(Index) 란?  (0) 2022.05.05
            인덱스 란? ***  (0) 2022.02.18

            + Recent posts