오늘 게시글이나 버튼을 중앙에 배치하고 싶어서 여러 가지 찾아보게 되었다.

우선 버튼을 중앙에 배치하는 방법이다. 이 방법은 div 같은 태그 안의 요소들을 중앙에 배치할 때 유용하다.

style="justify-content:center; display:flex;

bootstrap을 사용한 중앙에 게시글 수정 요소를 나타낼 때 사용했던 방법이다.

<div class="row">
	<div class="col"></div>
	<div class="col-md-6"></div>
	<div class="col"></div>
</div>

위와 같이 html을 작성하면 부트스트랩이 중앙에 정렬을 원하는 요소를 정렬해준다.

 

이번에는 JPA 페이지 사용법을 정리하겠다.

 

Repository

 List<Article> findByCategory(String category, Pageable pageable);

Service

    @Transactional(readOnly = true)
    public List<ArticleListResponseDto> findByCategory(String category, Pageable pageable) {
        return articleRepository.findByCategory(category, pageable).stream()
                .map(ArticleListResponseDto::new)
                .collect(Collectors.toList());
    }

Controller

    @GetMapping("/majorBoard")
    public String majorBoard(Model model, @LoginUser SessionUser user, @AuthenticationPrincipal User user_s,
                            @PageableDefault(sort="id", direction=Sort.Direction.ASC) Pageable pageable)
    {
        List<ArticleListResponseDto> lst = articleService.findByCategory("major", pageable);

        return "article-select";
    }

기본적으로 위와 같이 Repository와 Service 그리고 Controller에 Pageable을 매개변수로 주고받으면 된다.

Controller에서 처음에 Pageable 객체를 받을 때는 @PageableDefault 어노테이션을 사용한다.

어떤 컬럼을 기준으로 정렬을 할지 정렬은 어떤 방식으로 할지 정할 수 있다. 

기본적으로 page 몇 개를 나타낼지 설정하지 않았다면 10개의 행만 나타낸다.

'Today I Learned' 카테고리의 다른 글

수동으로 프로젝트 제배포하기  (0) 2022.03.06
JPA를 사용하며 ORDERBY 주의점  (0) 2022.03.06
mustache로 권한 체크하기  (0) 2022.02.20
MockMvc  (0) 2022.02.03
orm, ibatis, Spring Data JPA  (0) 2022.01.31

 

https://www.acmicpc.net/problem/10825

 

10825번: 국영수

첫째 줄에 도현이네 반의 학생의 수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 한 줄에 하나씩 각 학생의 이름, 국어, 영어, 수학 점수가 공백으로 구분해 주어진다. 점수는 1보다 크거나 같고, 1

www.acmicpc.net

나의 풀이 by python

n = int(input())
data = []

for i in range(n):
    name, a, b, c = input().split()
    a, b, c = int(a), int(b), int(c)
    data.append([a, b, c, name])

data = sorted(data, key = lambda x : (-x[0], x[1], -x[2], x[3]))

for i in range(n):
    print(data[i][3])

해당 문제는 여러가지 값을 정렬로 이용해야 할 때 유용하게 사용할 수 있는 예제이다. 

이것이 코딩 테스트이다 답안

n = int(input())
students = [] # 학생 정보를 담을 리스트

# 모든 학생 정보를 입력받기
for _ in range(n):
    students.append(input().split())


students.sort(key=lambda x: (-int(x[1]), int(x[2]), -int(x[3]), x[0]))

# 정렬된 학생 정보에서 이름만 출력
for student in students:
    print(student[0])

오늘 관리자 화면 버튼을 유저가 관리자 권한을 가졌을 때만 나타나게끔 만들기로 했다.

하지만 mustache에는 Thymeleaf처럼 아래와 같은 로직을 구현하는 사용할 수 있는 방도를 찾진 못했다.

                        <a
                                class="nav-link active"
                                sec:authorize="hasAnyRole('ROLE_USER')"
                                th:href="@{/note}"
                        >

github에 mustache로 spring security 관련 코드를 찾아봤다.

해당 정보는 찾았지만 해당 코드를 사용하기 위해서는 maven 기반 프로젝트여야 했다. 나의 경우 gradle 기반이기 때문에 임포트 하는 방법에서 방법을 찾기 힘들었다.

그래서 다른 방식으로 권한을 체크하게 되었다.

 

    @GetMapping("/")
    public String main(Model model, @LoginUser SessionUser user, @AuthenticationPrincipal User user_s) {
        checkUser(model, user, user_s);
        return "main";
    }

 

    static public void checkUser(Model model, SessionUser user, User user_s){
        if (user != null) {
            model.addAttribute("nickname", user.getName());
            if(user.getRole().getKey().equals("ROLE_ADMIN"))
                model.addAttribute("isAdmin", user.getRole().getKey());
        }
        if (user_s != null) {
            model.addAttribute("nickname", user_s.getName());
            if(user.getRole().getKey().equals("ROLE_ADMIN"))
                model.addAttribute("isAdmin", user_s.getRole().getKey());
        }
    }

