본문 바로가기

스프링

[spring] xml_DAO 분리_예외만들기

1.     Com.springsource.javax.activation : Spring java-mail

2.     Com.springsource.javax.mail : Spring java-mail

3.     Com.springsource.org.aopalliance : Spring ProxyFactoryBean

4.     Com.springsource.org.aspectj.tools : AspectJExpressionPointcut 포인트컷 표현식 지원

5.     Com.springsource.junit : junit

6.     Commons-logging : Spring-context가 사용

7.     Mail : java-mail

8.     Mockito : 목 프레임워크 중 Mockito

9.     Mysql-connector : Mysql JDBC

10.   Org.springframework.context.support : Spring java-mail

11.   Spring-aop : 스프링 기능 자체의 aop, Spring ProxyFactoryBean

12.   Spring-bean : 스프링 빈을 활용하는 경우 필요. 스프링의 XML 설정파일과 자바 애노테이션을 파싱 하는데 필요한 클래스 포함

13.   Spring-context : 스프링 코어를 확장한 많은 클래스가 들어 있는데 모든 클래스는 EJB, JNDI(Java Naming Directory Interface), JMX용 클래스와 연동하는데 applicationcontext기능을 사용해야 하며 스프링 리모팅 클래스, 동적 스크립팅 언어(제이루비, 그루비등)와 연동하는 클래스, 빈 유효성검증(JSR-303) API, 스케줄링을 하는 클래스도 포함되어 있다.

14.   Spring-core : 모든 스프링 모듈에서 필요한 모듈. 다른 스프링 모듈에서 사용하는 공통 클래스가 포함됨.

15.   Spring-expression : 스프링 표현언어(SpEL) 지원 클래스 포함.

16.   Spring-jdbc : 스프링이 지원하는 jdbc.

17.   Spring-test.jar

-       @RunWith : Junit 프레임워크의 테스트 실행방법을 확장시 사용.

-       SpringJUnit4ClassRunner : 어플리케이션컨텍스트를 만들고 관리하는 확장 클래스

-       @ContextConfiguration(경로) : 자동으로 만들어줄 어플리케이션 컨텍스트 설정파일

18.   Spring-tx : DuplicateKeyException.class 파일 존재 및 스프링 트랜잭션

 

 

레벨이 할일은 레벨에게 위임

 

 

User의 일은 User에게 위임

 

JDBC,Hibernate,JDO,JPA DataAccess API의 확장을 고려한 인터페이스

 

JDBC 구현

DB의 테이블, 필드 이름과 SQL 문장이 바뀔 수 있다. 물론 처음부터 잘 만들면 되겠지만 SQL 변경 작업은 생각보다 빈번히 일어난다.

그럴 때 마다 DAO 코드를 수정하고 이를 다시 컴파일해서 적용하는 건 번거로울 뿐만 아니라 위험하기도 하다.

실수로 필드명을 잘못 기입하면 다시 코드를 수정하고 빌드하는 작업이 반복되어야 한다.

실제로 DBA에게 SQL 작성을 전담시키고 개발자가 이를 넣는데 잘못 복사되면 DBA가 찾기 어렵다.

17. 외부로부터 DI 받은 SQL 문장을 사용하게 위처럼 커스터마이징

 

가장 손쉽게 생각해 볼 수 있는 SQL 분리 방법은 SQL을 스프링의 XML 설정파일로 빼내는 것이다.

이제 add()에서 사용할 SQL은 코드의 수정 없이 XML 설정을 바꾸는 것만으로도 자유롭게 수정이 가능하다.

단점

하지만. 매번 새로운 SQL이 필요할 때마다 프로퍼티를 추가하고 DI를 위한 변수와 수정자 메소드도 만들어줘야 한다.

>  SQL이 점점 많아지면 그때마다 DAODI용 프로퍼티를 추가하기가 귀찮다.

 

위처럼 Map을 활용하면 일일이 프로퍼티를 추가하지 않고 활용 가능.

 

 

 

SQL이 점점 많아지면 그때마다 DAODI용 프로퍼티를 추가하기가 상당히 귀찮으므로 위처럼 Map을 이용하면 프로퍼티는 하나만 만들고 DAO의 코드는 더 간결해진다. SQL이 더 필요하더라도 프로퍼티 추가 없이 설정파일의 맵 정보만 변경하면 된다. 스프링 <map> 태그 활용.

 

