Java & Spring2021. 6. 1. 15:40

IntelliJ의 경우 MyBatis 연동을 하면 쿼리문의 배경이 아래처럼 적용되는데

Injected language fragment 가 설정됐기 때문이다.

File - Settings - Editor - Color Scheme - General에 보면 다음과 같이 Background에 체크돼있는데

이걸 체크해제 하면 배경이 사라지면서 깔끔해진다.

근데 이걸 해제함으로써 생기는 불편함이 있을 거 같은데 아직은 찾질 못했다.

 

- 이상 끗.

Posted by 홍규홍규
Java & Spring2021. 2. 26. 10:21

# 작업환경 IntelliJ, SpringBoot 2.4.3, gradle 기반, Java 13

 

# TEST_ID -> testId 형식의  CamelCase 적용하기

 

기존 레거시에서는 ObjectMapperFactory 구현과 MapWrapper 상속을 이용해서

hashmap에 들어간 key를 바꾸는 방법을 사용했는데 부트에서는 좀 더 다른 방법을 써보기로 했다.

 

다만, 아래와 같은 방법으로 하면 resultType을 hashmap이 아닌 구현한 객체 이름으로 바꿔줘야 한다.

 

1. 내가 사용한 방법은 guava 라이브러리를 활용, 따라서 build.gradle에 해당 라이브러리를 등록했다.

dependencies {
    // ...
    implementation group: 'com.google.guava', name: 'guava', version: '30.1-jre'
}

 

2. mybatis-config.xml 작성하기

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <typeAliases>
    <typeAlias type="packagename.mybatis.CamelHashMap" alias="CamelHashMap" />
  </typeAliases>
</configuration>

- 기타 설정은 필요없어서 날리고 생성할 객체만 typeAlias로 지정해주었다.

 

3. application.properties 에 mybatis-config.xml 등록하기

mybatis-config.xml 의 위치

파일의 경로를 아래와 같이 등록했다.

# Mybatis
mybatis.config-location=classpath:mybatis/mybatis-config.xml

 

4. CamelHashMap 클래스 생성 및 기능 구현

public class CamelHashMap extends HashMap<String, Object> {
  public Object put(String key, Object value) {
    return super.put(CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, key), value);
  }
}

 

5. 결과

ABC_DE가 abcDe의 형태로 변환된 결과

 

※ varchar의 결과가 위와 같이 byte 형식으로 반환된 것은 마리아db의 버전이 낮아서일까.. (10.1.x)

  10.4.x에서는 정상적인 문자열로 반환이 된다. 

  위 경우 byte 를 String 형태로 다시 변환하는 작업을 해야 하는데, 그냥 vo를 사용할까 싶다.

  (해결 방법을 도저히 찾을 수가 없음)

 

- 이상 끗

Posted by 홍규홍규
Java & Spring2019. 3. 27. 13:59

1. 기존에 오라클 또는 openjdk 구 버전이 설치되어있다면 다 삭제한다.

- openjdk-java 시리즈

# sudo apt-get remove openjdk*

- oracle-java 시리즈

# sudo apt-get remove oracle*

- 완료하고 나면 다음 명령어도 실행해주자.

# sudo apt-get autoremove --purge
$ sudo apt-get autoclean

2. oepnjdk 설치

# sudo apt install openjdk-11-jdk 

이렇게 설치하고 나서 자바 버전을 확인해보면 다음과 같이 나온다.

# sudo apt install openjdk-11-jdk
# java -version
openjdk version "10.0.2" 2018-07-17
OpenJDK Runtime Environment (build 10.0.2+13-Ubuntu-1ubuntu0.18.04.4)
OpenJDK 64-Bit Server VM (build 10.0.2+13-Ubuntu-1ubuntu0.18.04.4, mixed mode)

????

분명 11 설치했는데???

이것에 대한 이유는 다음 사이트에 가보면 대략 알 수 있다.

https://askubuntu.com/questions/1037646/why-is-openjdk-10-packaged-as-openjdk-11