나의 경우 위와같은 방식으로 문제를 해결하였다. 

컨트롤러가 호출될때 유저 권한을 받아서 만약 ADMIN 권한을 가졌다면 isAdmin이라는 값을 model에 넣는 것이다. 

그렇게 하여 mustahce에서는 아래와 같이 구현하였다.

        {{#isAdmin}}
        <!-- Nav Item - Tables -->
        <li class="nav-item" sec:authorize="hasRole('ROLE_ADMIN')">
            <a class="nav-link" href="tables.html">
                <i class="fas fa-fw fa-table"></i>
                <span>관리자 화면</span></a>
        </li>
        {{/isAdmin}}

관리자의 권한을 가졌다면 자연스럽게 관리자 화면 버튼 클릭 버튼이 생성될 것이고 아니라면 생성되지 않을 것이다.

MockMvc

 

perform

요청을 전송하는 역할을 합니다. 결과로 ResultActions 를 반환합니다.

get, post, put, delete

perform() 안에 넣어서 요철할 http method를 정합니다. 

ex)perform(get("/hello"))

params

Key value 파라미터를 전달할수 있습니다.

여러 개일 때는 params, 한개면 param을 사용합니다.

 

andExpect

응답을 검증합니다.

ex) andExpect(status().isBadRequest())

satatus() 상태를 검증합니다. isOk(200), isNotFound(404)

view() 응답으로 받은 뷰 이름을 검증합니다.

redirect() 응답으로 받은 redirect를 검증합니다.

content() 응답 body를 검증합니다.

 

andDo

일반적으로 해야할 일을 표현합니다.

andDO(print()) 하면 결과를 print합니다.

 

스프링 시큐리티의 테스트는 일반적인 컨트롤러 테스트와 약간 다릅니다.

그 이유는 유저가 로그인을 한 상태로 서비스를 이용했다는 가정하에

테스트를 진행할 수 있어야 하기 때문입니다.

시큐리티 테스트를 사용하면 테스트를 시행 전에 원하는 유저를 마치 로그인한 것 처럼 설정할 수 있습니다.

 

가짜 유저를 세팅하는 방법중 3가지 방법을 소개합니다.

@WithMockUser

특정 사용자가 존재하는 것처럼 테스트 진행할 수 있습니다.

@WithUserDetails

사용자 가짜 로그인 가능

~.with

직접 사용자를 mockMvc에 지정하는 방식입니다. 

@Entity

엔티티 클래스 애노테이션

데이터베이스에 저장(persist)할 자바 객체를 정의

- 다양한 애노테이션을 이용해 보다 자세한 테이블 스키마 정보를 표현

- 애노테이션으로 표현한 스키마 정보와 실제 테이블 스키마가 완벽히 일치해야 할 필요는 없음

- 하나의 도메인(domain)으로 간주

 

@Entity 클래스 안에서 사용되는 주요 JPA 애노테이션

- @Table, @Index, @UniqueConstraint: 테이블 기본 정보와 인덱스, unique 키를 설정

- @Id, @GeneratedValue: primary key 설정

- @Column: 각 컬럼 설정

- @Enumerated: enum 을 처리하는 방법을 설정

- @Transient: 특정 필드를 DB 영속 대상에서 제외

- @OneToOne, @OneToMany, @ManyToOne, @ManyToMany: 연관 관계 설정

- @MappedSuperClass: 상속을 이용한 공통 필드 정의

- @Embedded, @Embeddable: 클래스 멤버를 이용한 공통 필드 정의

- @DataTimeFormat: 스프링에서 제공하는 애노테이션, 날짜 입력의 포맷을 지정

 

 

@Entity: JPA엔티티의 lifecycle event를 활용한 Auditing(생성자, 생성일자, 수정자, 수정일자) 테크닉

JPA엔티티에 생성일시, 수정일시 같이 일정하게 작성하는 메타데이터를 처리 가능

- @PrePersist

- @PostPersist

- @PreRemove

- @PostRemove

- @PreUpdate

- @PostUpdate

- @PostLoad

 

@Entity: Spring JPA Auditing 애노테이션

엔티티의 생성일시, 수정일시, 생성자, 수정자를 자동으로 관리해주는 애노테이션

설정

- @EnableJpaAuditing

- @EntityListeners(AuditingEntityListener.class)

활용

- @CreatedBy

- @CreatedDate

