도메인 모델 패턴: 엔티티가 비즈니스 로직을 가지고 객체 지향의 특성을 적극 활용하는 것

엔티티 -> 비즈니스 로직 대부분

서비스 계층 -> 단순히 엔티티에 필요한 요청을 위임하는 역할

JPA, ORM

 

트랜잭션 스크립트 패턴: 서비스 계층에서 대부분의 비즈니스 로직을 처리

SQL 다룰 때 

 

유지보수 측면에서 고민

한 프로젝트 내에서도 두가지 패턴이 양립 가능

'Web Programming > JPA' 카테고리의 다른 글

테스트  (0) 2023.02.20
애플리케이션 아키텍쳐  (0) 2023.02.19
엔티티 클래스 설계  (0) 2023.02.19

계층형 구조 사용

controller, web: 웹 계층

service: 비즈니스 로직, 트랜잭션 처리

repository: JPA를 직접 사용하는 계층, 엔티티 매니저 사용

domain: 엔티티가 모여 있는 계층, 모든 계층에서 사용

 

패키지 구조

  • me.seongim
    • domain
    • exception
    • repository
    • service
    • web
    • api

개발 순서: 서비스 리포지토리 계층 개발 -> 테스트 케이스 작성 -> 검증 -> 웹 계층 적용

Getter 모두 열고

Setter 사용X 변경 추적이 어렵다. 변경 지점이 명확하도록 변경을 위한 비즈니스 메서드를 별도로 제공

 

엔티티의 식별자는 id 사용 PK 컬럼명은 member_id

엔티티는 타입이 있으므로 id만으로 구분 가능

테이블은 타입이 없으므로 구분이 어렵다.

테이블은 테이블 + id

 

실무에서는 @ManyToMany 사용X

중간 테이블에 컬럼을 추가할 수 없고 세밀하게 쿼리 실행이 어려움

중간 엔티티를 만들고 @ManyToOne @OneToMany로 매핑해서 사용

다대다 매핑 -> 일대다 + 다대일

 

값 타입은 변경 불가능하게 설계

@Setter 제거하고 생성자에서 값을 모두 초기화해서 변경 불가능한 클래스로 만들어야함

JPA 스펙상 엔티티나 임베디드 타입 (@Embeddable) 은 자바 기본 생성자를 public protected로 설정해야 함

public보다는 protected가 안전

(JPA 구현 라이브러리가 객체를 생성할 때 리플렉션 같은 기술을 사용할 수 있도록 지원하기 위한 제약)

 

모든 연관관계는 지연로딩(LAZY)으로 설정

즉시로딩(EAGER)은 예측이 어렵고, 어떤 SQL이 실행될지 추적하기 어려움

JPQL 실행할 때 N+1 문제가 자주 발생

연관된 엔티티를 함께 DB에서 조회해야 하면, fetch join 또는 엔티티 그래프 기능을 사용

@XToOne(OneToOne, ManyToOne) 관계는 기본이 즉시로딩이므로 직접 지연로딩으로 설정해야함

 

컬렉션은 필드에서 초기화

null 문제에 안전함

 

스프링 부트 신규 설정

엔티티(필드) 테이블(컬럼)
카멜 케이스 memberId 언더스코어 member_id
언더스코어
대문자 소문자

 

cascade = CascadeType.ALL (ALL은 delete까지 모두)

persist(orderItemA)

persist(orderItemB)

persist(order)

= > persist(order)

 

연관관계 메서드 작성

 

 

 

문제:

ArrayList를 for 문으로 반복하며 add 하는 와중에

마지막 객체가 전체 리스트를 덮어쓰기 하는 현상이 발생했습니다.

 

원인:

만든 객체 클래스에서 변수가 static 으로 선언되었던 것

 

해결:

static 빼면 됩니다.!

 

static 변수는 클래스 변수로 객체를 생성하지 않고도 접근 가능

메모리에 고정되어 할당되므로 여러 주소값으로 주어져도 변수의 값은 변하지 않습니다.

 

   메모리 영역
     static 영역
   클래스 모임
     힙 영역
   객체 모임
 
 
  GC관리 ⤴  

 

  static 영역 사용자가 만든 Class GC(Garbage Collector)가 관리 X -> 자주 사용시 과부하 위험
메모리 영역      
  힙 영역 new 연산을 통해 생성한 객체 GC(Garbage Collector)가 관리 O

 

예를 들어

게시물의 좋아요 수를 구한다고 가정했을 때

 

import java.util.*;

public class PostLike {
    public static class Post {
        private static Integer likeCnt1;
        private Integer likeCnt2;

        public Post(Integer likeCnt1, Integer likeCnt2) {
            this.likeCnt1 = likeCnt1;
            this.likeCnt2 = likeCnt2;
        }

        public Integer getLikeCnt1() {
            return this.likeCnt1;
        }

        public Integer getLikeCnt2() {
            return this.likeCnt2;
        }
    }

    public static void main(String[] args) {
        List<Post> postList = new ArrayList<>();

        for (int i = 0; i < 3; i++) {
            postList.add(new Post(i, i));
        }

        for (Post post : postList) {
            System.out.println("POST Like COUT 1 : " + post.getLikeCnt1());
            System.out.println("POST Like COUT 2 : " + post.getLikeCnt2());
            System.out.println();
        }
    }
}

 

