2015의 게시물 표시

gitup.co

http://gitup.co/ git을 사용하다보면 commit을 수정하거나, 나누기, 합치기 등등의 작업을 해야할때 있다. 이때 rebase 등의 명령을 사용해서 작업을 하는데 git 명령어를 완벽하게 이해하지 못한 상태에서 작업을 하다보면 commit을 날려먹는 등의 실수를 할수 있다. 물론 reflog 등을 사용해서 복구는 가능하지만 그 작업 또한 쉽지 않다. gitup은 gui 환경에서 rebase를 할수 있는 툴이라고 생각하면 될듯. cmd+z/cmd+shift+z 를 통해서 언제든지 작업을 redo/undo 할수 있다. commit 메시지를 조금 수정하고 싶을뿐인데 rebase 명령어가 어렵다고 생각되면 이 툴을 사용하면 된다.

Hibernate(Criteria) having절 사용하기

criteria에서 having절을 사용할수 있는 방법이 없는듯!? 고민고민하다가 방법이 떠오름. criteria.add(Restrictions.sqlRestriction(" 1=1 having sum(EXPOSE) > 0"));

네이밍, 이름짓기

단어선택의 문제가 아니다. 어떤 단어(용어)를 사용할지는 정하기만 하면 문제가 안된다. 네이밍과 관련된 문제는 다른데서 발생한다. 바로 혼란스러움이다. 혼란을 만드는 경우는 두가지가 있다. 첫번째는 줄임말, 두번째는 대소문자이다. 1. 줄임말 vld로 할지 valid로 할지 정해야 한다. 이것은 프로젝트 전반에 줄임말을 허용할지 말지의 문제이다. 허용한다면 사용가능한 줄임말을 명확하게 정해야 한다. 줄임말은 최소한으로 사용하는게 좋다. vld가 당장은 문제가 없어 보이지만 invalid라는 단어가 추가되었을 경우 어떻게 할것인가? vld와 invalid라는 단어가 공존하는 순간 혼란은 시작된다. 2. 대소문자 username으로 할지 userName으로 할지 정해야 한다. DB의 컬럼명이 USERNAME이라면 변수명도 username이라야 한다. 컬럼명이 USER_NAME이라면 변수명은 userName이라야 헤깔리지 않는다. 그렇다면 unserscore 또는 대문자를 언제 사용해야 할까? 그것도 정해야 한다. 결국  일관성 이다. 이름짓기는 일관된 규칙이 있어야 한다. 일관성을 위해 prefix 또는 suffix를 사용하는 것은 좋은 아이디어다. 하지만 남용하면 안된다. 필요한 곳에 써야 한다. 일관성은 팀단위가 될수도 있고 프로젝트 단위가 될수도 있다. 그 범위 안에서 지켜져야 한다. 예외는 없어야 한다. 예외가 발생하는 순간 혼란이 시작된다. 만약 예외가 생겼다면 그 예외 조차도 일관성이 있어야 한다. 적절한 네이밍인지 여부는 시간이 지나야 알수 있다. 로직을 개선하듯이 네이밍도 꾸준히 개선되어야 한다.

Spring Security vs Apache Shiro

Spring Security Apache Shiro 버전 4.0.2 1.2.3 장점 Spring-based 어플리케이션에서 잘 동작한다. ㄴ 타 Spring 모듈과 디펜던시가 없다. Spring 이라는 이름빨이 있다. 커스터마이징을 통한 다양한 니즈에 대응 가능. ㄴ 클래스 상속을 통한 확장이 용이하다. ㄴ 그만큼 진입장벽이 높다는 의미 사용하기 쉽다(고 한다. 사용안해 봐서 아직은 모르겠음)  ㄴ 대체로 스프링 시큐리티보다는 훨씬 쉽다는 의견 Spring-based 어플리케이션 뿐만 아니라 다양한 환경에서 동작한다. 단점 배우기 어렵다. 용어가 어렵다.(잉글리쉬 네이티브들도 어렵다고 하는데 하물며..) 버전 3.x 으로 오면서 개선이 되었다고는 하지만, 여전히 복잡하고 어려운 XML 설정 OAuth, Digest Authentication 공식적으로는 미지원 ㄴ 비공식  https://github.com/FeedTheCoffers/shiro-oauth ㄴ 당장 필요한 기능은 아님 레퍼런스 많다. 많이 쓰니까.. ㄴ  http://spring.io/guides 부족하진 않은거 같은데? ㄴ 개발하면서 트러블이 생겨봐야 알수 있을듯 ㄴ  http://shiro.apache.org/documentation.html 사내 레퍼런스 많다. 없다.  - 사내 깃헙 검색해보니 조금 나오긴 한다.

Spring Boot + Hibernate + DBUnit + HSQLDB Example

https://github.com/ekcode/spring-boot-dbunit-example

Spring Boot 시작하기