- @LastModifiedBy

- @LastModifiedDate

 

ORM(Object Relational Mapping)

객체지향 언어를 이용하여, 서로 호환되지 않는 타입 간의 데이터를 변환하는 기술

 

Apache iBatis

SQL 데이터 베이스와 객체 간 매핑을 지원해주는 persistence framework

 

Spring Data JPA 인터페이스

단계별로 필요한 기능까지만 사용 가능

- Repository: 기본 repository 인터페이스, 어떤 메소드도 제공하지 않음 

- CrudRepository: Repository + CRUD 기능 제공

- PagingAndSortingRepository: CrudRepository + 페이징, 정렬 기능 제공

- JpaRepository: PagingAndSortingRepository + Spring Data JPA repository 전체 기능

 

 

인터페이스에 작성한 메소드 이름이 곧 쿼리 표현이 됨

ex: List<Event>findByEventStatusAndEventNameOrCapacity(String eventStatus, String eventName, Integer capacity);

- 다이나믹 쿼리를 만들 수는 없음

- 사용 가능한 키워드

  - distinct, and, or, is, not, between, lessThan, lessThanEqual, greaterThen, greaterThenEqual

  - null, isNotNull, like, startingWith, endingWith, containing, orderBy, in true, false, ignoreCase

  - join 등 복잡한 표현은 불가

 

 

@Param: 쿼리 메소드 입력 파라미터에 사용하여 애노테이션 기반 파라미터 바인딩할 때 사용

@QUERY: 직접 JPQL을 작성하고 싶을 때 사용

@ NoReositoryBean: 빈으로 등록하고 싶지 않은 인터페이스를 지정할 수 있음

 - 특정 쿼리 메소드를 기본 메소드로 지정하는 방식으로 운영 가능

 - 특정 메소드를 선택적으로 사용하거나 api에 노출하고자 할 때도 사용하는 테크닉

 

오류
source release 11 requires target release 11

 

해당 오류는 JDK 버전 오류이다.

해당 오류 발생시 확인해야하는 사항이 있다.

1. build.gradle 파일에서 sourceCompatibility = '11' 인지 확인한다.

 

2. ProjectStructure > ProjectSettings > Project

 - ProjectSDK = 11

 - Project language level = 11

글쓴이의 경우 1.8 버전이 default로 되있어서 오류가 난 것이었다.

 

3. Project Structure > Plaform Settings > SDKs

- SDK 버전이 설치 되어있는지 확인한다.

 

참고 글

https://hothoony.tistory.com/1105

 

[intellij] java: warning: source release 11 requires target release 11

오류 java: warning: source release 11 requires target release 11 오류 발생시 확인해 볼 내용 build.gradle sourceCompatibility = '11' Project Structure > Project Settings > Project Project SDK = 11 P..

hothoony.tistory.com

 

누적합

합들의 값을 미리 더해두는 것을 누적 합이라고 한다.

누적합의 예

A = [i for i in range(10)]
print(A)
for i in range(1, 10):
	A[i] = A[i-1] + A[i]
print(A)

DP[i] = i까지 합

i부터 j까지의 합은 DP[i] - DP[j-1]

 

 

 

<구현으로 인한 풀이>

n, m = map(int, input().split())
lst = [[0 for _ in range(m+1)] for _ in range(n+1)]

for i in range(1, n+1):
    tmp = list(map(int, input().split()))
    for j in range(1, m+1):
        lst[i][j] = tmp[j-1]

k = int(input())
k_lst = [list(map(int, input().split())) for _ in range(k)]
result = []

for u in range(k):
    a,b,x,y = k_lst[u][0], k_lst[u][1], k_lst[u][2], k_lst[u][3]
    sum = 0
    for i in range(a,x+1):
        for j in range(b, y+1):
            sum += lst[i][j]
    result.append(sum)

for i in range(len(result)):
    print(result[i])

<DP를 활용한 풀이>

N, M = map(int, input().split())
A = [list(map(int, input().split())) for _ in range(N)]
# DP[i][j] = 1, 1부터 (i, j)까지의 부분합
DP = [[0 for i in range(M+1)] for _ in range(N+1)]

for i in range(1, N+1):
    for j in range(1, M+1):
        DP[i][j] = DP[i-1][j] + DP[i][j-1] - DP[i-1][j-1] + A[i-1][j-1]
        
for _ in range(int(input())):
    i, j, x, y = map(int, input().split())
    print(DP[x][y] - DP[i-1][y] - DP[x][j-1] + DP[i-1][j-1])

 

Traditional Deployment
여러 버전의 앱을 하나의 서버에 돌린다.
효율성, 확장성이 떨어진다.


