개발 127

timestamp의 가장 큰 값

Mysql의 timestamp 컬럼을 쓰고 있는데, 큰 수의 년도를 저장하려고 시도했더니 Cause: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect datetime value: 이런 에러가 발생했다. https://dev.mysql.com/doc/refman/5.5/en/datetime.html Mysql 레퍼런스에 따르면 timestamp는 '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC. 이 시간의 범위를 저장할 수 있다고 한다. 애매한 시간인 2038년 1월 19일까지인 이유는 초를 4byte로 저장하기 때문이고, 그 max 값이 저 날짜이기 때문이다. 현재 timestamp의 가장 ..

개발/Database 2016.09.12

trim()으로 걸러내지 못하는 공백문자 정규식으로 걸러내기

우리 서비스에서 공백이름으로는 저장할 수 없도록 trim()으로 막는 곳이 있는데 클라이언트는 물론 서버에서도 걸러지지 못하고 넘어가서 DB까지 저장되어버린 공백문자를 발견했다. 그 공백 문자는 바로 유니코드(U+00A0) No-Break space였다. HTML에서 공백쓸 때 쓰던 가 이 공백문자였던거구만.. ㅋㅋ java에서 그 문자가 정말 trim으로 걸러지지 않는지 테스트를 해보자. 먼저 유니코드(U+00A0)을 UTF-8로 하면 무엇인지 본다. (http://www.utf8-chartable.de/) c2 a0이다. String utf8char = "c2 a0"; // no-break space String[] strNumbers = utf8char.split(" "); byte[] rawCha..

개발/JAVA 2016.07.22

Spring batch step loop 할 때 메모리 이슈

(한달 전에 삽질했던 내용인데 이제 씀) 지난번에 step을 loop 구조로 하는 것에 대한 포스팅을 했었다.http://marobiana.tistory.com/133 여기에는 주의해야할 점이 있다. 싱글톤 bean이 아닌 bean을 Step 단위로 loop를 돌릴 경우,Step이 수행될 때마다 새 bean이 생성되고,다음 loop로 넘어가도, 이전 스텝에서 생긴 bean은 메모리 해제가 되지 않는다. 그 bean들은 계속 누적이되어 memory leak을 일으킨다. 쓰레드덤프를 떠본 것 까진 아니지만일정한 속도로 여러번 batch를 수행시켰을 때 같은 시간 경과 후 (2시간 30분) job이 죽었다. 로그를 보니 Out of Memory였다. 나의 경우 singleton bean으로 처리하지 못했던 이..

개발/Spring Batch 2016.07.22

step을 loop 구조로 수행하기, step과 step간 파라미터 넘기기

보통은 한 step 내에서 Reader, Writer 구조로 잡고, reader 내에서 페이징을 하지만 아래 예제의 경우 한 step을 Reader처럼 두고, loop를 돌면서 Step 간의 페이징을 해볼 것이다. * 흐름에 대한 대략적인 정리라 컴파일은 따로 안해봤음 1. job.xml 설정 2. Reader Tasklet public class TestItemReaderTaskletimplements Tasklet { @Autowired private testDAO testDAO; private int pageSize; // TODO getter, setter @Override public RepeatStatus execute(StepContribution contribution, ChunkConte..

개발/Spring Batch 2016.06.22

Spring Batch 파티셔닝(partitioning) 예제(Database range query)

Batch job을 구성할 때 보통 reader - writer 구조로 작성한다.reader에서 페이징으로 row들을 읽어서, writer에서 commit interval 만큼 단건을 write 하는 방식이다. 나는 reader에서 range로 읽어서 range로 한방에 write 하려는 목적을 가지고 찾아본 결과파티셔닝이 적합해보여서 조사해보았다. 파티셔닝은 여러 일을 동시에 수행시킬 때 사용하기 유용하다. 1. 파티셔닝 (Partitioning)의 개념 파티셔닝이란, 병렬로 chunk 단위(각 slave들)을 동시에 수행하는 것이다.* chunk : reader, processor, writer를 수행하는 단위 (tasklet으로 통째로 구현하는 것도 가능) Master가 Partitioner로 각 ..

개발/Spring Batch 2016.05.25

Java의 Integer, int 숫자 비교의 주의사항

예전에 프로그램에 버그가 있었고 원인을 한참을 못찾은적이 있었다.숫자 비교하다 생긴 문제였고, 무심코 코딩하다 틀리고 삽질할 수 있는 부분이라 블로그에 남겨본다.ㅎㅎ 아래는 숫자를 저장하는 3가지 방법이다. int a = 1;Integer b = 1;Integer c = new Integer(1); if (a == 1) => true if (b == 1) => trueif (c == 1) => true a, b, c 모두 숫자 1인지 비교해보면 결과는 true이다. 그럼 변수끼리 비교해보겠음 1) int VS Integer int a = 1;Integer b = 1; if (a == b) => true 2) int VS Integer int a = 1;Integer c = new Integer(1); i..

