반응형

리눅스에서 Junit 테스트를 해야할 경우가 있는데 테스트 할 때 필요한 라이브러리들 입니다.

스프링 부트 이용시 기준 입니다.

tomcat-embed-core 의 경우 테스트 환경에 servlet이 포함된 경우 필요합니다.


assertj-core-2.5.0.jar  
junit-4.12.jar                              
spring-boot-test-1.4.2.RELEASE.jar                
spring-test-4.3.4.RELEASE.jar
hamcrest-core-1.3.jar   
spring-boot-starter-test-1.4.2.RELEASE.jar  
spring-boot-test-autoconfigure-1.4.2.RELEASE.jar  
tomcat-embed-core-8.5.6.jar



실행시에는 아래와 같이 org.junit.runner.JUnitCore 클래스를 메인 클래스로 args를 테스트할 클래스로 지정하면 됩니다.

TEST_CLASS=com.tistory.goni9071.Test
CP=클래스패스
$JAVA_HOME/bin/java -cp $CP org.junit.runner.JUnitCore $TEST_CLASS


반응형
반응형

분명 어제까지 문제 없던 프로젝트 였는데 오늘 갑자기 빌드 오류가 발생합니다. ㅎㄷㄷ


1
2
The project was not built since its build path is incomplete. Cannot find the class file for org.springframework.core.io.support.PropertySourceFactory. 
The type org.springframework.core.io.support.PropertySourceFactory cannot be resolved. It is indirectly referenced from required .class files    MainApplication.java    


대체 왜? 아무리 생각해도 모르겠습니다.


그렇게 이것 저것 원인을 추측하며 구글링하던 중

1
mvn dependency:purge-local-repository


이 놈을 찾아 내었습니다. 


두둥.


maven 중에 위 명령어를 실행하면 해당 pom.xml 에 명시된 dependency 들에 대해서 Local(~/.m2/repository)에 다운 받아 놓은 라이브러리들을 모두 지우고 다시 받아 줍니다. 


cache를 clean하고 re download 하는 거죠.


그랬더니 거짓말처럼 오류가 사라졌네요. @@

뭘까 대체..

반응형
반응형

스프링 부트의 기본 커넥션 풀이 원래 Tomcat JDBC Connection Pool 이었는데 2.0.0 버전 부터 HikariCP 로 변경 되었습니다.


1.5.9 RELEASE

29.1.2 Connection to a production database

Production database connections can also be auto-configured using a pooling DataSource. Here’s the algorithm for choosing a specific implementation:

  • We prefer the Tomcat pooling DataSource for its performance and concurrency, so if that is available we always choose it.
  • Otherwise, if HikariCP is available we will use it.
  • If neither the Tomcat pooling datasource nor HikariCP are available and if Commons DBCP is available we will use it, but we don’t recommend it in production and its support is deprecated.
  • Lastly, if Commons DBCP2 is available we will use it.

If you use the spring-boot-starter-jdbc or spring-boot-starter-data-jpa ‘starters’ you will automatically get a dependency to tomcat-jdbc.



2.0.0 RELEASE

29.1.2 Connection to a Production Database

Production database connections can also be auto-configured by using a pooling DataSource. Spring Boot uses the following algorithm for choosing a specific implementation:

  1. We prefer HikariCP for its performance and concurrency. If HikariCP is available, we always choose it.
  2. Otherwise, if the Tomcat pooling DataSource is available, we use it.
  3. If neither HikariCP nor the Tomcat pooling datasource are available and if Commons DBCP2 is available, we use it.

If you use the spring-boot-starter-jdbc or spring-boot-starter-data-jpa “starters”, you automatically get a dependency to HikariCP.


그래서 2.0 버전 부터는 Tomcat JDBC Connection Pool 을 쓰려면 몇 가지 설정 추가해야 합니다.


application.properties 에서 어떤 데이터소스를 사용할지 명시해야 합니다.

1
spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource


그리고 tomcat-jdbc 라이브러리도 가 추가 되어야합니다. 

<maven - pom.xml>

1
2
3
4
5
6
    <!-- tomcat-jdbc -->
    <dependency>
      <groupId>org.apache.tomcat</groupId>
      <artifactId>tomcat-jdbc</artifactId>
      <scope>provided</scope>
    </dependency>



application.properties 에 tomcat connection pool 설정입니다. 위의 2가지를 설정하지 않으면 아래 설정이 동작하지 않습니다.

1
2
3
4
5
6
7
8
9
spring.datasource.tomcat.max-active=50
spring.datasource.tomcat.max-idle=50
spring.datasource.tomcat.min-idle=10
spring.datasource.tomcat.max-wait=-1
spring.datasource.tomcat.initial-size=10
spring.datasource.tomcat.test-on-borrow=true
spring.datasource.tomcat.test-while-idle=true
spring.datasource.tomcat.validation-query=select 'GONI'
spring.datasource.tomcat.time-between-eviction-runs-millis=3000


