Redis-cli 원격 접속하기.

|

리눅스 데스크탑 매니저 파일이 없어도 외부에서 redis-cli 명령어로 접근이 가능하다는 것을 이제야 알았다…왜 이제 알았을까

1. redis 설치 (windows)

  • https://github.com/rgl/redis/downloads 에서 설치파일 내려받고 설치하면 Program Files 에 설치됨.

2. 리눅스에 Redis 설치 (ubuntu)

먼저 리눅스에 redis를 설치하기 위해서 파일을 직접 다운받거나 apt-get 등을 이용할 수 있다. 만약 apt-get 패키지 다운로드를 사용할 경우 아래와 같이 커맨드를 입력하면 된다.

  $ sudo apt-get install redis-server

3. 명령어

  redis-cli -h 123.123.123.123(레디스 설치되어있는 아이피) -p 6379 -a password

-h : 호스트 아이피

-p : redis 포트

-a : 비밀번호

출처:

  • https://blog.geun.kr/349 [Geun`s Page]

[Spring] 스프링에서 File객체를 MultipartFile로 변환하기.

|

스프링에서 파일을 업로드 하려고 하는데, MultipartFile로 업로드를 해야만 하고 File로만 받아올 수 있는 상황이 백엔드에서 파일 다루다 보면 종종 발생한다. 그래서 File > MultipartFile 변환을 해 주어야 하는데 방법을 찾기가 쉽지는 않았다.

일반적이진 않지만 몇가지 방법이 있어 소개한다.

1. 스프링 테스트의 MockMultipartFile 사용

import org.springframework.mock.web.MockMultipartFile;
....

MultipartFile multipartFile = new MockMultipartFile("test.xlsx", new FileInputStream(new File("/home/admin/test.xlsx")));

or

import org.springframework.mock.web.MockMultipartFile;
....
String writerData = "str1,str2,str3,str4";
MultipartFile multipartFile = new MockMultipartFile("files", "파일명.csv", "text/plain", writerData.getBytes(StandardCharsets.UTF_8));

2. IOUtils 사용

1번 방법이 간편하긴 하나.. 테스트를 runtime에 올려햐 하며 사용이 불가능하다는 커뮤니티 글도 있었다.
그럴땐 아래와 같은 방법으로 변환이 가능하다.


File file = new File("/path/to/file");
FileItem fileItem = new DiskFileItem("mainFile", Files.probeContentType(file.toPath()), false, file.getName(), (int) file.length(), file.getParentFile());

try {
    InputStream input = new FileInputStream(file);
    OutputStream os = fileItem.getOutputStream();
    IOUtils.copy(input, os);
    // Or faster..
    // IOUtils.copy(new FileInputStream(file), fileItem.getOutputStream());
} catch (IOException ex) {
    // do something.
}

MultipartFile multipartFile = new CommonsMultipartFile(fileItem);

참고자료

  • https://okky.kr/article/441770
  • https://stackoverflow.com/questions/16648549/converting-file-to-multipartfile

[MyBatis] insert 후 key값 가져오기

|

mybatis 의 insert 구문을 통해 autoincrement 된 키값을 가져오고 싶을 때 사용하는 방법이다.

useGeneratedKeys 옵션

 <insert id="insertData" parameterType="DataClass" useGeneratedKeys="true" keyProperty="id">
     /* query */

 </insert>

id가 autoincrement인 PK일 경우, 그 id값은 DataClass에 선언되어 있는 id 필드 안으로 값이 저절로 들어간다.
debug 찍고 DataClass 객체의 id값을 보면 값이 들어있을 것이다.

selectKey 옵션

Oracle 같은 경우는 Auto Increment 가 없고 Sequence를 사용해야만 한다. 해당 경우엔 아래와 같이 설정해주면 된다.

<insert id="insertStudents" parameterType="DataClass">
  <selectKey keyProperty="id" resultType="int" order="BEFORE">
    select SEQ_ID.nextval FROM DUAL
  </selectKey>
     /* query */
</insert>

참고자료

  • https://marobiana.tistory.com/23 [Take Action]
  • https://taetaetae.github.io/2017/04/04/mybatis-useGeneratedKeys/

[MySQL] 테이블 스키마 정보 조회하기.

|

테이블 필드정보 1

SELECT
 a.TABLE_NAME '테이블명',
 b.ORDINAL_POSITION '순번',
 lower(b.COLUMN_NAME) '필드명',
 upper(b.DATA_TYPE) 'DATA TYPE',
 b.COLUMN_TYPE '데이터길이',
 b.COLUMN_DEFAULT '디폴트값',
 b.COLUMN_KEY 'KEY',
 b.IS_NULLABLE 'NULL값여부',
 b.EXTRA '자동여부',
 b.COLUMN_COMMENT '필드설명'
