<01. 웹 프로젝트 생성>



<02. Project 설정>
중간에 보이는 Configuration을 바꿔주어야 한다.
여기서 그냥 Finish를 눌러서 프로젝트 정보에서도 가능하나, 만들때 하기로 한다.

Modify를 누러서 진행 

<03. JPA 설정>
JPA를 선택하고 Runtimes에 Tomcat을 선택한다. 현재 JPA Version은 2.0으로 되어 있다. 

<04. JPA Library 다운로드>
플랫폼은 EclipselInk 2.4를 사용할 것이고 해당 라이브러리는 Download 버튼을 누르면 아래처럼 창이 나온다. 

<05. Library 다운로드>
각 환경에 맞는 EclipseLink를 선택한 후 Next를 눌러 다운로드를 완료한다. 

<06. 추가 라이브러리 설정>
JPA에 필요한 Hibernate 관련 라이브러리를 추가해주어야 한다. 
다운로드 버튼 위 라이브러리 구성 화면으로 들어가 아래 화면으로 이동한다.

이 화면에서 Add External JARs로 이동해 HIbernate JAR 파일을 추가해준다.
최신 라이브러리를 넣으면 되며 라이브러리는 www.hibernate.org 에서 구할수 있다. 

<07. 라이브러리 추가>
OK를 누르고 Finish를 누른다.
06 화면에서 라이브러리 설정 아래 Connection이 있는데, MySQL로 설정을 해주자.
Add Connection을 눌러 아래 화면으로 이동한다.
 

<08. MySQL Connection 추가>
Name을 바꿔주고 Next 

<08-1. Driver 추가 및 설정>
기존에 만들어 놓은게 있어 나타나지만, 처음 만들경우 아무것도 나타나지 않는다.
Drivers 우측에 있는 + 아이콘을 눌러 추가 화면으로 이동한다. 

<08-2. DB Connection 정보 입력>
자신의 정보에 맞게 입력해준다. 

<08-3. 완료된 설정 화면>

<09. 프로젝트 생성 완료 화면>
Finish를 눌러 프로젝트 생성을 완료한다. 

Server OS : Ubuntu 10.04
MySQL : 5.5.28, for debian-linux-gnu (x86_64) using readline 6.2


MySQL 역시 샘플 DB를 제공한다.

160MB 정도의 대용량을 샘플로 제공하는데, 이를 통해 JPA 프로젝트 생성을 할 수 있다.
샘플 DB의 Table역시 각 관계가 설정되어 있어 JPA에서 관계를 어떻게 표현하는지 알 수 있기에 다른 샘플 DB보다 적합하다.

자세한 것은 아래 URL을 참조.
http://dev.mysql.com/doc/employee/en/employees-introduction.html 

MySQL Example Database download
https://launchpad.net/test-db/employees-db-1/1.0.6/+download/employees_db-full-1.0.6.tar.bz2

실행 법은 압축을 풀고 콘솔창에서 mysql -u root -p employees < employees.sql 
sql 파일 하나만으로는 불가능하다.
sql을 살펴보면 dump 내용을 복원하는 것이기 때문에 압축 파일 내의 모든 파일이 필요하다.

DB 생성 후 각 테이블을 살펴보면..

select count(dept_no) from departments  -- 9
select count(emp_no) from employees  -- 300024
select count(emp_no) from dept_emp -- 331603
select count(dept_no) from dept_manager -- 24
select count(emp_no) from salaries -- 2844047
select count(emp_no) from titles -- 443308

자료가 상당히 많아서 아주 좋다.

 


  top_vacancy = 'Y',

'Framework > myBatis' 카테고리의 다른 글

MyBatis 3.2) Mapper 방식과 DAO Pattern은 같이 사용할 수 없다.  (0) 2013.07.19
프로시저 호출 시 주의 할 점..  (0) 2012.11.13
iBatis isEqual  (0) 2012.11.05
[3.0] forEach 사용  (0) 2010.07.15
[3.0] like 검색.  (0) 2010.07.09
[3.0] JDBC Type  (0) 2010.07.09
http://download.eclipse.org/rt/eclipselink/updates/ .
원글 : http://techblog.bozho.net/?p=358)**