Virtualized Deployment
가상머신 사용
Hypervisor를 통해 GeustOS를 생성 컴퓨터 한대를 시뮬레이션 한다.
cpu/ram/hdd 장치 필요 -> 호스트 운영체제에서 생성하여 실행
확장성이 좋아진다. 
cpu/ram/hdd 를 직접 생성하여 사용함으로 오버헤드가 증가하며 성능이 떨어진다.

 

Container Deployment

하나의 호스트 서버에서 
또다른 운영체제를 띄울 필요없이 하나의 컨테이너에서 띄울 수 있다.
각각의 컨테이너는 커널을 공유한다. 
경량화, 오버헤드가 줄어들며 성능이 향상된다.

Kubernetes Deployment
서버 여러대에서 컨테이너를 관리한다.
머신들을 클러스트하여 사용한다.

'DevOps' 카테고리의 다른 글

ec2 서버 생성 후 꼭 해야되는 초기 설정  (0) 2022.07.31
mac에서 간단하게 ec2 서버 접근하기  (0) 2022.07.31
AWS CLI  (0) 2022.01.16

AWS CLI


  • https://aws.amazon.com/cli
  • https://github.com/aws/aws-cli
  • AWS 서비스 관리를 위한 CLI 명령형 도구
  • AWS CLI는 Python 기반으로 작성되어 Boto 패키지를 이용

 

CLI(Command Line Interface)


명령 줄 인터페이스 또는 명령어 인터페이스는 가상 터미널 또는 터미널을 통해 사용자와 컴퓨터가 상호 작용하는 방식을 뜻한다. 즉, 작업 명령은 사용자가 컴퓨터 키보드 등을 통해 문자열의 형태로 입력하며, 컴퓨터로부터의 출력 역시 문자열의 형태로 주어진다. from 위키백과

 

AWS CLI 설치(macOS)

$ brew install awscli

Window 에서 설치

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

 

AWS CLI를 사용하기 위해서 자격 증명을 해야 한다. 

AWS 계정 혹은 IAM 사용자의 액세스 키 발급이 필요하다.

 

Access Key ID

 - 자격증명 주체를 가리킴

   인증 요청한 사람이 누구인가?

Secret Access Key

 - 자격증명 주체 본인임을 인증

   인증 요청한 사람이 정말 A가 맞는가?

 

엑세스 키 만드는 방법

 

AWS CLI 자격증명 설정: CLI 설정 파일

 - / .aws/config

[default]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrsfhefuwefij/werewuihi/ewrhweiuhkey

 

AWS CLI 자격증명 설정: 환경변수

- AWS_ACCESS_KEY_ID 

- AWS_SECRET_ACCESS_KEY

- AWS_PROFILE

 

AWS CLI 자격증명 설정: EC2 인스턴스 프로파일

IAM 역할(Role)을 EC2 머신에 부여하기 위한 목적

EC2 내에서 AWS 서비스에 대한 권한을 수행할 수 있게 됨

 

fastcampus 강의에서는 바로 nvim ~/.aws/config 명령어부터 시작된다.

하지만 /.aws 파일은 존재하지 않았다.

해당 과정을 진행하기 위해서

aws cli를 설치한 후 aws configure 명령어를 실행하고 aws access key id 와

aws secret access key 를 입력하고 default region name과 output format을 입력하고 나서야

/.aws 파일이 생성 되었다.

 

AWS CLI 명령어는 일반적으로 아래와 같은 형식으로 사용된다.

aws <command> <subcommand> [options and parameters]

 

aws 매뉴얼 확인하기

aws help
aws <command> help 
aws <command> <subcommand> help

aws <command> help 명령어는 command에 대한 설명을 나타냅니다.

aws <command> <subcommand> help 명령어는 subcommand 명령어에 대한 설명을 나타냅니다.

 

aws 디버그 모드 활성화

$ aws sts get-caller-identity --debug

디버그 모드를 활성화하면, 특정 명령어를 수행할 때 aws cli의 동작을 디버그 할 수 있다.

 

aws 현재 자격증명 정보 확인하기

$ aws sts get-caller-identity

강의 요약

AWS CLI는 AWS 서비스를 관리할 수 있는 명령형 도구로, 자동화 목적에 활용 가능

AWS CLI를 설치하고 자격증명 및 기본 리전, 결과 출력 형식을 설정할 수 있음

AWS 액세스 키를 발급받고 자격증명으로 사용할 수 있음

 

 

'DevOps' 카테고리의 다른 글

ec2 서버 생성 후 꼭 해야되는 초기 설정  (0) 2022.07.31
mac에서 간단하게 ec2 서버 접근하기  (0) 2022.07.31
devops의 변천사  (0) 2022.01.18

+ Recent posts