새로운 프로젝트를 셋업할때 AS-IS 1. 기존에 있던 프로젝트 중에서 적당한걸 고른다. 그리고 pom파일을 ctrl+c, ctrl+v 한다. 2. 더 필요한 라이브러리가 있으면 추가한다. 3. 아파치 톰캣 설정을 한다. 4. 서버를 띄워본다. 5. 에러가 난다. 6. 각종 설정 파일 수정 및 라이브러리 버전을 바꿔본다. 7. 에러가 안날때까지 반복한다. 문제점 1. 사용하지 않는 불필요한 디펜던시가 pom에 추가된다. 2. pom에 이것저것 추가하다 보면 디펜던시가 충돌난다. 3. pom.xml 이 엄청 길어진다. 4. 어지간해서는 스프링 및 기타 라이브러리의 버전을 바꾸지 않는다. (괜히 버전 올려서 에러라도 나면..) 5. 서버 띄우기가 힘들다. (nodejs, rails 등을 생각해보면...) 처음 한두번은 뭔가 배울게 있을지 몰라도 몇번 하다보면 지루한 단순반복작업일 뿐이다. TO-BE Spring Boot 참고 http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/   준비물 JDK1.6+ Intellij 14.1(버전업이 되면서 Spring-boot가 추가되었다.) 시작하기(셋중 하나로 시작하거나 아니면 복붙하던가..) - Spring CLI  -  https://start.spring.io - Intellij > Spring Initializer 프로젝트를 생성하고 실행한다. 이렇게 나오면 일단 성공이다. 톰캣8이 포함되어 있기 때문에 따로 톰캣을 설치하지 않아도 실행할수 있다. 외부 톰캣 컨테이너에서 실행시키기려면 약간의 추가 작업이 필요하다. scope를 provided로 설정해야 한다.  그리고 SpringBootServletInitializer를 상속받게 수정한다.

cd ../../../../ 쉽게 하기

뭐 대단한 방법이 있는건 아니고 alias ..="cd .." alias ...="cd ../.." alias ....="cd ../../.." alias .....="cd ../../../.." alias ......="cd ../../../../.." 이렇게 설정해두고 (익!숙!해지면) 편리하다.

Mac에서 java_home 확인하기

mac에 java8을 설치했는데 기존의 java6가 있던 위치랑 전혀 다른곳에 있더라. /usr/libexec/java_home 을 실행시켜 보니 java8이 설치된 경로가 표시된다.(JAVA_HOME) https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/java_home.1.html

ssh 접속할때 private key 지정하기

-i 옵션 ssh -i /path/to/id_dsa ricardo@123.12.12.12 또는 .ssh/config에 설정하면 된다.

JSONP with Jersey 2.0

Jersey는 JAX-RS 구현체이다. 여기에 더해서 몇가지 추가적인 기능을 자체적으로 제공하는데 JSONP 어노테이션도 그중에 하나. 스프링이든 뭐든 JSONP를 구현하려면 이래저래 잡다한 코드가 들어가야 한다. Jersey 1.x 에서도 상황이 크게 다르진 않았는데 2.x부터는 @JSONP 어노테이션이 추가되어서 간단하게 JSONP를 구현할수 있다! https://jersey.java.net/apidocs/2.0/jersey/org/glassfish/jersey/server/JSONP.html 그냥 @JSONP를 붙히기만 하면 된다. callback 함수 이름을 지정하려면 callback 속성을 지정하면 되고 디폴트값은 "callback"이다. callback 함수를 queryParam에서 가져올수도 있다. 즉, queryParam이 설정되어 있으면 그걸 쓰고 없으면 callback 속성을 사용한다. @GET @Path("/get") @JSONP(queryParam="callback") @Produces({"application/x-javascript"}) public MediaInfo getMediaInfo(@QueryParam("callback") String callback) { return new MediaInfo("imbc"); } }

spring-boot profile 셋팅해서 서버 띄우기

mvn spring-boot:run -Drun.jvmArguments="-Dspring.profiles.active=development"

8080포트 사용중인 프로세스 찾기 on Mac

lsof -i tcp:8080

하이버네이트, 데이터 변경 이력 남기기

입력/수정/삭제에 대해  히스토리을 남기고 싶다.  - 속성, 이전값, 변경값 https://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/Interceptor.html 간단히 EmptyInterceptor를 오버라이드해서 쓰면 된다. [설정, hibernate 4.2는 이렇고 3.x는 설정이 다르다. 인터셉터 구현 패턴의 변경]     <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">         <property name="dataSource" ref="dataSource"/>         <property name="entityInterceptor" ref="historyInterceptor"/> 1. 입력 onSave(...) 2. 수정 onFlushDirty(...) 3. 삭제 onDelete(...) 4. 컬렉션 입력/수정/삭제 onCollectionRecreate(...), onCollectionUpdate(...), onCollectionRemove(...) 5. 기타 등등 많이 있음. 이상한점 1 객체가 컬렉션일때(OneToMany) 그 객체들을 삭제하려면? 1. Set.remove(o)를 하면 삭제가 안된다. 왜 안되는지 모르겠다. 2. Set.removeAll(..) 을 해야 삭제가 된다. 그런데 Set 전체를 삭제해야 한다. 일부만 삭제하면 삭제가 안된다. 이건 뭥미?? 3. 위와 같은 경우에 인터셉터에 걸리지 않는다. 삭제가 안되었으니까 .. 이상한점 2 afterTransactionBegin(), afterTransactionCompletion(), before