이 글을 Korea Spring User Group의 송준이 <socurites@gmail.com>  님이 번역을 하여 글을 퍼옵니다.


 *지독하게 해로운 프레임워크, 그리고 복잡함*
     
    *(*http://techblog.bozho.net/?p=358)**
     
    2011년 4월 29일
      
    하이버네이트와 스프링같은 프레임어크는 업계 표준이다. JSF, EJB 등도 또한 업계 표준으로 많은 어플리케이션에 사용된다. 하지만
    프레임워크 사용을 반대하는 사람들은 항시 있기 마련이다. 다루려는 주제는 "언어 불가지론(language-agnostic)"에 대한
    것이고 자바를 예로 들겠지만, 모든 언어에 적용되는 내용이다.
     
     
    프레임워크를 반대하는 일반적인 근거는 다음과 같다.
     
    - 프레임워크는 매우 복잡하고, 사용할 필요가 없다
     
    - 더 효과적인 프레임워크를 직접 만들 수 있다.
     
    - 프레임워크가 품질이 높을 것 같지 않으며, 필요한 작업을 해줄 것 같지도 않다.
     
    - 프레임워크를 추가적으로 배울 필요가 없으며, 코어 자바로도 충분하다.
     
    - "프레임워크가 그렇게도 좋아?"라는 말을 한번도 들어본적이 없다.
     
      
    안타까운 점은 이렇게 믿는 사람들과 말이 통하지 않는다는 점이다. 게다가 이 부류의 사람들이 프로젝트를 이끄는 리더거나 아키텍트가
    되버리면, 결국 프로젝트는 망한다. 그래도 오해는 하지 말기 바란다. 이들 프레임워크를 사용하지 않고도 성공하는 프로젝트도 꽤 있다. 하지만
    이 프로젝트들은 일반적인 경우는 아니다. 위의 논거들을 조목조목 다뤄보도록 하자.
     
     
    "프레임워크는 매우 복잡하고, 사용할 필요가 없다" - 복잡도는 사실 프레임워크에서 나타나는 문제점이다. 프레임워크를 처음 익힐 때는
    일주일이 걸린다. 하지만 시작할 때만 어려울 뿐이고, 한번 익히고 나면 팀은 프레임워크를 능숙하게 다룰 수 있게 된다. 결국 특정
    수준정도로 어려울 뿐이다. 내 경험을 빌려 이 점을 확실히 알 수 있다. 지금 일하는 회사에 왔을 때, 회사에서는 스프링과 하이버네이트를
    사용해 대규모의 프로젝트를 진행하고 있었다. 일주일 가량 지나자 나는 이 프로젝트에서 무엇이든 변경할 수 있게 되었다. 스프링을 적용한
    프로젝트는 복잡도가 증가하는 게 아니라 그저 규모가 커질 뿐이고, 복잡도는 특정 수준에 그칠 뿐이다. 이 복잡도는 알고리즘에 관련된게
    아니라, 구조와 설정에 관련된다.
     
      
    다음으로 "더 효과적인 프레임워크를 직접 만들 수 있다"는 주장이 가진 문제점을 살펴보자. 프레임워크를 직접 만들게되면, 복잡도는 한없이
    증가하기 쉽다. 항상 그렇지는 않지만, 직접 프레임워크를 만들고 바귀를 다시 발명하게 되면 프로젝트를 유지하기에 어려울 때가 많다.
     
      
    일하는 팀이 5명내지 6명으로 구성되고, 팀원은 비즈니스 가치를 이끌어내야지 프레임워크를 작성할 시간이 부족하다는 점은 말할 필요도 없다.
    오픈소스 프레임워크에 수천 시간을 들이고, 이 프레임워크를 개발하고 생길 수 있는 모든 종류의 이슈와 문제점을 찾느라 수백만 시간을
    들였다는 점을 생각해볼 때, "프레임워크가 품질이 높을 것 같지 않으며, 필요한 작업을 해줄 것 같지도 않다"는 주장은 근거가 없어
    보인다. 널리 쓰이는 프레임워크는 평범한 팀에서 프로젝트 일정에 맞춰서 만들 수 있는 프레임워크이 비해 품질이 훨씬 높다.
     
     
     하지만 다른 방향에서 접근하는 사람들도 있기 마련인데, 바로 "과도한 설계'다. 내 생각에 과도한 설계는 프로젝트에서 있을 수 있는 가장
    큰 문제다. 그리고 "프레임워크를 추가적으로 배울 필요가 없으며, 코어 자바로도 충분하다"는 근거가 요점을 제대로 짚은 것처럼 보인다. 하지만
    이 주장은 "능력이 부족하거나 배울 실력이 안되며 배우고자하는 의지가 없다"는 말을 속여서 말한 것에 지나지 않는다. 나는 프레임워크에
    대해 불평하는 일(stackoverflow.com에 있는 질문들을 포함해)을 많이 봐왔다. 스프링은 쓸데 없이 복잡하고
    비대해졌으며, 하이버네이트는
    제어권을 개발자로부터 빼았고, 문제점들을 많이 만들어낸다는 것이다. 왜 이들 주장이 확실히 잘못된 것인지는 설명하지 않겠다. 하지만
    사람들이 이들 프레임워크를 잘 이해하지 못했기에 이처럼 주장하는 것이다. 그리고 겉보기에 더 쉬운 방법을 선택하게 되면 결국 실망만
    가져올 뿐이다.
      
     
    반대로 잘 알지도 못하면서 프레임워크가 유행하기 때문에 도입하려는 사람들도 있다. 결국 이들은 프레임워크를 비난하게 된다. 이들 사이에
    공통적인 테마가 있음을 알 수 있다. 문제는 프레임워크가 아니라, 프레임워크를 이해하지 못하는 사람이다.
      
     
    그렇긴 해도 프레림워크는 모두 훌륭하다는 뜻은 아니다. EJB2는 별로였다. 스트럿츠 1도 벼로였다. 하지만 프레임워크를 비난한 입장이
    되려면 진짜 문제가 무엇인지 그리고 어떻게 고쳐야 하는지 알아야만 한다. 개빈 킹과 로드 존슨은 깨달았다. 다른 이들은 EJB 2를
    사용했고, 이는 "아마도" 직접 만든 프레임워크를 사용한 것이 비하면 더 나은 선택이었을 것이다. 뭐 당신이 수퍼 아키텍트라서 직접 만든
    프레임워크가 더 낫다고 치자. 그렇다면, 스프링/하이버네이드/기타 등등의 프레임워크를 압도하는 사이트의 링크를 부담 갖지 말고 알려주기
    바란다.
     
      
    이렇게까지 말하고 나면 "프레임워크 반대론자"는 "도대체 왜 새롭게 나오는 프레임워크들을 모두 배워야 하지"라고 악을 쓸수 있다. 먼저,
    배운만큼 얻기 마련인데, 어쨌든 새로운 것을 매일 익혀야하기 때문이다. 두번째로는 인기 있는 프레임워크는 최선의 방법과 개념들을 보급하기
    때문이다. 프레임워크 통해 흔히 생기는 상황에 대처하는 최선의 방법을 배울 수 있다. 또 다른 장점으로 스프링에 정통해지면 다른 의존성
    주입을 활용하는 프레임워크를 쉽게 배울 수 있으며, 하이버네이트 전문가가 되면 어떤 ORM도(실제로는 객체를 객체지향이 아닌
    데이터에비스에 매핑하는 어떤 툴도(NoSQL을 포함해)) 쉽게 배울 수 있다. 다시 말하면, 설정 방법과 메서드 사용법이 문서화되어 있고,
    쉽게 확인할 수 있다. 프레임워크에서 중요한 건 바로 개념이다.
      
     
    따라서 중요한 것은 프레임워크를 도입할 지, 장단점을 제대로 평가할 수 있을지, 그리고 당면한 프로젝트에 적합한지 선택하는 사람들의
    능력과 이해 정도다. 프레임워크는 수월하게 개발하기 위해 만들여졌지, 복잡하게 만들려고 만들어진게 아니다. 시작할 때는 어려움이 따르지만,
    프레임워크를 제대로 선택했다면 이후로는 복잡도를 생각하는 것보다는 낮은 수준으로 맞출 수 있다.



아주 좋은 글이다.

     
- Spring-security-3.1.0.RC2로 작업.
- 일반적인 Spring 설정은 제외.

web.xml
	
	
		contextConfigLocation
		
			 classpath*:/applicationContext*.xml
		
	
...
...
	
		springSecurityFilterChain
		org.springframework.web.filter.DelegatingFilterProxy
	

	
		springSecurityFilterChain
		/*
	


applicationContext-security.xml



	
	

	
		
		
     	
		
        
		
		
		
		
		
		
		
		
		
		
        
		
		
	
	
		
	
	
	
	
	

	
	
	
	

	
		
        	
	

	
		
		
	

	
		
		
	

	
		
		
		
	
	


MemberManager.java
public interface MemberManager extends UserDetailsService{
	// 구현하고픈 메서드
}

MemberManagerImpl.java
@Service("memberMgr")
public class MemberManagerImpl extends AbstractGenericManager implements MemberManager{

	@Autowired
	// DB와 통신할 DAO
	MemberDao memberDao;
	
	@Override
	// 로그인 메서드
	public Member login(String memberId, String memberPw){
		Member member = (Member) loadUserByUsername(memberId);
		if(member != null){
			if(memberPw.equals(member.getPasswd())) {
				member.setName(member.getAuth().get(0).getAuthority());
				member.setAuthenticated(true);
				return member;
			}
		}
		return null;
	}
		
	@Override
	// UserDetailService 구현체
	public UserDetails loadUserByUsername(String adminId) throws UsernameNotFoundException {
		// Parameters는 커스텀 클래스임.
		Parameters params = new Parameters();
		params.put("p_id", adminId);
		List list = null;
		try{
			// DAO를 통해 쿼리를 날리고 결과를 받아오는 것.
			list = memberDao.list(params);
			// 유저가 없을경우.
			if(list.size() == 0 || list.size() > 1){
				return null;
			}
		}catch(Exception e){
			StringBuilder logMsg = (new StringBuilder("Username(")).append(adminId).append(") access exception!");
			logger.error(logMsg.toString(), e);
            throw new UsernameNotFoundException(logMsg.toString(), e);
		}
		return list.get(0);
	}
	
	
	public Collection getAuthorities(Member member) {
		List authList = new ArrayList();
		Role role = member.getRole();
		authList.add(new SimpleGrantedAuthority(role.getRoleName()));
        return authList;
	}

}

Member와 SecurityObject (인증을 저장하고 있을 JPA Entity)
인증 정보를 가지고 있을 객체는 몇가지 객체를 구현해야하는데 이에 필요한 filed가 존재해야만 한다.
JPA에서는 @Entity가 붙은 클래스는 DB와 동기화를 하기 때문에 DB에 없는 filed를 넣을시 에러가 난다.
때문에 SecurityObject를 만들어서 객체 구현에 필요한 filed를 가지게하고
인증 정보를 가지고 있을 객체가 SecurityObject를 상속하는 방식으로 처리 했다.

SecurityObject.java
public class SecurityObject implements Serializable{

	private static final long serialVersionUID = 8359426924640562032L;
	
	protected boolean accountNonExpired;
	protected boolean accountNonLocked;
	protected boolean credentialsNonExpired;
	protected boolean accepted;
	
	protected String name;
	protected Object credentials;
	protected Object details;
	protected Object principal;
	protected boolean authenticated;

}


인증 정보를 가지고 있을 Member 객체
/**
 * The persistent class for the members database table.
 * 
 */
@Entity
@Table(name="members")
public class Member extends com.score.www.common.domain.SecurityObject implements Serializable, UserDetails, Authentication {
	private static final long serialVersionUID = 1L;

	// 이런 저런 filed, ex) name, id, nickname 등

	//bi-directional many-to-one association to Role
	// ROLE과 Member 는 1:N의 관계로 설정했고 이를 JPA로 구현한 것.
	@ManyToOne
	@JoinColumn(name="ROLE_SEQ")
	private Role role;

	public Member() {
	}

	// 일반 filed의 getter/setter

	public Role getRole() {
		return this.role;
	}

	public void setRole(Role role) {
		this.role = role;
	}
	
	@Override
	public Object getCredentials() {
		return credentials;
	}

	@Override
	public Object getDetails() {
		return details;
	}

	@Override
	public Object getPrincipal() {
		return principal;
	}
	
	public void setPrincipal(Object principal){
		this.principal = principal;
	}

	@Override
	public boolean isAuthenticated() {
		return authenticated;
	}

	@Override
	public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
		this.authenticated = isAuthenticated;
	}

	@SuppressWarnings("unchecked")
	public List getAuth(){
		return (List) this.getAuthorities();
	}
	
	@Override
	public Collection getAuthorities() {
		List list = new ArrayList();
		list.add(new SimpleGrantedAuthority(role.getRoleName()));
		return list;
	}

	@Override
	public String getPassword() {
		return this.passwd;
	}

	@Override
	public String getUsername() {
		return this.memberName;
	}

	@Override
	public boolean isAccountNonExpired() {
		return accountNonExpired;
	}

	@Override
	public boolean isAccountNonLocked() {
		return accountNonLocked;
	}

	@Override
	public boolean isCredentialsNonExpired() {
		return credentialsNonExpired;
	}

	@Override
	public boolean isEnabled() {
		return super.accepted;
	}

	@Override
	public String getName() {
		return this.name;
	}

	public void setName(String authority) {
		this.name = authority;
	}
	
}


 