반응형
반응형

구문

 기존 데이터가 없으면

기존 데이터가 있으면 

 INSERT IGNORE

데이터 입력 

row affected 1

무시

row affected 0 

 REPLACE INTO

데이터 입력 

row affected 1

기존 데이터 삭제 후 입력
row affected 2

AUTO_INCREMENT 필드가 있다면 값이 바뀝니다.

 ON DUPLICATE UPDATE

데이터 입력 
row affected 1

기존 데이터 수정
row affected 2




<Create Script>

1
2
3
4
5
6
CREATE TABLE `CAR` (
  `ID` INT NOT NULL AUTO_INCREMENT,
  `COLOR` VARCHAR(45NOT NULL,
  `NUMBER` VARCHAR(45NOT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE INDEX `NUMBER_UNIQUE` (`NUMBER` ASC));


** 주의 사항 : Primary Key 혹은 Unique Index 필드를 기준으로 중복 체크를 하게 됩니다.


<Data Insert> - 최초 데이터 입력

1
2
INSERT INTO CAR (COLOR, NUMBER) VALUES ('RED''1234');
INSERT INTO CAR (COLOR, NUMBER) VALUES ('BLUE''7777');


<Result> 

IDCOLORNUMBER
1RED1234
2BLUE7777

* 각각 1 row affected



<Data Insert Ignore> - INSERT IGNORE 중복 입력

1
2
INSERT IGNORE INTO CAR (COLOR, NUMBER) VALUES ('RED''1234');
INSERT IGNORE INTO CAR (COLOR, NUMBER) VALUES ('BLUE''7777');



<Result> 

IDCOLORNUMBER
1RED1234
2BLUE7777

* 각각 0 row affected

* 데이터 변화 없음.



<Data Replace> - Replace 중복 입력

1
2
REPLACE INTO CAR (COLOR, NUMBER) VALUES ('RED''1234');
REPLACE INTO CAR (COLOR, NUMBER) VALUES ('BLUE''7777');


<Result> 

IDCOLORNUMBER

5

RED1234

6

BLUE7777

* 각각 2 row affected - 기존에 데이터가 없으면 1 있으면 2 row affected

* ID값이 mysql ver 5.1.73 에서는 3, 4, mysql ver 5.6 에서는 5, 6이 된다. INSERT IGNORE 에서 Auto Increment 되는지 여부가 달라지는 것 같다.



<Data Insert On Duplicate Key Update> - Insert On Duplicate Key Update 중복 입력

1
2
INSERT INTO CAR (COLOR, NUMBER) VALUES ('RED''1234'ON DUPLICATE KEY UPDATE COLOR='PINK';
INSERT INTO CAR (COLOR, NUMBER) VALUES ('BLUE''7777'ON DUPLICATE KEY UPDATE COLOR='GREEN';


<Result> 

IDCOLORNUMBER

5

PINK1234

6

GREEN7777

* 각각 2 row affected - 기존에 데이터가 없으면 1 있으면 2 row affected

* ID 값은 변화가 없고 COLOR만 UPDATE 되었다.



이곳에서 테스트 및 확인이 가능합니다.

http://sqlfiddle.com/#!9/9fd7b7/1


반응형
반응형

11자리 번호와 10자리 번호 모두 됩니다.


[>999999999]0##-####-####;0##-###-####


대상이 텍스트 서식으로 된 셀이라면 =TEXT(대상셀, "[>999999999]0##-####-####;0##-###-####") 이렇게 변환해서 사용하면 됩니다.

반응형

'Tool' 카테고리의 다른 글

윈도우 JEUS 6.0 설치  (0) 2018.10.10
SQL DEVELOPER 날짜형식 변경하기  (0) 2018.10.08
Tibero Admin Tool 설치  (0) 2018.09.30
리눅스 Tibero5 SP1설치  (0) 2018.09.30
SQLGate for DB2 무료 설치  (0) 2018.06.04
bower 설치  (0) 2018.05.25
STS - no prefix constructor completions  (0) 2018.05.24
problem during content assist in eclipse  (0) 2018.05.16
반응형

fasterxml 을 이용해 JSON 문자열을 객체로 변환하는데 단순 Snake Case 가 아닌 대문자 Snake Case 인 경우 아래 코드처럼 참고해 네이밍 전략을 수정해주면 됩니다.


2018/06/18 - [기타] - 스네이크 표기법 Snake Case



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
 
import java.io.IOException;
 
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy.SnakeCaseStrategy;
 
 
public class Test{
  private static UpperCaseStrategy UPPER_CASE = new UpperCaseStrategy();
 
  public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setPropertyNamingStrategy(UPPER_CASE);
    Code code = mapper.readValue("{\"CODE\": \"A01\", \"CODE_MSG\":\"청하\"}", Code.class);
    System.out.println("code : " + code.getCode());
    System.out.println("codeMsg : " + code.getCodeMsg());
  }
 
  public static class Code {
    private String code;
    private String codeMsg;
 
    public String getCode() {
      return code;
    }
 
    public void setCode(String code) {
      this.code = code;
    }
 
    public String getCodeMsg() {
      return codeMsg;
    }
 
    public void setCodeMsg(String codeMsg) {
      this.codeMsg = codeMsg;
    }
 
  }
 
  public static class UpperCaseStrategy extends SnakeCaseStrategy {
    /**
     * 
     */
    private static final long serialVersionUID = -284516094725996654L;
 
    @Override
    public String translate(String input) {
      return super.translate(input).toUpperCase();
    }
  }
 
}
 


반응형
반응형


RestTemplate 설정 예제


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
    // 읽기타임아웃 - 5초동안 연결은 되었지만 처리 속도가 느려 응답 없으면 타임아웃
    factory.setReadTimeout(5000); // milliseconds
    // 연결타임아웃 - 5초동안 연결이 되지 않으면 타임아웃(잘못된 주소 연결 혹은 서비스 다운)
    factory.setConnectTimeout(5000);// milliseconds
 
    // 커넥션 풀 설정
    HttpClient httpClient = HttpClientBuilder.create()//
        .setMaxConnTotal(50)// IP:PORT 관계없이 전체 커넥션 수
        .setMaxConnPerRoute(50)// IP:PORT 마다 커넥션 수
        .build();
    factory.setHttpClient(httpClient);
    // 커넥션 풀 설정
 
    RestTemplate restTemplate = new RestTemplate(factory);
 
    HttpClientContext context = HttpClientContext.create();
    restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory() {
      @Override
      protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
        if (context.getAttribute(HttpClientContext.COOKIE_STORE) == null) {
          context.setAttribute(HttpClientContext.COOKIE_STORE, new BasicCookieStore());
          Builder builder = RequestConfig.custom()
              // .setCookieSpec(CookieSpecs.IGNORE_COOKIES)
              // .setAuthenticationEnabled(false)
              .setRedirectsEnabled(false);
          context.setRequestConfig(builder.build());
        }
        return context;
      }
    });



http client

1
2
3
4
    <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpclient</artifactId>
    </dependency>


import

1
2
3
4
5
6
7
8
9
10
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.protocol.HttpContext;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;


반응형
반응형
 

 

Controller

 

 

 

Entity

 

 

List Wrapper

 

 

 

** 이거 사용하다 보니 문제점이 있어서 추가 공유합니다.

 

1. data["종목목록[" + index + "].종목코드"]  이렇게 쓰는데 index가 1부터 1000 였습니다.

- 그런데 순서대로 넣었음에도 불구하고 Spring에서 자동으로 List 객체에 넣는 과정에서  1다음에 바로 1000을 넣으려고 하면서 인덱스 오류가 발생합니다.

- 해결법은 0001, 0002, ... , 1000 이렇게 하면 순서대로 들어가서 이 오류가 발생하지는 않습니다.

 

2. AbstractNestablePropertyAccessor 클래서 List로 자동 맵핑 해주는데 autoGrowCollectionLimit 이런 속성에 의해서 기본 최대 값이 256 입니다.

- 그래서 이 방식으로는 최대 256개 파라미터 밖에 넘기지 못합니다.

- 뭐 InitBinder를 통해서 수치를 재설정 할 수 있다고 하지만 별로 그렇게까지 하고 싶지는 않네요.

 

** 256개가 넘는 건 그냥 문자열로 붙여서 split 해서 처리했습니다.

반응형

'스크립트' 카테고리의 다른 글

javascript cookie getCookie setCookie  (0) 2018.11.05
netstat unique ip  (0) 2018.09.10
javascript java rsa  (0) 2018.08.13
aes256 cbc javascript and java  (0) 2018.08.09
javascript object size  (0) 2018.07.23
jquery ajax ie no transport error  (0) 2018.07.17
윈도우 netstat grep wc 포트 커넥션 확인  (0) 2018.07.09
리눅스 프로세스 생성 스크립트  (0) 2018.06.29
반응형
 
 

 

 
반응형
반응형

grep 에서 정규식을 쓰려면 -E 옵션을 추가하면 됩니다.



tail -f debug.log |grep -"^(START|REMOTE)"



이런 식으로 사용할 수 있습니다.


debug.log 에서 START 시작하거나 REMOTE로 시작하는 줄만 tail 하겠다.

반응형

+ Recent posts