출력

POST Like COUT 1 : 2
POST Like COUT 2 : 0

POST Like COUT 1 : 2
POST Like COUT 2 : 1

POST Like COUT 1 : 2
POST Like COUT 2 : 2

 

static으로 선언된 likeCnt1은 값이 메모리에 씌어질시 프로그램이 종료될 때까지 메모리의 값이 유지되기 때문에

마지막에 씌어진 2 라는 값이 나오게 됩니다.

 

클래스에서 변수의 값을 공유하고 싶을 때 static 변수를 사용합시다.

 

 

'Web Programming > JAVA' 카테고리의 다른 글

val var  (0) 2023.09.01
Calendar week of year 53주 대신 1주 뜨는 현상 해결  (0) 2021.01.11
HttpServletRequest 요청 URL 정보 얻는 함수  (0) 2020.11.06
[JAVA] JAVA 언어의 이해  (0) 2020.01.21

부모창에서 다른 도메인을 가진 iframe 페이지 표시하는 방법

 

1. iframe src 요청에 요청 헤더 추가

일반적으로 부모창에서 서로 다른 도메인을 가진 iframe을 추가하게 되면 에러 발생

에러 메세지 : Refused to display 'http://~' in a frame because it set 'X-Frame-Options' to 'sameorigin'.

 

-> iframe 서버의 로직 수정 필요

'X-Frame-Options' to 'sameorigin'

response.setHeader("X-Frame-Options", "ALLOW-FROM http://부모창.com");

 

2. 다른 도메인간 쿠키 전송

다른 도메인 내부에 쿠키 생성

쿠키는 브라우저에 데이터를 저장하기 위한 수단 중 하나

로그인시 사용자 인증 후 쿠키에 토큰 저장

 

aaa.com

bbb.com / jsp

  1. aaa.com 로그인
  2. 로그인시 서버에서는 사용자 인증 후 쿠키에 토큰 저장하고 응답값으로 헤더에 포함해서 주기
  3. aaa.com은 쿠키를 브라우저에 저장
  4. aaa.com에서 서버로 요청 보낼 때 헤더에 쿠키 같이 전송
  5. 서버는 헤더를 읽고 사용자 식별하기 위한 수단으로 사용

쿠키에 도메인을 설정하면 해당 도메인에서만 유효한 쿠키가 된다.

third-party 쿠키 : 사용자가 접속한 페이지와 다른 도메인으로 전송하는 쿠키

first-party 쿠키 : 사용자가 접속한 페이지와 같은 도메인으로 전송하는 쿠키

 

다른 도메인간에 쿠키 전송하는 방법

브라우저의 쿠키 정보나 인증과 관련된 헤더를 함부로 request에 담지 않아야 한다.

 

aaa.com에서 ajax 요청 보낼 때 withCredentials 설정 필요

서버는

1. CORS 설정 필요

2. 응답 헤더로 Access-Control-Allow-Credentials 옵션 true

3. Access-Control-Allow-Origin 도메인 적어주기 (aaa.com)

 

SameSite 쿠키 정책

None : 크로스 사이트 요청의 경우에도 항상 전송. SameSite 탄생 전과 동일하게 동작

Strict : 크로스 사이트 요청에는 항상 쿠키 전송 안함

Lax : Strict에 비해 느슨한 정책. 대체로 서드파티 쿠키를 전송하지 않지만 몇 가지 예외적인 요청에는 전송

* Lax 쿠키 예외 사항 : Top Level Navigation (웹 페이지 이동), "안전한" HTTP 메서드 요청의 경우 (예 GET)

Top Level Navigation: <a> 클릭, window.location.replace 등 자동으로 이루어지는 이동, 302 redirect 이용한 이동

"안전하지 않은 요청" POST DELETE

 

크롬의 SameSite 기본값 : Lax

 

'Web Programming > JAVASCRIPT' 카테고리의 다른 글

CORS 정책  (0) 2022.11.09

Open Distro Alert 기능을 사용해 장애 알람을 받아봅시다

 

1. elasticsearch에 open distro alert 설치

vi elasticsearch/Dockerfile
ARG ELASTIC_VERSION

FROM docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION}
RUN elasticsearch-plugin install -b https://github.com/opendistro-for-elasticsearch/alerting/releases/download/v1.13.1.0/alerting.zip

 

2. kibana에 open distro alert 설치

vi kibana/Dockerfile
ARG ELASTIC_VERSION

FROM docker.elastic.co/kibana/kibana:${ELASTIC_VERSION}
RUN kibana-plugin install https://github.com/opendistro-for-elasticsearch/alerting-kibana-plugin/releases/download/v1.13.0.0/opendistroAlertingKibana-1.13.0.0.zip

 

3. elk랑 open distro alert 버전 맞추기

vi .env
ELASTIC_VERSION=7.10.2

 

4. x-pack 설정 off

vi elasticsearch/config/elasticsearch.yml

false로 수정합니다!