'Framework > Spring' 카테고리의 다른 글

Spring 3.2.3 + myBatis 3.2.2  (0) 2013.07.19
Spring Framework 3.2.3 Maven으로 한번에 추가하기..  (0) 2013.07.18
Spring 3.2.2 + Tiles 3.0  (0) 2013.05.22
Spring Security 설정.  (2) 2011.08.30
[2011-05-26] Spring Security 설정 오류.  (0) 2011.05.26
MySQL AutoReconnect 설정.  (0) 2010.07.12
  1. 개발자 2014.09.30 10:54 신고

    이해와 연결이 잘 안되는 부분이 있는데 질문 드려도 될까요?
    MemberManagerImpl 에서 login 메소드는 어디서 호출이 되는건가요??
    Spring의 UserDetailsService 에는 없는 메소드인데, authenticationManager에 설정했다고 해도 이 메소드가 어떻게 호출이 되고 어떻게 로그인 처리가 되는지 잘 이해가 안되네요...
    설명좀 부탁드려도 될까요?
    그리고 AbstractGenericManager 이 녀석도 제가 갖고 있는 라이브러리 (Spring Security 3.2.4) 에는 안나오던데, 이건 어디에 포함된 클래스인가요?

    • jYeory 2015.04.08 14:01 신고

      회사에서 티스토리 접근이 안돼서 이제 봤네요.
      2011년에 사용했던 코드는 원래 사용하는 방법에서 많이 가다듬어 사용한 거라 문서에 없는 것도 몇 개 있습니다.
      현재는 유지보수 쉽게 문서에 있는 그대로 사용하고 있구요.
      늦게나마 댓글 답니다.