그럼 실제 openjdk를 설치하려면 어떡해야 되지? 

다음과 같은 방법으로 설치하자.

# sudo add-apt-repository ppa:openjdk-r/ppa
# sudo apt install openjdk-11-jdk

자바11에 새롭게 도입된 String 클래스의 strip(), lines(), 또는 Collection에 새롭게 추가된 toArray()나 incubator에서 나온

HttpClient 같은 클래스를 사용하여 빌드할 땐 문제가 되기 때문에 11 버전으로 제대로 설치해줘야 한다.

성공적으로 설치가 된다면 다음과 같이 제대로 출력됨을 볼 수 있다.

# java -version
openjdk version "11.0.1" 2018-10-16
OpenJDK Runtime Environment (build 11.0.1+13-Ubuntu-3ubuntu118.04ppa1)
OpenJDK 64-Bit Server VM (build 11.0.1+13-Ubuntu-3ubuntu118.04ppa1, mixed mode, sharing)

- 이상 끗~!

Posted by 홍규홍규
Java & Spring2019. 2. 7. 12:54

간단하게 다음 메소드로 할 수 있다. (자바 7부터 추가)

Arrays.sort(배열); // 올림차순
Arrays.sort(배열, Collections.reverseOrder()); // 내림차순

※ 숫자는 기본이고 영문과 한글도 잘 정렬된다.




Posted by 홍규홍규
Java & Spring2019. 1. 24. 11:15
<context : annotation-config />
<context : component-scan />

두 가지는 유사하면서도 차이점이 존재한다.

둘 다 application-context에 정의해서 사용할 수 있는데 헷갈리던 부분이 있어 명확하게 다시 정리해보고자 한다.


<context : annotation-config />

이미 등록된 bean에 대해서만 Annotation을 활성화한다.

어딘가에 bean을 등록해놓으면 @Autowired와 @Qualifier Annotation을 해석해서 가져다 쓰겠다는 의미이다.

@Autowired와 @Qualifier 두 가지만 해결한다.

따라서 위 태그를 사용하더라도 xml에 bean을 반드시 선언해야 한다.

<context : component-scan/>

bean의 등록 여부와 관계없다. 스프링이 알아서 bean 스캔을 통해 Annotation을 해석하고 활성화한다.

@Autowired와 @Qualifier 뿐만 아니라 @Service, @Component, @Controller, @Repository 등 모든 클래스를 스캔하고

bean을 작성한다.

따라서 이 태그를 사용하면 위 태그는 사용할 필요가 없다.

다만 이 경우 base-package를 통해 스프링이 스캔할 패키지 위치를 지정해두는 것이 일반적이다.

<context : component-scan base-package="com.sample"/>


마지막으로 둘의 중요한 공통점은 의존 주입(DI)이다. 스프링에서 흔히 말하는 의존주입은 위 과정을 통해 일어난다.

그리고 이 의존 주입(또는 의존성 주입)은 스프링 IoC의 중요한 개념 중 하나이다.


- 이상 끗



Posted by 홍규홍규
Java & Spring2018. 3. 31. 00:36

HttpURLConnection Request Header 설정하는 방법

// HttpURLConnection 객체 생성.
HttpURLConnection conn = null;
 
// URL 연결 (웹페이지 URL 연결.)
conn = (HttpURLConnection)url.openConnection();
 
// TimeOut 시간 (서버 접속시 연결 시간)
conn.setConnectTimeout(CONN_TIMEOUT * 1000);
 
// TimeOut 시간 (Read시 연결 시간)
conn.setReadTimeout(READ_TIMEOUT * 1000);
 
// 요청 방식 선택 (GET, POST)
conn.setRequestMethod(GET);
 
// Request Header값 셋팅 setRequestProperty(String key, String value)
conn.setRequestProperty("NAME", "name");
conn.setRequestProperty("MDN", "mdn");
conn.setRequestProperty("APPID", "appid");
 
// 서버 Response Data를 xml 형식의 타입으로 요청.
conn.setRequestProperty("Accept", "application/xml");
 