xpack.security.enabled: false
xpack.monitoring.collection.enabled: false

 

5. 실행

docker-compose build && docker-compose up -d

'Web Programming > SPRINGBOOT' 카테고리의 다른 글

아키텍쳐  (0) 2023.08.18
[Kotlin] kapt(kotlin annotation processing tool)  (0) 2023.08.18
Spring Elk 연동  (0) 2022.11.17
ELK 설치  (0) 2022.11.16
mac에 docker 설치  (0) 2022.11.16

spring boot와 elk를 연동

 

기존 프로젝트를 열어서

pom.xml에 dependency 추가

<dependency>
	<groupId>net.logstash.logback</groupId>
	<artifactId>logstash-logback-encoder</artifactId>
	<version>7.0.1</version>
</dependency>

 

logback.xml에 추가

<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <destination>127.0.0.1:50000</destination>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder"></encoder>
</appender>

<root>
	<appender-ref ref="LOGSTASH"/>
</root>

 

application.yml에 추가

logging:
  config: classpath:logback.xml

 

이제 프로젝트 실행하면 logstash로 로그를 전송합니다.

'Web Programming > SPRINGBOOT' 카테고리의 다른 글

[Kotlin] kapt(kotlin annotation processing tool)  (0) 2023.08.18
장애 탐지 및 알람  (0) 2022.11.24
ELK 설치  (0) 2022.11.16
mac에 docker 설치  (0) 2022.11.16
docker redis 설치  (0) 2021.02.17

mac에 docker 설치 후 docker 사용해 elk 구축하기

 

1. docker 설치

https://imsseong.tistory.com/34

 

mac에 docker 설치

저는 macOS Ventura intel칩 버전입니다! 1. os에 맞게 다운로드해주세요. https://www.docker.com/ Docker: Accelerated, Containerized Application Development Docker is a platform designed to help developers build, share, and run modern applic

imsseong.tistory.com

 

2. docker-elk 설치

terminal에 입력

git clone https://github.com/deviantony/docker-elk.git
cd docker-elk

 

3. elasticsearch 설정 변경

vi elasticsearch/config/elasticsearch.yml

하단에 xpack.monitoring.collection.enabled: true 추가

---
## Default Elasticsearch configuration from Elasticsearch base image.
## https://github.com/elastic/elasticsearch/blob/main/distribution/docker/src/docker/config/elasticsearch.yml
#
cluster.name: "docker-cluster"
network.host: 0.0.0.0

## X-Pack settings
## see https://www.elastic.co/guide/en/elasticsearch/reference/current/security-settings.html
#
xpack.license.self_generated.type: trial
xpack.security.enabled: true
xpack.monitoring.collection.enabled: true

 

4. kibana 설정 변경

vi kibana/config/kibana.yml

elasticsearch.password: 패스워드 변경

 

5. logstash 설정 변경

vi logstash/config/logstash.yml
---
## Default Logstash configuration from Logstash base image.
## https://github.com/elastic/logstash/blob/main/docker/data/logstash/config/logstash-full.yml
#
http.host: "0.0.0.0"

xpack.monitoring.elasticsearch.hosts: [ "http://elasticsearch:9200" ]
 vi logstash/pipeline/logstash.conf
input {
        beats {
                port => 5044
        }

        tcp {
                port => 50000
                codec => json_lines
                type => logstash
        }
}

## Add your filters / logstash plugins configuration here

output {
        stdout {
        }
        elasticsearch {
                hosts => "elasticsearch:9200"
                index => "logstash-%{+YYYY.MM.dd}"
                user => "elastic"
                password => "패스워드"
        }
}

 

6. docker-compose.yml

vi docker-compose.yml

 

ELASTIC_PASSWORD: 패스워드 변경

 

7. 실행

docker-compose build && docker-compose up -d

 

 

실행이 안됐습니다. ㅠㅠ

 

 

8. 에러 해결

에러: value of "elastic" is forbidden. This is a superuser account that cannot write to system indices that Kibana needs to function. Use a service account token instead.

 

해결: elasticsearch 인증을 token으로 변경

elasticsearch 터미널창 열고 토큰 발급

bin/elasticsearch-service-tokens create elastic/kibana my-token

 

SERVICE_TOKEN elastic/kibana/my-token = [AA~]

 

토큰 리스트 확인

bin/elasticsearch-service-tokens list

 

토큰 값 복사 후 kibana 설정 다시 변경해줍니다.

username과 password는 주석 처리 후 token값을 넣어줍니다.

vi kibana/config/kibana.yml
#elasticsearch.username: elastic
#elasticsearch.password: 패스워드
elasticsearch.serviceAccountToken: 토큰값

 

9. 재실행

docker-compose build && docker-compose up -d

 

10. 접속

http://localhost:9200/

http://localhost:5601/

 

 

'Web Programming > SPRINGBOOT' 카테고리의 다른 글

장애 탐지 및 알람  (0) 2022.11.24
Spring Elk 연동  (0) 2022.11.17
mac에 docker 설치  (0) 2022.11.16
docker redis 설치  (0) 2021.02.17
Http를 통한 양방향 통신  (0) 2021.02.16

+ Recent posts