from information_schema.TABLES a JOIN information_schema.COLUMNS b on a.TABLE_NAME = b.TABLE_NAME and a.TABLE_SCHEMA = b.TABLE_SCHEMA
where a.TABLE_SCHEMA = '테이블 스키마명' 
ORDER BY
  a.TABLE_NAME, b.ORDINAL_POSITION
;

테이블 필드정보 2

SELECT 
  b.TABLE_NAME,
  b.ORDINAL_POSITION,
  lower(b.COLUMN_NAME) '필드명',
  upper(b.DATA_TYPE) 'DATA TYPE',
  b.CHARACTER_MAXIMUM_LENGTH,  
  b.COLUMN_DEFAULT,
  CASE WHEN b.IS_NULLABLE = 'NO' THEN 'NOT NULL' ELSE '' END NULLABLE,
  b.COLUMN_COMMENT
FROM information_schema.COLUMNS b
WHERE TABLE_SCHEMA = '테이블 스키마명'
ORDER BY TABLE_NAME, b.ORDINAL_POSITION
;

인덱스 정보 (프라이머리 제외)

SELECT TABLE_NAME, INDEX_NAME, GROUP_CONCAT(COLUMN_NAME SEPARATOR ','), UNIQ
FROM (
	SELECT TABLE_NAME, SEQ_IN_INDEX, INDEX_NAME, LOWER(COLUMN_NAME) COLUMN_NAME, CASE WHEN NON_UNIQUE = 0 THEN 'UNIQUE' ELSE '' END UNIQ 
	FROM INFORMATION_SCHEMA.STATISTICS
) AS DT
WHERE INDEX_NAME <> 'PRIMARY'
GROUP BY TABLE_NAME, INDEX_NAME, UNIQ
ORDER BY TABLE_NAME
;

테이블 코멘트 조회

SELECT TABLE_NAME, TABLE_COMMENT from information_schema.TABLES
WHERE TABLE_SCHEMA = '테이블 스키마명'
ORDER BY TABLE_NAME
;

HandlerMethodArgumentResolver 를 통해 특정 Argument 사용 시 변경하기.

|

  • HandlerMethodArgumentResolver 를 사용하여 컨트롤러 메소드에 선언된 특정 Arguments를 변경하거나 또는 권한체크를 하여 arguments에 값을 넣어주거나 할 수 있다.

0. 멤버 클래스


@Getter
@RequiredArgsConstructor
public class Member {
  private final String username;
  private final String email;
}

1. MemberHandlerMethodArgumentResolver 추가.

  1. 컨트롤러에서 파라미터를 바인딩.
    • ex) 특정클래스나 특정 어노테이션등의 요청 파라미터를 수정해야한다거나 또는 클래스의 파라미터를 조작, 혹은 공통적으로 써야하는 파라미터들을 바인딩 해주는 역할을 한다.
    • 예제에서는 유저정보를 고정으로 가져와서 파라미터로 쓰기 위해 사용하였다.
@Slf4j
public class MemberHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    /**
     * @param parameter
     * @return
     */
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return Member.class.isAssignableFrom(parameter.getParameterType());
    }

    /**
     * @param parameter
     * @param mavContainer
     * @param webRequest
     * @param binderFactory
     * @return
     * @throws Exception
     */
    @Override
    public Member resolveArgument(MethodParameter parameter,
                                  ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest,
                                  WebDataBinderFactory binderFactory) throws Exception {

        // 컨트롤러의 메소드에 아래 아규먼트가 선언되었을 때만 아래 로직 태움..
        if (parameter.getParameterType().equals(Member.class)) {
           Member member = new Member("jmlim", "hackerljm@naver.com");
           return member;
        }
    }
}

2. WebConfig에 작성한 ArgumentResolver 등록

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
  
  @Override
  public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
    argumentResolvers.add(new MemberHandlerMethodArgumentResolver());
  }
}

3. 컨트롤러에서 사용.

Member 클래스에는 아무 파라미터를 넣지 않아도 테스트를 해보면 위에서 넣어둔 jmlim과 hackerljm@naver.com 이 나오게 된다.


@Slf4j
@RestController
@RequestMapping()
public class TestController {


    /**
     *
     * @param member
     * @return
     */
    @GetMapping("/member/info")
    public ResponseEntity getLoginInfo(Member member) {
       /**해당 메소드 호출 전에 resolveArgument 를 타게 됨.*/
       ....
    }

참고:

  • http://wonwoo.ml/index.php/post/1092