Spring Security 3.1.0.RC2는 최소 Spring 3.0.5 and Java 5가 무조건 필요하다.
Spring Security 3..0.5 는 최소 Spring 3.0.3 and Java 5가 무조건 필요하다. 

위 두개를 간과하고 설정하다가 하루종일 삽질만 해댔다. 
 
sec 버전은 3.1인데 프로젝트 Spring 버전은 3.0.2 requirement 조차 맞추지 못하고 급하게 시작한 결과는 삽질. 




필요 버전으로 업데이트 하고 다시 설정하니 오류가 안난다. 

'Framework > Spring' 카테고리의 다른 글

Spring 3.2.3 + myBatis 3.2.2  (0) 2013.07.19
Spring Framework 3.2.3 Maven으로 한번에 추가하기..  (0) 2013.07.18
Spring 3.2.2 + Tiles 3.0  (0) 2013.05.22
Spring Security 설정.  (2) 2011.08.30
[2011-05-26] Spring Security 설정 오류.  (0) 2011.05.26
MySQL AutoReconnect 설정.  (0) 2010.07.12
예전에 ivy를 사용한 경험이 있는데 요새 뉴스거리에 가끔 maven이 올라 오길래 검색해보았다.
maven을 사용해 본 경험이 없어 비교하기가 그랬으나 누군가 경험적 비교를 해놔서 살펴보니..