단점

SQLDI 설정정보가 섞여있어 보기에도 지저분하고 관리하기에도 좋지 않다.

SQL을 따로 분리해둬야 독립적으로 SQL 문의 리뷰나, SQL 튜닝 작업을 수행하기도 편하다.

스프링 설정파일로부터 생성된 오브젝트와 정보는 어플리케이션을 다시 시작하기 전에는 변경이 매우 어렵다는 점도 문제.

주입된 SQL 맵오브젝트를 직접 변경하는 방법을 생각해 볼 수 있겠지만 싱글톤인 DAO의 인스턴스 변수에 접근해서 실시간으로 내용을 수정하는 것은 간단하지 않다.

어플리케이션에서 빈번하게 맵 내용을 수정할 경우 동시성 문제 발생 우려.

이는 DAO가 사용할 SQL을 제공해주는 기능을 독립시킬 필요가 있다.

SQL 구현방법

SQL을 스프링 빈 설정 방법을 사용해 XML에 담아둘 이유가 없다.

XML이 아닌 프로퍼티 파일이나 엑셀 파일 또는 임의 포맷의 파일에서 SQL을 저장해두고 읽어와야 할 수 도 있다.

SQLDB에 담아두고 DB에서 가져오게 할 수 도 있다.

>  웹서비스나 리모팅을 이용해 최신 SQL 정보를 보관해두는 외무 시스템에서 가져오는 방법도 있다.

 

 

 

 

레벨의 역할은 레벨에게 위임

 

User의 역할은 User에게 위임

 

JDBC, JDO, JPA, Hibernate 등의 Data Access API를 활용하기 위한 인터페이스

 

JDBC 구현

sqlService를 이용해 SQL을 가져오도록 수정

 

가장 먼저 할 일은 SQL서비스의 인터페이스를 설계하는 것이다.

DBMS 사에 따라 SQL이 달라질 수 있으며, 테스트 오브젝트 및 공통오브젝트에 사용될 수 있으므로. 혹은 데코레이터 패턴 및 프록시를 활용할 수 도 있다. 인터페이스를 사용해야하는 이유는 다양하다.

DAO가 사용할 SQL 서비스의 기능은 간단하다. SQL에 대한 키 값을 전달하면 SQL을 돌려주는 것이다.

*  SqlRetrievalFail~Exception : 주어진 키를 가지고 SQL을 가져오다가 어떤 이유에서든 실패하는 경우에는 해당 예외를 던지도록 정의. 이러한 경우는 복구가 불가능하므로 런타임 예외로 정의한다.

 

 

10. Throwable 예외를 처리할 수 있는 최상위 클래스. 에러가 어디서 발생되었고, 어디서 호출되었는지 처리되는 것 Throwable을 통해 부모 생성자에 보내줘야함.

> 메시지나 필요한 정보를 더 넣을 수 있다. Runtime > Thowable 까지 넘어가는데 API로 생성자를 까보면 알 수 있음.

> SQL을 가져오는데 실패한 근본원인을 담을 수 있도록 중첩 예외를 저장할 수 있는 생성자

 

 

6~9. 설정파일에 <map>으로 정의된 SQL정보를 가져오도록 프로퍼티 등록

 

 

앞에서 커스터마이징 한 것과 큰 차이가 없어 보이지만 사실 큰 차이가 있다.

1.     이제 DAOSQL을 어디에 저장해두고 가져오는지에 대해서 전혀 신경쓰지 않아도 된다.

2.     구체적인 구현방법과 기술에 상관없이 SqlService 인터페이스 타입의 빈을 DI 받아서 필요한 SQL을 가져다 쓰기만 하면 된다.

 

하지만 스프링의 XML 설정파일에서 <bean> 태그 안에 SQL 정보를 넣어놓고 활용하는 건 좋은 방법이 아니다. 그보다는 SQL을 저장해두는 전용포맷을 가진 독립적인 파일을 이용하는 편이 바람직하다.

독립적이라고 해도 가장 편리한 포맷은 역시 XML이다.

*  검색용 키와 SQL 문장 두 가지를 담을 수 있는 XML 문서를 설계해보고, XML 파일에서 SQL을 읽어뒀다가 DAO에게 제공해주는 SQL 서비스 구현 클래스를 만들어보자.

 

Test 위와 동일