개발/JAVA 2016.03.30

구아바(Guava)를 이용하여 List의 특정값 추출해서 새로운 List 만들기

구글의 구아바(Guava)를 이용하면 Collection을 간편하게 처리할 수 있다. 앞에 글에서는 리스트에 있는 값을 특정 Precate로 필터링 하는 법을 설명했는데, 이번에는 필터링이라기 보다는, 어떤 리스트를 어떤 새로운 객체의 리스트로 변환한다고나 할까? 1. List에 들어있는 어떤 값을 추출해서 새로운 List로 만들기 아래는 List 리스트를 유저의 숫자 아이디만 뽑아서 List로 만드는 예제이다. List users = ... List userIds = Lists.transform(users, new Function() { @Override public Integer apply(User user) { return user.getUserId(); } }); 이 기능의 핵심 메소드는 바로 구..

개발/JAVA 2016.03.25

구아바(Guava) Iterables.filter를 사용해서 리스트 필터링 하기

구글에서 제공하는 라이브러리인 구아바(Guava)를 사용하면 java의 Collection을 간편하게 활용할 수 있다. 이번 글에서 설명할 것은 리스트의 값을 특정 조건으로 필터링 하는 예제이다. 1. List에서 null값 모두 제거하기 List users = Lists.newArrayList(Iterables.filter(users, Predicates.notNull())); 여러 메소드가 있으니 맨 안쪽부터 뜯어서 보자. 1-1 Iterables.filter(users, Predicates.notNull()) 구글에서 제공하는 Iterables의 filter 메소드의 파라미터는 unfiltered, predicate 라고 나와있다. Iterables.filter(필터링할 리스트, 필터 조건) 역시 ..

개발/JAVA 2016.03.25

Spring Batch decision으로 step 결정하기

보통은 step1 수행 -> step2 수행 -> step3 수행 이렇게 순차적으로 수행한다.실행되는 스텝이 내가 할일 끝나고 나면 다음 스텝을 지정해서 다음 스텝을 실행시킨다. 이번에 포스팅할 예제는step1 step2 가 있을 때 이런 규칙이 있다고 치자. - step2만 실행- step1 -> step2 : step1가 성공해야만 step2를 실행한다. skip1를 스킵할지 말지는 skipFlag의 값으로 분기할 것이다. decision 을 이용해서 스텝을 결정할 수 있다.설정은 아래와 같음. job.xml * step1을 스킵하고 step2만 실행하는 경우 decider1에서 skipFlag가 true이면, step2로 갈 수 있도록 한다. * step1 -> step2 인 경우 decider1에..

개발/Spring Batch 2015.10.29

(MyBatis) Mysql tinyint(1) boolean이 integer로 바뀌는 현상

Mysql의 컬럼 타입 중 tinyint(1)은 0이면 false, 0보다 크면 true를 반환하므로, boolean으로 주로 사용하고 있다. query.xml SELECT test_yn FROM test LIMIT 1 DAO.java public Map selectYn() { return sqlSessionTemplate.selectList("selectYn"); } 이해하기 쉽게 boolean 컬럼 한 행을 가져오는 쿼리로 예를 들어봤다. test_yn이 tinyint(1) 이라면 나는 결과 값을 hashmap으로 받았으니 {"test_yn" : false} 이런식으로 받아질 것이고, Boolean으로 캐스팅해서 test_yn 값을 쓸 수 있다. 그런데 쿼리를 아래와 같이 바꿔보았다. SELECT t..

개발/Database 2015.09.17