// 서버 Response Data를 JSON 형식의 타입으로 요청.
conn.setRequestProperty("Accept", "application/json");
 
// 타입설정(text/html) 형식으로 전송 (Request Body 전달시 text/html로 서버에 전달.)
conn.setRequestProperty("Content-Type", "text/html");
 
// 타입설정(text/html) 형식으로 전송 (Request Body 전달시 application/xml로 서버에 전달.)
conn.setRequestProperty("Content-Type", "application/xml");
 
// 타입설정(application/json) 형식으로 전송 (Request Body 전달시 application/json로 서버에 전달.)
conn.setRequestProperty("Content-Type", "application/json");
 
// 컨트롤 캐쉬 설정
conn.setRequestProperty("Cache-Control","no-cache");
 
// 타입길이 설정(Request Body 전달시 Data Type의 길이를 정함.)
conn.setRequestProperty("Content-Length", "length")
 
// User-Agent 값 설정
conn.setRequestProperty("User-Agent", "test");
 
// OutputStream으로 POST 데이터를 넘겨주겠다는 옵션.
conn.setDoOutput(true);
 
// InputStream으로 서버로 부터 응답을 받겠다는 옵션.
conn.setDoInput(true);
 
// Request Body에 Data를 담기위해 OutputStream 객체를 생성.
OutputStream os = conn.getOutputStream();
 
// Request Body에 Data 셋팅.
os.write(body.getBytes("euc-kr"));
 
// Request Body에 Data 입력.
os.flush();
 
// OutputStream 종료.
os.close();
 
// 실제 서버로 Request 요청 하는 부분. (응답 코드를 받는다. 200 성공, 나머지 에러)
int responseCode = conn.getResponseCode();
 
// 접속 종료
conn.disconnect();

출처 : http://arabiannight.tistory.com/204

Posted by 홍규홍규
Java & Spring2017. 12. 19. 00:06

application-context.xml 에 다음을 밑줄 친 부분을 추가한다.

<beans xmlns="http://www.springframework.org/schema/beans"
    ...
    xmlns:task="http://www.springframework.org/schema/task"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context.xsd
                         ...
                        http://www.springframework.org/schema/task 
                        http://www.springframework.org/schema/task/spring-task-3.0.xsd"> 

그리고 아랫 부분도 추가해준다.

<context:component-scan base-package="패키지명" />
<bean id="scheduleJob" class="패키지명.클래스이름" />
<task:scheduler id="scheduler" pool-size="10" />
<task:annotation-driven scheduler="scheduler" /> 

xml 설정은 이걸로 끝난다. 매우 간단.

다음은 구현부인데 구현부도 간단하다.

@Component
public class Shceduler {
  
  @Scheduled(cron="0 0 1 * * *")
  public void sheduler() {
    Calendar calendar = Calendar.getInstance();
    Date date = calendar.getTime();
    String today = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
    System.out.println("스케쥴러 작동 시간 : " + today);
  }

}

클래스 위에 @Component 어노테이션을 붙여주고, 구현 메서드에도 @Scheduled 어노테이션을 붙여주면 된다.

cron 표현식은 스케쥴러가 작동하는 주기.

아래 블로그에 cron 표현식에 대해 자세하게 정리되어 있다. 


http://blog.naver.com/PostView.nhn?blogId=lovemema&logNo=140200056062


내 경우 하루에 한 번씩 주기적으로 쿼리문을 돌려야 해서 위 스케쥴러를 구현하게 되었다.


- 2019-02-19 추가

위 처럼 하면 스케쥴러가 중복실행되는 이슈가 발생한다. 

이것은 바보처럼 Scheduler 클래스에 @Component 어노테이션을 붙였기 때문인데 

xml에서 스케쥴러 세팅을 했는데도 클래스를 빈으로 등록하는 어노테이션을 선언했기 때문이다.


따라서 @Component 어노테이션은 삭제해주자...^^;;

Posted by 홍규홍규