난 ivy가 좋을 것 같다...
우스갯소리로 ivy는 dependency 추가가 한줄인데 maven은 5줄이상이다... 여기에서 부터 호불호가 갈렸다;;



경험을 바탕으로 간단히.. maven(maven2) vs ivy 장단점 비교를 해보겠습니다.

-  의존성 다운로드
1) ivy : 선택에 의해서 다운로드 가능. 해당 jar외엔 아무것도 받지 않겠다라고 쓸 수 있음. 명시적인 lib 관리 가능
2) maven : 불필요한 jar도 다운받을 수 있습니다. 쓰지 않더라도 선언때문에 다운 받을 수 있고, 상황에 따라서는 exclude 해줘야 함. 
(운영상..  maven을 못 쓴 이유가 바로 이런 불편함이었습니다. 쉽게 운영을 위해서는 명시적인 lib 외엔 다른 것을 쓰지 않도록 하는 것이 더 편리하고 명확합니다. )

- 라이브러리 경합
1) ivy : 유연성 제공, 같은 라이브러리, 버젼일 때, conflict manager 사용가능
2) maven : 같은 라이브러리라도 다른 버젼이면 맨 처음 선언된 artifact에 맞춰 다운로드 됩니다. maven plugin에서는 이 부분이 달라진다.. 결국 버젼 관계를 설정할 방법이 없습니다.

- 의존성 lib 기술 방법
1) ivy : property 이용. 
2) maven : element 단위.

- 이클립스 상
1) ivy : jar만 다운받으면, ant 상에서 빌드 가능, 플러그인 설치 필요 없음
2) maven : m2 플러그인 설치를 통해서 빌드 해야 함

- 장점
1) ivy : ant와 동시에 쓰면서 세밀한 작업이 가능함. 디렉토리 위치를 편하게 관리. 복잡해질 수 있는 소지. ant 의 condition 같은 구린 것이 if / else로도 쓸 수 있도록 지원.
2) maven : 플러그인을 편하게 쓸 수 있음. 간단한 구조에 좋음.

- ivy의 단점 : 파일 이름에 명시적인 패턴을 요구 합니다.


* ant + ivy는 spring 3 에서 사용하고 있습니다. 그 외에서 reference하는 곳는 많지는 않은 듯 합니다.


* 경험상..
maven은 작은 모듈에 적합
ant+ivy는 배포서버나, 세밀함이 필요한 곳에 적합


<볼만한 ivy 이야기>
  • item : forEach내에서 각 아이템 이름으로 사용할 것.
  • index : index
  • collection="classNames"  // 배열명
  • open=""  // forEach 시작 전 ex: "(" forEach 시작전에 ( #{item}
  • separator=","  // forEach 1회시 구분 해줄 기호
  • close="" // forEach 종료 후 ex: ")" forEach 종료 후에 ( #{item}, #{item}, #{item} .... #{item[index]} )



  
	SUM(CASE WHEN R.CLASS_NAME = #{item}  THEN R.CNT ELSE 0 END) AS #{item}



'Framework > myBatis' 카테고리의 다른 글

프로시저 호출 시 주의 할 점..  (0) 2012.11.13
iBatis isEqual  (0) 2012.11.05
[3.0] forEach 사용  (0) 2010.07.15
[3.0] like 검색.  (0) 2010.07.09
[3.0] JDBC Type  (0) 2010.07.09
iBatis 3.0 Cache 문제 -  (0) 2010.07.08

+ Recent posts