달력

122024  이전 다음

  • 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
프로그래밍/It 용어 2016. 9. 26. 11:35



---------------------------------------------------------------------------------------------------------------



[이게 필자가 알고 있는 컨테이너]

토비의 스프링은 다음과 같이 말한다. 스프링은 거대한 컨테이너임과 동시에 Ioc/DI를 기반으로 하고 있는 거룩한 존재이며 서비스 추상화를 통해 삼위일체로 분리되는 3단 변신로봇이라고 한다. 이럴수가! 뭔말하는지는 하나도 모르겠지만 일단 말만 들어도 엄청난데다 가격까지 공짜다. 게다가 이걸 쓰는 사람들마다 칭찬 또 칭찬 일색이니 궁금해서 참을 수가 없다.



근데 말이다…. 필자는 스프링의 지독한 뉴비이므로 여기서 뉴비답게 눈치없게 한번 굴어보려 한다. 일단 스프링이 대단하고 무지 엄청나다는 건 알겠는데…. 컨테이너는 뭐고 IoC/DI는 뭐란 말인가? 평생 살면서 컨테이너란 위의 사진같은 것 밖에 모르는데… 그리고 서비스 추상화? 난 아직 서비스가 뭔지도 모르겠다.


컨테이너란?

컨테이너란 당신이 작성한 코드의 처리과정을 위임받은 독립적인 존재라고 생각하면 된다. 컨테이너는 적절한 설정만 되있다면 누구의 도움없이도 프로그래머가 작성한 코드를 스스로 참조한 뒤 알아서 객체의 생성과 소멸을 컨트롤해준다. 거기다 컨테이너를 이용함으로써 얻게되는 이득은 어마어마 하며, 이런 강력한 기능을 무료로 이용할 수 있다는 점 또한 엄청나다.

허나 소수의 독립심 강하고 줏대있는 사람들은 내가 잘 알지도 못하는 프로그램을 무작정 써야 한다는 것에 반감을 살 수도 있다. 게다가 프로그래머가 다른 라이브러리에 의존하지 않고 직접 코드를 작성해나간다면 완성된 프로그램에 대한 이해도 또한 상상을 초월할 것이다. 혹은 인간이 그렇게 줏대없이 프로그램만 의존하다가 터미네이터나 매트릭스 같은 세상이 되버리면 어떡하냐고 필자에게 따질 수도 있는 것이다.

만약 이러저러한 이유로 컨테이너를 거부하겠다면 필자는 굳이 사용하지 않아도 상관은 없다고 말하겠다. 진심으로 실력만 된다면사용자가 직접 컨테이너를 만들어써도 상관은 없다.

그러나 직접 컨테이너를 구현해보고자 키보드에 손을 올렸다면 아마 배보다 배꼽이 더큰 컨테이너의 어마어마한 기능에 입이 쩍벌어질 것이다. 빈정상하라고 하는 말은 아니지만 사실 당신이 구현하고자 하는 코드와 컨테이너의 구현 코드는 비교도 안될 정도로 수준차가 어마어마하다. 그러므로 코드의 이해가 당장 힘들어지고 뭐가뭔지 모르겠더라도 일단 막강한 기능을 제공하는 컨테이너를 이용하기로 하자.

다시 말하지만 프로그래머가 작성한 코드는 컨테이너를 사용하게 됨으로서 프로그래머의 손을 떠나 컨테이너의 영역으로 떠나버리게 된다. (정확히 말하자면 컨테이너가 맘대로 객체를 생성하는 게 아니라 프로그램을 이용하는 이용자의 호출에 의해 컨테이너가 동작하게 되는 구조이다.) 여하튼 컨테이너를 이용한다면 우리의 골치아픈 문제는 다 컨테이너 알아서 해주므로 쓸데없는 버그나 난해한 과제들에 골치 아파질 이유가 없어진다. 당신은 컨테이너의 기능을 이용하고 사용 중 오류가 있으면 일단 무조건 개발사 탓을 하면 되므로 회사에서 짤릴 가능성까지 어느 정도 낮아진 셈이다!

내친 김에 당신이 필자와 같은 初뉴비라면 임기응변을 위해서라도 반드시 스프링의 개발자와 자바의 개발자 정도가 누군지는 알아두어야 한다. 이런걸 미리미리 알아둬야 나중에 직장 상사가 괜한 버그로 트집을 잡을 때 무조건 이 사람들 탓으로 돌릴 수 있게 된다.

자바의 아버지, 제임스 고슬링 - 선 마이크로시스템즈라는 회사와 함께 자바라는 언어를 탄생시키는데 혁혁한 공을 세운 인물이며 SUN이 오라클로 인수된 뒤 얼마 지나지 않아 회사를 퇴임하고 현재 구글에서 근무 중이다. 개인적으로 C와 UNIX를 만든 데니스 리치 다음으로 훌륭한 프로그래머라고 생각한다.
스프링 혁명가, 로드 존슨 - 프로그래밍 계의 락스타같은 존재라 할 수 있다. 그가 한 유명한 말로 "항상 프레임워크 기반으로 접근하라"라는 말이 있는데 이 말은 곧 당신이 한 클래스에서 DB에 넣고 빼는 등 온갖 짓거리로 코드를 짜고 있다면 당신이 어디가서 프로그래밍의 프자도 꺼내서는 안된다는 말이다.

당신은 이 서블릿 클래스가 몇시몇분몇초에 호출될지 정확히 알고 있는가?

다시 본론으로 돌아와 스프링과 더불어 대표적인 컨테이너를 예로 들자면 톰캣과 같은 WAS(Web Application Service)를 들 수 있다. 우리가 열심히 작성한 서블릿을 써줄지 말지는 톰캣이 결정하므로 당연히 컨테이너 아닌가. 혹여나 그래도 이해가 가지 않는다면… 그냥 당신이 쓰고 있는 코드가 도통 언제 호출될지도 감이 안오는 막막한 상태라면 올바르게 컨테이너를 이용하고 있다고 하자. 그런 의미에서 컨테이너는 당신의 사수나 수석 프로그래머라고 할 수 있다. 내가 쓴 코드를 그 사람들이 써줄지 말지는 모르는 일이니 말이다.


IoC/DI란?

IoC/DI란 Inversion of ControlDependency Injection의 줄임말이다. 한글로 번역하면 제어의 역전, 의존적 주입이라고 하는데 목에 힘을 좀 빼고 솔직히 말하자면 살다살다 한글로 번역까지 했는데 이해 못할 말이 튀어나올 줄은 몰랐다. 그래서 나름 좀… 쪽팔려도 뉴비의 표현으로 바꾸자면 "대신 해줌(IoC)"과 "미리 찜해 놓음(DI)"라고 잠시 명칭을 정정하도록 하겠다.

일단 IoC란 무엇인가? 당신이 위의 컨테이너의 설명글을 꼼꼼히 읽어왔다면 IoC는 지금 당신이 생각하고 있는게 맞다. 바로 컨테이너다. 컨테이너는 당신이 작성한 코드 컨트롤(객체의 생성과 소멸)을 대신 해주는데 IoC덕분에 우리는 미친 사람마냥 언제 호출될지도 모르는 코드를 마음껏! 칠 수 있게 되었다.

사실 IoC는 스프링만의 코딩방식은 아니고 다른 프레임워크에서도 사용되는 방식인데 굳이 스프링만 우리는 IoC 방식이라고 목이 힘주어 강조하는 이유는 스프링은 정말 철저하게 IoC 방식을 써먹었다는 것이다. 그러므로 우리가 여기서 얻을 수 있는 결론은 어디가서 스프링 좀 안다고 IoC가 스프링만의 고유한 방식이라고 떠벌리면 안된다는 것일테다.

그렇다면 DI란 또 무엇인가? 이것은 마치 당신이 받아먹기도 전에 미리 받아먹겠노라고 선언하는…, 주는 놈은 생각도 않았는데 먼저 말부터 꺼내놓는 파렴치한 코딩방식이라고 할 수 있다. 예를 들어 당신이 조촐한 회식으로 사장님과 중국집을 갔는데 당당히 "저는 짜장면 안먹고 양장피 먹겠습니다."라고 선언한다면 당신은 DI개념이 아주 확실한 프로그래머인 셈이다.

게다가 사실 DI 마저도 스프링만의 고유한 방식은 아니라는 거다. DI란 전설과도 같은 프로그래밍 예언서 GoF 중에서 가장 유명한 전략패턴을 일종의 프레임워크 처럼 편리하게 사용할 수 있도록 만든 것이라 할 수 있는데 스프링은 이런 전설로만 알아오던 전략패턴을 뉴비마저도 산소 호흡하듯 능수능란하게 사용하게끔 편리화하였다.

좀 더 구체적으로 DI에 대해 말하자면, DI방식으로 코드를 작성한다면 현재 사용하고 있는 객체의 메서드가 어떻게 작성되었는지 알 필요가 없으며 솔직히 그 클래스가 기능을 잘 구현했는지 조차도 알 필요가 없다. 그저 당신이 확인할 사항은 클래스의 기능을 추상적으로 묶어둔 인터페이스만 갖다 쓰면 그만이다. 나머지는 스프링에서 찜한 걸 연결시켜줄테니 말이다.

아래 그림은 위의 글로만 써놓은 전략패턴과 DI에 대해 정말 간단히 예제로 만든 코드이다.



먼저 말했듯 DI는 스프링만 가지고 있는 고유의 기능이 아니므로 자바의 오브젝트 단위에서도 DI의 구현이 가능하다. 먼저 StrategyPatternService 클래스를 보면 sp라는 객체는 인터페이스 객체인 StrategyPattern로 선언되었으며 StrategyPattern의 메서드인 dependency_injection()를 호출하고 있긴 하다. 그러나 객체 생성 과정에서 객체 sp에 StrategyPatternImpl 클래스를 주입시켜버림으로써 결과적으로 객체 sp는 StrategyPatternImpl의 dependency_injection()이란 메서드를 호출해버리고 말았다는 것이다.

그러므로 위에서 말했듯이 당신은 인터페이스의 메서드만 이용하더라도 위와같이 구현부는 나중에 주입을 통해 해결하므로 획기적인 분업과 동시에 구현 클래스를 쉽게 교체할 수 있다는 장점을 얻게 된다. 물론 스프링은 위의 이미지와 같이 단순한 방식으로 주입하진 않는다. 주입 방식에만 클래스 형태와 XML형태 2가지가 있으며 그 세부적으로도 어마어마하게 많은 방식으로 DI를 할 수 있다.

가끔 스프링을 쓰다보면 이런 다양한 방식이 진짜 편리와 우수한 기능을 위해서인지… 아니면 일부러 사용자를 헷갈리게 하려는 건지 분간이 안갈 때가 종종 있다. (개인적으로 로드 존슨이 프로그래머들을 편집증으로 몰아가기 위해 꾸민 음모가 아닌가 싶다…)

여하튼 IoC/DI의 개념을 요약하자면 정신나간듯 언제 사용될 지도 모르는 코드를 쳐대면서(IoC) 동시에 사용하고 있는 코드가 뭔지도 모르면서 일단 갖다 쓰는(DI) 획기적이고 진보적인 프로그래밍 작성방식이라 이해하면 되겠다.


서비스 추상화란?

솔직히 지금 DI를 설명하면서 서비스 추상화에 대한 부분까지 함께 설명해버렸다. 간략하게 개념에 대해서만 설명하자면 토비의 스프링의 일부분을 발췌하는 것이 좋을 듯 싶다.

추상화란 하위 시스템의 공통점을 뽑아내서 분리시키는 것을 말한다. 그렇게 하면 하위 시스템이 어떤 것인지 알지 못해도, 또는 하위 시스템이 바뀌더라도 일관된 방법으로 접근할 수가 있다.

그렇다. 우리는 위의 간단한 DI예제에서 StrategyPattern이란 인터페이스로 기능을 분리시킴으로서 하위시스템, 즉 클래스가 그 무엇으로 교체되더라도 해당 메서드는 반드시 존재할 것이란 보장을 받은 셈이다. 당신이 위의 모든 글을 읽고서도 아직 잘 이해가 가지 않는다면 지금 당장은 이러한 것을 과연 어떻게 구현해낼까에 대해 고민하지 않아도 된다. 사실 그것을 알아나가는 과정이 바로 스프링을 공부하는 과정이기 때문이다.

다만… DI예제의 과정, 즉 인터페이스를 구현하고 주입하는 과정이 이해가 가지 않는다면 당신은 자바에 대한 기본기가 매우 부족한 것이니 자바의 정석을 펼치고 객체지향개념부터 다시 필독하고 읽어보길 바란다.


출처 : http://egloos.zum.com/springmvc/v/487497


'프로그래밍 > It 용어' 카테고리의 다른 글

기본용어  (0) 2016.09.27
자바 리플렉션 ( JAVA Reflection )  (0) 2016.09.26
퍼시스턴스 프레임워크  (0) 2016.09.26
iBatis(아이바티스)란?  (0) 2016.09.26
WAS와 웹서버의 차이  (0) 2016.09.23
Posted by 당구치는 개발자
|
프로그래밍/It 용어 2016. 9. 26. 11:31


퍼시스턴스(Persitence)

퍼시스턴스는 데이터의 지속성을 의미. 즉 애플리케이션을 종료하고 다시 실행하더라도 이전에 저장한 데이터를 다시 불러올수있는 기술.

퍼시스턴스 프레임

프레임워크(Framework)

라이브러리가(library)가 개발에 필요한 도구들을 단순히 나열해 놓은 것이라면 프레임워크(framework)는 동작에 필요한 구조를 어느 정도 완성해 놓은 반제품 형태의 도구입니다.

퍼시스턴스 프레임워크

퍼시스턴스 프레이임워크는 데이터의 저장, 조회, 변경, 삭제를 다루는 클래스 및 삭제를 다루는 클래스 및 설정 파일들의 집합

퍼시턴스 프레임워크를 사용하면 JDBC프로그래밍의 복잡함이나 번거로움 없이 간단한 작업만으로 데이터베이스와 연동되는 시스템을 빠르게 개발할 수 있습니다. 안정적인 구동도 보장되므로 금상첨화가 아닐수 없습니다.

퍼시스턴스 프레임워크에는 SQL문장으로 직접 DB데이터를 다루는 'SQL 맵퍼(mapper)와 자바 객체를 통해 간접적으로 DB데이터를 다루는 객체 관계 맵퍼(Object-Relational mapper)' 가 있습니다. SQL 맵퍼의 대표주자로 'mybatis(이전버전의 이름은 iBATIS)'가 있고, 객체관계 맵퍼의 대표 주자로 하이버네이트(Hibernate)'와 '탑링크('TopLink)'가 있습니다.

mybatis

mybatis의 핵심은 개발과 유지보수가 쉽도록 소스코등 박혀있는 SQL을 별도의 파일로 분리하는것. 또한 단순하고 반복적인 JDBC코드를 캡슐화하여 데이터베이스 프로그래밍을 간결하게 만드는 것입니다.

mybatis 작동 흐름

1. 데이터 처리를 위해 DAO는 mybatis에 제공하는 객체의 메서드를 호출

2. mybatis는 SQL문이 저장된 맵퍼 파일에서 데이터 처리에 필요한 SQL문을 찾는다.

3. mybatis는 맴퍼 파일에서 찾은 SQL을 서버에 보내고자 JDBC드라이버를 사용

4. JDBC 드라이버는 SQL문을 데이터베이스 서버로 보낸다.

5. mybatis는 select문의 실행 결과를 값 객체에 담아서 반환, insert, update, delete 문인 경우 입력, 변경, 삭제된 레코드의 개수를 반환.

일반적으로 DAO에서 mybatis를 사용하는 시나리오.

1. Dao는 SqlSessionFactory에게 SQL을 실행할 객체를 요구한다.

2. SqlSessionFactory는 SqlSession 객체를 생성하여 반환한다.

3. Dao는 SqlSession 객체에게 SQL실행을 요청

4. SqlSession 객체는 SQL이 저장된 맵퍼 파일(XML) 에서 SQL을 찾는다.

5. SqlSession은 JDBC드라이버를 통해 데이터베이스에 질의를 실행

6. SqlSession은 데이터베이스로부터 가져온 질의 결과를 객체로 생성하여 반환

7. Dao는 사용이 끝난 SqlSession을 닫는다.

mybatis 사용 준비

mybatis를 사용하기위해서 관련 라이브러리 파일을 다음 사이트에서 내려받자.

mybatis github : http://github.com/mybatis

jar배포파일 다운받는 페이지 : https://github.com/mybatis/mybatis-3/releases

배포된 압축파일을 풀면

mybatis-3.2.7.jar 파일과 의존 라이브러들을 해당 웹프로젝트의 /WebContent/WEB-INF/lib 폴더에 복사.

단 중복 파일이 있으면 버전이 낮은 파일을 삭제



mybatis 프레임워크의 핵심 컴포넌트

[표] mybatis의 핵심 컴포넌트

컴포넌트

설명

SqlSession

실제 SQL을 실행하는 객체, 이 객체는 SQL을 처리하기 위해 JDBC드라이버를 사용함.

SqlSessionFactory

SqlSession 객체를 생성함.

SqlSessionFactoryBuilder

mysql 설정 파일의 내용을 토대로 SqlSessionFactory를 생성함.

mybatis 설정 파일

데이터베이스 연결 정보, 트랜잭션 정보, mybatis제어 정보등의 설정 내용을 포함하고 있음. SqlSessionFactory를 만들 때 사용됨

SQL 맵퍼 파일

SQL문을 담고 있는 파일, 보통 XML파일로 작성. SqlSession객체가 참조함.

DAO 에서 SqlSessionFactory 사용

SqlSessionFactory는 SQL을 실행할때 사용할 도구를 만들어줌.

DAO 클래스에서 SqlSessionFactory를 저장할 인스턴스 변수와 셋터 메서드를 선언

SqlSessionFactory sqlSessionFactory;

public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {

this.sqlSessionFactory = sqlSessionFactory;

}

SqlSession 사용

SqlSession은 SQL을 실행하는 도구.

이 객체는 직접 생성할수 없고, SqlSessionFactory를 통해서만 얻을수있다.

SqlSession sqlSession = sqlSessionFactory.openSession();

try {

return sqlSession.selectList("test.dao.testDao.selectList");

//List<E> selectList(String sqlId)

//sqlId = SQL 맵퍼의 네임스페이스 이름 + 맵퍼파일에 있는 SQL문 ID

//List<E> selectList(String sqlId, Object parameter)

//SELECT문을 실행하는데 값이 필요하다면 위와 같이 두번째 매개변수로 값을 전달.

} finally {

sqlSession.close();

}

[표] SqlSession의 주요 메서드

메서드

설명

selectList()

SELECT문을 실행. 값 객체(Value Object)목록을 반환함

selectOne()

SELECT문을 실행. 하나의 값 객체를 반환함

insert()

INSERT문을 실행. 반환값은 입력한 데이터 개수.

update()

UPDATE문을 실행. 반환값은 변경한 데이터 개수.

delete()

DELETE문을 실행. 반환값은 삭제한 데이터 개수.


SqlSession의 메서드와 매개변수 값 전달.

DAO 일부 .....

sqlSession.insert("test.dao.testDao.insert", project);

.....

맵퍼파일 일부 ...

<insert id="insert" parameterType="project">

insert into PROJECTS_web(PNO, PNAME,CONTENT,STA_DATE,END_DATE,STATE,CRE_DATE,TAGS)

values ( projects_web_pno_seq.nextval, #{title},#{content},#{startDate},#{endDate},0,sysdate,#{tags})

</insert>

.....

=> #{프로퍼티명} ​자리에 project객체의 프로퍼티 값이 온다.

객체의 프로퍼티란? 인스턴스 변수를 말하는 것이 아니라 겟터/셋터를 가리키는 용어, 프로퍼티 이름은 겟터/셋터 메서드의 이름에서 추출.

예를 들어 #{title} 자리에는 project객체의 getTitle() 반환값이 놓이게 된다.

commit()과 rollback() 메서드

DBMS는 INSERT, UPDATE, DELETE문을 실행하면 그 작업 결과를임시 데이터베이스에 보관. 클라이언 요청이 있어야만 임시 데이터베이스의 작업물을 운영 데이터베이스에 반영

commit()은 임시 데이터베이스에 보관된 작업결과를 운영 데이터베이스에 적용하라고 요청할때 사용하는 메서드

int count = sqlSession.insert("spms.dao.ProjectDao.insert",project);

sqlSession.commit();

return count;

rollback()은 임시 데이터베이스의 작업 결과를 운영 데이터베이스에 반영하지 않고 취소할때 호출.


자동 커밋 (Auto-commit)

INSERT, UPDATE, DELETE 을 실행할때 자동으로 커밋하고 싶다면 SqlSession객체를 생성할때 true 전달.

SqlSession sqlSession = sqlSessionFactory.openSession(true);

=> 자동 커밋으로 설정해 놓고 쓰면 편리하지만 트랜잭션을 다룰수없음.



SQL 맵퍼 파일 작성



[맵퍼 예시] OracleProjectDaoMapper.xml

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
57
58
59
60
61
62
63
64
65
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="spms.dao.ProjectDao">

<resultMap type="project" id="projectResultMap">
<id column="PNO" property="no"/>
<result column="PNAME" property="title"/>
<result column="CONTENT" property="content"/>
<result column="STA_DATE" property="startDate" javaType="java.sql.Date"/>
<result column="END_DATE" property="endDate" javaType="java.sql.Date"/>
<result column="STATE" property="state"/>
<result column="CRE_DATE" property="createdDate" javaType="java.sql.Date"/>
<result column="TAGS" property="tags"/>
</resultMap>

<select id="selectList" parameterType="map" resultMap="projectResultMap">
select PNO, PNAME, STA_DATE, END_DATE, STATE
from PROJECTS_web
order by
<choose>
<when test="orderCond == 'TITLE_ASC'">PNAME asc</when>
<when test="orderCond == 'TITLE_DESC'">PNAME desc</when>
<when test="orderCond == 'STARTDATE_ASC'">STA_DATE asc</when>
<when test="orderCond == 'STARTDATE_DESC'">STA_DATE desc</when>
<when test="orderCond == 'ENDDATE_ASC'">END_DATE asc</when>
<when test="orderCond == 'ENDDATE_DESC'">END_DATE desc</when>
<when test="orderCond == 'STATE_ASC'">STATE asc</when>
<when test="orderCond == 'STATE_DESC'">STATE desc</when>
<when test="orderCond == 'PNO_ASC'">PNO asc</when>
<otherwise>PNO desc</otherwise>
</choose>
</select>

<insert id="insert" parameterType="project">
insert into PROJECTS_web(PNO, PNAME,CONTENT,STA_DATE,END_DATE,STATE,CRE_DATE,TAGS)
values ( projects_web_pno_seq.nextval, #{title},#{content},#{startDate},#{endDate},0,sysdate,#{tags})
</insert>

<select id="selectOne" parameterType="int" resultMap="projectResultMap">
select PNO, PNAME, CONTENT, STA_DATE, END_DATE, STATE, CRE_DATE, TAGS
from PROJECTS_web
where PNO=#{value}
</select>

<update id="update" parameterType="project">
update PROJECTS_web
<set>
<if test="title != null">PNAME=#{title},</if>
<if test="CONTENT != null">CONTENT=#{content},</if>
<if test="STA_DATE != null">STA_DATE=#{startDate},</if>
<if test="END_DATE != null">END_DATE=#{endDate},</if>
<if test="STATE != null">STATE=#{state},</if>
<if test="TAGS != null">TAGS=#{tags}</if>
<!-- mybatis는 SET절의 끝에 콤마(,)가 있으면 제거 -->
</set>
where PNO=#{no}
</update>

<delete id="delete" parameterType="int">
delete from PROJECTS_web
where PNO=#{value}
</delete>
</mapper>

동적 SQL의 사용

SQL문을 동적으로 생성.

동적 SQL엘리먼트 : mybatis는 동적 SQL을 위한 엘리먼트를 제공. JSTL코어 라이브러리에 정의된 태그들과 비슷.

[표] 동적 SQL을 작성할때 사용하는 엘리먼트들

엘리먼트 예

설명

<if test="조건">SQL 문</if>

<if> 태그는 어떤 값의 상태를 검사하여 참일경우에만 SQL문을 포함하고 싶을때 사용. test속성에 지정된 조건이 참이면 <if>태그의 내용을 반환

<choose>

<when test="조건1">SQL문</when>

<when test="조건2">SQL문</when>

<otherwise>SQL 문</otherwise>

</choose>

<choose>태그는 검사할 조건이 여러개일경우에 사용한다. test속성에 지정된 조건이 참이면<when>태그의 내용을 반환. 일하는 조건이 없으면 <otherwise>내용을 반환

<where>

<if test="조건1">SQL 문</if>

<if test="조건2">SQL 문</if>

</where>

<where>태그는 WHERE절을 반환한다. <where>안의 하위 태그를 실행하고 나서 반환값이 있으면 WHERE절을 만들어 반환하고, 없으면 WHERE절을 반환하지 않는다.

<trim prefix="단어"

prefixOverrides="문자열|문자열">

<if test="조건1">SQL 문</if>

<if test="조건2">SQL 문</if>

</trim>

<trim>태그는 특정 단어로 시작하는 SQL문을 반환하고 싶을때 사용한다. prefix는 반환값 앞에 붙일 접두어를 지정한다. prefixOverrides는 반환할 값에서 제거해야하는 접두어를 지정한다.

다시말하면 <trim>의 반환값이 있다면, 그 값의 앞 부분이 prefixOverride에 지정된 문자열과 일치할 경우 그 문자열을 제거한다. 그리고 그 값의 앞부분에 prefix로 지정한 접두얼르 붙여 반환한다.

<set>

<if test="조건1">SQL 문</if>

<if test="조건2">SQL 문</if>

</set>

<set>태그는 UPDATE문의 SET절을 만들 때 사용한다. 조건이 참인<if>의 내용은 SET절에 포함된다. SET절의 항목이 여러개일 경우 자동으로 콤마(,)를 붙인다.

<foreach

item="항목"

index="인덱스"

collection="목록"

open="시작문자열"

close="종료문자열"

separator="구분자">

</foreach>

<foreach>태그는 목록의 값을 가지고 SQL문을 만들때 사용한다. 특히 IN(값, 값, .) 조건을 만들 때 좋다.

item속성에는 항목을 가리킬때 사용할 변수의 이름을 지정한다.

index속성에는 항목의 인덱스 값을 꺼낼때 사용할 변수 이름을 지정한다.

collection속성에는 java.util.List구현체나 배열 객체가 온다.

open속성에는 최종 반환값의 접두어를 지정한다.

close속성에는 최종 반환값의 접미어를 지정한다.

separator속성은 반복으로 생성하는 값을 구분하기 위해 붙이는 문자열을 지정한다.

<bind name="변수명" value="값" />

<bind>태그는 변수를 생성할때 사용한다.

mybatis 설정파일

mybatis프레임워크의 동작 환경을 설정하는 파일

mybatis설정 파일의 루트 엘리먼트는 configuration 입니다.

[표] configuration의 주요 자식엘리먼트들

엘리먼트

용도

properties

프로퍼티 파일이 있는 경로 설정. <property>를 사용하여 개별 프로퍼티 정의 가능

settings

프레임워크의 실행 환경을 설정

typeAliases

자바클래스 이름 (패키지이름 포함)에 대한 별명 설정

typehandlers

칼럼의 값을 자바 객체로, 자바 객체를 칼럼의 값으로 변환해 주는 클래스를 설정

environments

프레임워크에서 사용할 데이터베이스 정보 (트랜잭션 관리자, 데이터 소스)를 설정.

mappers

SQL 맵퍼 파일들이 있는 경로 설정

- 자바클래스 경로를 사용하는 방법 :

<mapper resource="spms/dao/OracleProjectDao.xml"/>

- 운영체제의 파일시스템 경로를 사용하는 방법.

<mapper url="file:///c:/project/dao/OracleProjectDao.xml"/>




[mybatis 설정파일 예제] mybatis-config.xml

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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
<!-- <properties resource="spms/dao/db.properties"/> -->

<!-- 로그기능 활성 -->
<settings>
<setting name = "logImpl" value="LOG4J"/>
</settings>
<!-- 타입 별칭지정 -->
<typeAliases>
<typeAlias type="spms.vo.Project" alias="project"/>
<typeAlias type="spms.vo.MemberVO" alias="member"/>
</typeAliases>

<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!--
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
-->

<dataSource type="JNDI">
<property name="data_source" value="java:comp/env/jdbc/studydb"/>
</dataSource>

</environment>
</environments>
<!-- 맵퍼파일 지정 -->
<mappers>
<mapper resource="spms/dao/OracleProjectDao.xml"/>
</mappers>
</configuration>

[참고] db.properties 내용

driver=oracle.jdbc.driver.OracleDriver

url=jdbc:oracle:thin:@localhost:1521:orcl

username=study

password=study


트랜잭션 관리 방식 설정

트랜잭션(Transaction)이란, 여러개의 데이터변경 작업(insert, update, delete)을 하나의 작업으로 묶은 것입니다. mybatis에서 트랜잭션을 관리하는 방식에는 둘가지가 있습니다.

[표] mybatis의 트랜잭션 관리 유형

트랜잭션 관리 유형

설명

JDBC

직접 JDBC의 커밋(commit), 롤백(rollback) 기능을 사용하여 mybatis 자체에서 트랜잭션을 관리

MANAGED

서버의 트랜잭션 관리 기능을 이용. 즉 JavaEE 애플리케이션 서버(JBoss, WebLogic, WebSphere 등) 나 서블릿 컨테이너 (톰캣 서버 등) 에서 트랜잭션을 관리

다음과 같이 <transactionManager>를 사용하여 트랜잭션 관리 유형을 설정, type속성에 트랜잭션 관리 유형(JDBC 또는 MANAGED)을 지정

<transactionManager type="JDBC"/>

데이터 소스 설정

mybatis 는 JDBC표준 인터페이스인 javax.sql.DataSource구현체를 이용하여 DB커넥션을 다룹니다.

[표] mybatis의 데이터 소스 유형

데이터 소스 유형

설명

UNPOOLED

DB 커넥션을 요청할 때마다 매번 커넥션 객체를 생성한다. 높은 성능을 요구하지 않는 단순한 애플리케이션에 적합하다.

POOLED

미리 DB커넥션 객체를 생성해 두고, 요청하면 즉시 반환한다. 데이터베이스에 연결하는 과정, 즉 연결을 초기화하고 사용자를 인증하는 과정이 없기 때문에 속도가 빠르다.

JNDI

Java EE 애플리케이션 서버나 서블릿 컨테이너(톰캣 등) 에서 제공하는 데이터 소스를 사용한다.

1) mybatis에서 지원하는 DBConnection Pool 사용

<environments default="development">

<environment id="development">

<transactionManager type="JDBC"/>

<dataSource type="POOLED">

<property name="driver" value="${driver}"/>

<property name="url" value="${url}"/>

<property name="username" value="${username}"/>

<property name="password" value="${password}"/>

</dataSource>

</environment>

</environments>

=> <property>의 value값을 보면 ${}로 되어있는데 이는 프로퍼티를 가리키는 문법이다. <properties>에서 설정한 파일(db.properties)로 부터 프로퍼티의 값을 가져온다.

2) mybatis에서 JNDI사용하기

<environments default="development">

<environment id="development">

<transactionManager type="JDBC"/>

<dataSource type="JNDI">

<property name="data_source" value="java:comp/env/jdbc/studydb"/>

</dataSource>

</environment>

</environments>

[참고]

web.xml

<!-- 웹 애플리케이션에서 톰캣서버의 자원 사용 -->

<resource-ref>

<res-ref-name>jdbc/studydb</res-ref-name> < !-- JNDI 이름 -->

<res-type>javax.sql.DataSource</res-type> < !-- 리턴될 자원의 클래스이름 -->

<res-auth>Container</res-auth> < !-- 자원 관리의 주체 -->

</resource-ref>

context.xml

<Context>

<!-- Default set of monitored resources -->

<WatchedResource>WEB-INF/web.xml</WatchedResource>

<Resource name="jdbc/studydb" auth="Container" type="javax.sql.DataSource"

maxActive = "10" maxIdle="3" maxWait="10000"

username="study"

password="study"

driverClassName="oracle.jdbc.driver.OracleDriver"

url="jdbc:oracle:thin:@localhost:1521:orcl"

closeMethod="close"/>

</Context>


mybatis 설정 파일에 로그 설정 추가

<settings>

<setting name = "logImpl" value="LOG4J"/>

</settings>

[표] 로그출력 구현체

value속성값

설명

SLF4J

SLF4J

LOG4J

Log4j

LOG4J2

Log4j 2

JDK_LOGGING

JDK logging

COMMONS_LOGGING

Apache Commons Logging

STDOUT_LOGGING

표준 출력장치로 출력

NO_LOGGING

로그 출력 기능 사용안함

클래스명(패키지명 포함)

org.apache.ibatis.logging.Log 인터페이스의 구현체.

FATAL < ERROR < WARN < INFO < DEBUG < TRACE

src/log4j.properties (로그4j 설정 파일)


log4j.rootLogger=ERROR, stdout

log4j.logger.spms.dao=DEBUG //하위

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.CoversionPattern=%5p [%t] - %m%n

=> DEBUG보다 더 자세한 내용을 보고 싶다면 로그 출력 등급을 TRACE로 설정 , 예를 들어 select문의 실행결과를 로그로 출력하고 싶다면 출력등급을 TRACE로 바꾸면된다.

==> Preparing: insert into PROJECTS_web(PNO, PNAME,CONTENT,STA_DATE,END_DATE,STATE,CRE_DATE,TAGS) values ( projects_web_pno_seq.nextval, ?,?,?,?,0,sysdate,?)

==> Parameters: 테스트프로젝트(String), 프로젝트 1234(String), 2013-12-01 00:00:00.0(Timestamp), 2014-07-01 00:00:00.0(Timestamp), 태그 태그 태그(String)

<== Updates: 1

/project/list.do

==> Preparing: select PNO, PNAME, STA_DATE, END_DATE, STATE from PROJECTS_web order by PNO desc

==> Parameters:

<== Columns: PNO, PNAME, STA_DATE, END_DATE, STATE

<== Row: 7, 테스트프로젝트, 2013-12-01 00:00:00, 2014-07-01 00:00:00, 0

<== Row: 6, 12343333, 2010-01-01 00:00:00, 2010-05-05 00:00:00, 0

<== Row: 4, 프로젝트3, 2013-10-02 00:00:00, 2013-12-30 00:00:00, 0

<== Row: 3, 프로젝트2, 2014-07-01 00:00:00, 2014-09-01 00:00:00, 0

<== Row: 2, 프로젝트1, 2014-07-01 00:00:00, 2014-09-01 00:00:00, 0

<== Total: 5


설정파일 불러오기

String resource = "spms/dao/mybatis-config.xml";

InputStream inputStream = Resources.getResourceAsStream(resource);

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);



출처 : http://gnujava.com/board/article_view.jsp?article_no=6392&menu_cd=57&board_no=36&table_cd=EPAR01&table_no=01


Posted by 당구치는 개발자
|
프로그래밍/It 용어 2016. 9. 26. 11:28


iBatis란?

 

더 빠른 JDBC 코딩을 위한 일반화된 프레임워크

- SQL 매퍼 + DAO 프레임워크

iBatis는 데이터베이스에 있는 자원들을 보다 편리하게 가져오기 위한 프레임워크이다.

XML서술자를 사용해서 간단하게 자바빈즈를 PreparedStatement의 바인드 변수인 파라미터와

ResultSet으로 맵핑시켜주는 기능으로  SQL Maps 또한 ORM이라고도 한다.

iBATIS 데이터 매퍼 프레임워크는 관계형 데이터베이스에  접근할 때 가독성, 유지보수성, 생산성 등을 향상시켜준다.

특징

간결함과 쉬운 접근성

다른 프레임워크와 객체관계맵핑툴에 비해 가장 간단한 퍼시스턴스 프레임워크

iBATIS 데이터 매퍼를 사용하기 위해서 자바빈즈와 XML 그리고 SQL만 알면 추가적으로 배워야 할것이 거의 없고

테이블을 조인하거나 복잡한 쿼리문을 수행하기 위해 필요한 복잡한 스키마도 없다.

데이터 매퍼를 사용하면 실제 SQL문의 모든 기능을 그대로 사용할수 있으며,

XML 형태로 서술된 JDBC 코드라고 생각해도 될 만큼 JDBC에 적용되는 거의 모든 기능은 iBATIS에서도 잘 적용된다

데이터베이스 관리자와 SQL 프로그래머 양 쪽 모두 이해하기 용이하다

 

 

생산성의 향상

JDBC와 SQL을 유지하면서도 훨씬 더 적은 코드로도 JDBC처럼 작동

자바코드의 20%를 사용하여 JDBC기능의 80%를 제공하는 간단한 프레임워크

작성할 필요가 없는 JDBC 코드로 인한 분량 문제는 현저하게 줄어듬 (JDBC에 비해 62%정도)

일반적으로 프레임워크는 장황한 코드를 제거하고 복잡한 구조적인 문제를 해결하면서 공통적인 작업을 수행하기 위해 존재  

 

 

성능

구조적 강점 - 데이터 접근 속도 높여주는 JOIN매핑

여러가지 방식의 데이터 가져오기 전략

      불필요한 수천 개의 행을 한꺼번에 데이터베이스로부터 가져오는 것 X

      가져오기 미루기, SQL 줄이기 기법

=> 애플리케이션의 성능을 명백히 향상  

 

 

 

 

SQL 문장과 프로그래밍 코드의 분리

작업의 분배 - 팀을 세분화하는 것을 도움

SQL문과 Java코드와의 분리만으로도 Java개발자는 Query문을 신경쓰지 않아도 된다.

SQL문이 변경되더라도 파라미터 값만 변경되지 않는다면 Java소스에서 수정할 부분이 없기 때문이다.

 

 

이식성

어떤 프로그래밍 언어로도 구현가능하다

 예) 자바, C#(iBATIS.NET), Ruby(RBATIS)

 

데이터베이스 접근 클래스와 비즈니스 로직을 담은 클래스의 분리

이른바 DAO(Data Access Object) 패턴이 이러한 일을 담당한다.

 ibatis는 DAO 계층 구현을 위한 유틸리티 성격이면서 동시에 best practice 역할도 수행한다.

 

 

자주 쓰이는 데이터를 변경되지 않는 동안에 임시 보관(Cache)

ibatis 에선 XML 설정만으로 캐시를 할 수 있다.

 

 

트랜젝션과 쓰레드 관리

트랜젝션 처리 역시 용이하다.

 

출처 : http://blog.naver.com/poloecko/70094791801

 

========================================================================================================

 

Java에서 사용되는 ORM툴 중 Hibernate와 iBatis중 국내 많은 업체들이 iBatis를 선택한 이유는 여러 설정이 필요한 Hibernate에 비해 iBatis는 직관적이여서(SQL문을 직접 쓰기때문) 이해가 빠르기 때문일것이다.

 하지만 세계적 추세는 Hibernate를 중시하며 추진하는 분위기며 (제7회 공감 개발자세미나)  유연한 확장성과 대처에는 Hibernate가 좋다고 한다. 

 하지만 국내 개발환경(협의 후 테이블 구축 유지)에는 iBatis가 좀더 유용하며 주류가 되는 추세이다. 쿼리문의 처리에는 iBatis가 조금더 성능이 우세하다.

  2010년 6월16일 이후 구글코드로 이전함에 따라 myBatis로 개명하였다*. 하지만 편의와 대중성을 위해 iBatis로 진행하겠다.

*창시자인 Clinton Begin이 iBatis의 모든 코드를 apache재단 에 기부함에 따라 이름도 바꾸었다고한다.

 

1. iBatis의 특징

1) 간결함, 쉬운 접근성

sql문을 xml에 그대로 서술하기 때문에 기존 sql문처리에 익숙한 개발자들이 다가가기 쉽다.

그에 따른 장점으로 개발자와 DB관리의 양쪽 모두 이해에 용이하다.

2) 생산성의 향상

JDBC의 많은 설정을 간결하게 줄여줌으로 인해 개발자의 작성분량을 줄여준다.

3) 성능

성능최적화 기법을 지원한다.

ex)예를 들어 가장 중요한 기능이라면 페이징 처리된 데이터 리스트를 읽어와서 사용할 때 불필요한 수천개의 행을 한꺼번에 데이터베이스로부터 가져오는것이 아니기 때문에 어플리케이션의 성능을 향상시킬수있다. 

(이해가안되서 그냥 그대로 타이핑하였다. 코드상 처리의 장점을 말하는것 같다.)

 

출처 : http://metalbird.tistory.com/entry/iBatis%EB%9E%80

 

========================================================================================================

 

#iBatis란?

  iBatis(아이바티스)는 SQL에 기반한 데이터베이스와 자바. 닷넷, 루비등을 연결시켜주는 역할을 하는 영속성 프레임워크이다. 이러한 연결은 프로그램의 소스코드에서 SQL문장을 분리하여 별도의 XML 파일로 저장하고 이 둘을 서로 연결시켜주는 방식으로 작동한다.


#데이터매퍼

  iBatis 데이터매퍼 API는 프로그래머에게 자바빈즈 객체를 PreparedStatement 파라미터와 ResultSets으로 쉽게 매핑할 수 있도록 한다. 이는 자바코드의 20%를 사용하여 JDBC기능의 80%제공하는 간단한 프레임워크라는 뜻이다.


  데이터 매퍼는 자바빈즈, Map구현체, 원시래퍼타입(String, Integer..) 그리고 SQL문을 위한 XML문서를 매핑하는 XML서술자를 사용하는 매우 간단한 프레임워크를 제공한다. 데이터 매퍼가 관리하는 생명주기는 다음과 같다.


  1. 파라미터(자바빈즈,Map 또는 원시래퍼)로써 객체를 제공한다. 파라미터 객체는 update문에서 입력값을 세팅하기 위해 사용되거나 쿼리문의 where절을 셋팅하기 위해서 사용된다.
  2. 매핑된 구문을 실행한다. 이 단계는 PreparedStatement 인스턴스를 생성할 것이고 제공된 파라미터 객체를 사용해서 파라미터를 셋팅한다. 그 후 구문을 실행하고 ResultSet으로부터 결과 객체를 생성한다.
  3. update의 경우에 영향을 미친 rows의 숫자를 반환한다. 조회작업인 경우에 한 개의 객체 또는 컬렉션 객체를 반환한다. 파라미터처럼 결과 객체는 자바빈즈, Map 원시타입 래퍼또는 XML이 될 수 있다.

 

출처 : http://javaclass1.tistory.com/150

 

========================================================================================================

 

iBATIS의 개념
 

iBATIS는 간단한 XML서술자를 사용해서 간단하게 자바빈즈를 SQL statement에 맵핑시킨다. 간단함(Simplicity)이란 다른 프레임워크와 객체관계맵핑툴에 비해 iBATIS의 가장 큰 장점이다. iBATIS Data Mapper를 사용하기 위해서 당신은 자바빈즈와 XML 그리고 SQL에 친숙할 필요가 있다. 여기엔 배워야 할것도 거의 없고 테이블을 조인하거나 복잡한 쿼리문을 수행하기 위해 필요한 복잡한 스키마도 없다. Data Mapper를 사용하면 당신은 실제 SQL문의 모든 기능을 가질수 있다. JDBC 로만 프로그래밍 할 때의 번거로움을 줄여주기 위해 재사용 모듈로 개발된 것인데 그 주요한 어려움을 ibatis 개발자 가이드에서 다음과 같이 정리하고 있다.

 
 
iBATIS의 역사와 사용
  • SQL 문장과 프로그래밍 코드의 분리
  • JDBC 라이브러리를 통해 매개변수를 전달하고 결과를 추출하는 일
  • 데이터베이스 접근 클래스와 비즈니스 로직을 담은 클래스의 분리
  • 자주 쓰이는 데이터를 변경되지 않는 동안에 임시 보관(Cache)
  • 트랜젝션과 쓰레드 관리
 
이러한 사항들에 대해서 한번쯤 생각해볼 필요가 있다.
  • SQL 문장과 프로그래밍 코드의 분리
    SQL문과 프로그램 코드는 꼭 분리해야 할까? 우선 프로그램이 작은 경우는 굳이 분리할 필요가 없어 보인다. 파일만 두개로 분리되기 때문에 관리에 불편함이 가중될 수 있다. 프로그램이 커져도 분리하는 것이 꼭 유리한 것만은 아니다. SQL을 사용하는 클래스가 1000개라면 분리했을 때 2000개가 되어서 더 복잡해질 수도 있다. 그럼에도 불구하고 ibatis에서는 SQL을 분리하는 이유는 무엇일까?
    Separation of Concern!! 할 일의 명확한 분리. 아마도 이것이라 짐작된다. 자바 코드에서 SQL을 없애서 순수 OO로 만들어놓기. 이것은 결벽증이나 지나친 원리집착이 아니라 체계가 다른 것을 나누어 보관하는 것이다. 논리적으로 정연한 흐름을 만들어 둘 수 있고, 객체지향 입장에서 데이터에 해당하는 도메인 모델(Domain model) 혹은 도메인 객체(Domain object)와 관계형 데이터베이스의 테이블(Table)을 느슨한 관계(loosely coupled)로 만들어서 변화에 대한 유연성을 확보할 수도 있다. 즉, 정규화를 위해서 혹은 데이터 접근의 효율성을 위해서 테이블 구조를 바꾸어도 프로그램 코드 안에 있는 SQL을 수정할 필요가 없어진다.
     
  • JDBC 라이브러리를 통해 매개변수를 전달하고 결과를 추출하는 일
    select 등를 할 때 조건에 해당하는 매개변수를 설정하거나, insert 문에서 값을 할당하기 위해 매개변수를 설정하는 일은 무척 번거로운 일이다. 단순한 일이면서도 오류가 잦은 부분이다. 때문에 프로젝트를 몇 차례 겪고 나면 자신만의 라이브러리를 만들거나 공통팀에서 유틸리티를 제공하는 일을 흔하게 볼 수 있다. Apache Commons의 DB Utils 나 Spring의 JDBC Template 등은 이러한 작업을 용이하게 하려고 등장했고, ibatis 역시 이러한 작업을 훨씬 부드럽게 해준다.
     
  • 데이터베이스 접근 클래스와 비즈니스 로직을 담은 클래스의 분리
    이른바 DAO(Data Access Object) 패턴이 이러한 일을 담당한다. ibatis는 DAO 계층 구현을 위한 유틸리티 성격이면서 동시에 best practice 역할도 수행한다.
     
  • 자주 쓰이는 데이터를 변경되지 않는 동안에 임시 보관(Cache)
    ibatis 에선 XML 설정만으로 캐시를 할 수 있다.
     
  • 트랜젝션과 쓰레드 관리
    트랜젝션 처리 역시 용이하다.


    iBATIS의 주요기능 

    Data Mapper (com.ibatis.sqlmap.*)


    개념
    iBATIS Data Mapper API는 프로그래머에게 자바빈즈 객체를 PreparedStatement파라미터와 ResultSets으로 쉽게 맵핑할 수 있도록 한다. Data Mapper의 기본적인 생각은 간단함(simple)이다. 이는 자바코드의 20%를 사용하여 JDBC기능의 80%를 제공하는 간단한 프레임워크라는 뜻이다.


    작동원리
    Data Mapper는 자바빈즈, Map구현, 원시래퍼타입(String, Integer…) 그리고 SQL문을 위한 XML문서를 맵핑하기 위한 XML서술자를 사용하는 매우 간단한 프레임워크를 제공한다.

    다음은 생명주기에 대한 높은 레벨의 서술이다.


    1) 파라미터(자바빈즈, Map 또는 원시래퍼)로써 객체를 제공한다. 파라미터 객체는 update문내에 입력값을 셋팅하기 위해 사용되거나 쿼리문의 where절을 셋팅하기 위해서 사용된다.

    2) 맵핑된 statement을 실행한다. 이 단계는 마법이 일어나는곳이다. Data Mapper프레임워크는
    PreparedStatement 인스턴스를 생성할것이고 제공된 파라미터객체를 사용해서 파라미터를 셋팅한다. 그리고 statement를 실행하고 ResultSet으로부터 결과 객체를 생성한다.

    3) update의 경우에 영향을 미친 rows의 숫자를 반환한다. 조회문일경우에 한 개(single)의 객체 또는 컬렉션 객체를 반환한다. 파라미터처럼 결과 객체는 자바빈즈, Map 원시타입래퍼또는 XML이 될수 있다.

  •  

    출처 : http://blog.empas.com/ahnyounghoe/11535652

     

    ========================================================================================================

     

    가장 간단히 설명하면, JAVA에서 DB관련 작업을 편하게 해주는 프레임웍정도라고 할까?

    iBATIS in action에서 iBATIS는 "SQL 실행 결과를 자바빈즈 혹은 Map 객체에 매핑해주는 퍼시스턴스 솔루션으로 SQL을 소스 코드가 아닌 XML로 따로 분리해 관리하여 지겨운 SQL 문자열 더하기에서 해방시켜 줍니다. 또한 XML에서 동적 SQL 요소를 사용하여 쿼리 문장을 프로그래밍 코딩 없이 자유롭게 변환할 수 있게 해줍니다. 이러한 접근방식으로 인해 iBATIS를 사용하면 JDBC를 사용할 때보다 약 60% 정도의 코드만으로 프로그램 작성이 가능하다" 라고 한다.

    말로만 하면 뭔소리인지 모르겠으니 간단한 예제 정도를 들어보자.


     

    - 일반적인 JDBC 예제
    import javax.naming.*;
    import javax.sql.*;
    import java.sql.*;

    public class Employee {
      public Account getAccount(int id) throws SQLException, NamingException{
        Account account = null;
        
        String sql = "select * from employee where id= ?";
        
        Connection conn      = null;
        PreparedStatement ps = null;
        ResultSet rs       = null;
        
        try {      
          Context ctx = new InitialContext();
          DataSource ds =
                  (DataSource)ctx.lookup(
                     "java:comp/env/jdbc/TestDB"); 
          conn = ds.getConnection();
          ps = conn.prepareStatement(sql);
          ps.setInt(1, id);
          rs = ps.executeQuery();
          
          while( rs.next()){
            account = new Account();
            account.setId(rs.getInt("ID"));        
          }
        } finally {
          try {
            if ( rs != null ) rs.close();
          } finally {
            try {
              if (ps != null) ps.close();
            } finally {
              if (conn != null) ps.close();
            }
          } 
        } 
        return account;  
      }
    }   

    뭐다들 아시겠지만 간단히 쿼리를 날려서 Acount 객체에 담아가지고 오는 소스이다. 대충봐도 무척이나 길다,
    이걸 iBATIS를 이용해서 처리하는 예를 보자, 

    - iBATIS 를 이용한 예
    acount.xml
    <select id="getAcount" resultClass="Acount" parameterClass="java.lang.Integer">
        select * from employee where id= #id#
    </select>

    java
    Acount act = (Acount) sqlMap.queryForObject("getAcount",new Integer(5));
     
    보면 알겠지만 상단에 쿼리를 닮고있는 xml과 아래 간단히 크 쿼리를 실행시키는 java 한줄정도?이다.
    사실 iBATIS를 설정하는 config파일과 sqlMap객체를 불러오는 부분이 있긴하지만, 무척이나 좋아보이도록,
    이것만 쓰겠다. -_-;;

    iBATIS 의 목표와 특징은 몇마디로 짧게정의하다면,

    쉽고, 간단하고, 의존성이 적은 프레임웍이라는 것이다. 
    sql문과 java코드와의 분리만으로도 java개발자는 쿼리문을 신경쓰지 않아도 된다. sql문이 변경되더라도,
    파라미터 값만 변경되지 않는다면, java소스에서는 수정할 부분이 없다.

    ~ 이론적인 면은 대충 접어두고 실전으로 넘어가자(사실 나도잘몰라서;;ㅈㅅ) 

    다음 포스트는 실제로 이클립스에서 오라클 디비와 연동하겠습니다.

     

    출처 : http://beans.tistory.com/36

     

    ========================================================================================================

     

    IBatis 는 XML 에 정의한 SQL 문을 이용하여 일반적으로 작성하는 데이터베이스 프로그래밍의 코드를 현저하게 줄여주는 Database Mapper Framework 이다.

    IBatis 는 Apache Project 에서 나온 오픈소스이며, 자바진영에서는 매우 많이 사용되는 Data Mapper 프레임워크이다.

    IBatis Site 는 http://ibatis.apache.org/ 이며, for.NET 메뉴를 선택하면 해당 프로그램과 도큐멘트를 받을 수 있다.

     

    일반적으로 Web Form 에서 사용자가 데이터를 입력하고 submit 을 하게 되면 데이터베이스에 입력하기 위해서 아래와 같은 방법을 취하게 된다.

     

    1. 입력된 데이터 검증.

    2. SqlConnection 생성 및 연결

    3. SqlCommand 에 파라미터를 대입

    4. 데이터베이스에 입력

    5. 데이터베이스 연결 종료

     

    이것을 코드로 표현하면 아래와 같다.

     

    -------------------------------------------------------------------------

    String sql = "INSERT INTO member (userName, userId, passwd, email, regDate, etc) "

    + " VALUES (@userName, @userId, @passwd, @email, @regDate, @etc)";

     

    SqlConnection conn = new SqlConnection(connectionStr);

     

    SqlCommand command = new SqlCommand();

    command.Connection = conn;

    command.CommandText = sql;

    command.Parameters.AddWithValue("@userName", userName.Text);

    command.Parameters.AddWithValue("@userId", userId.Text);

    command.Parameters.AddWithValue("@passwd", passwd.Text);

    command.Parameters.AddWithValue("@email", email.Text);

    command.Parameters.AddWithValue("@regDate", DateTime.Now);

    command.Parameters.AddWithValue("@etc", etc.Text);

     

    int affectedRow = command.ExecuteNonQuery();

     

    conn.close();

    -------------------------------------------------------------------------

     

    이런 식으로 데이터 입력이 된다.

     

    command 객체에 입력 파라미터를 대입하는 부분이 데이터를 입력하는 부분마다 이런식으로 작업이 되면 계속되는 반복작업으로 효율성이 떨어지게 된다.

     

    뭐 이런 부분들을 작업이 용이하게 만들면 되지 라고 할 수도 있겠지만, 자동화 시키려면 DataSet 이나, 형식화된 DataSet, 사용자 정의 Property, Map 으로 작업해야 하지만, 여기에서 또 문제가 생긴다. 트랜잭션은 어떻게 자동화 시킬 것이며, 매개변수로 넘어오는 object 들을 SqlCommand 객체에 대입할 것이며 등등...

     

    거 리플렉션으로 넘어오는 Object 들을 분석해서 SqlCommand 랑 대입하면 되잖아 할수도 있지만.. 만들려고 하면 이것저것 생각할 것도 많고, 상당히 귀찮은 일이 된다.

    그리고 일을 하다 보면 프로그램을 실제 구현하는 것보다, 남이 만들어 놓은 프로그램을 구해서 작업을 더 많이 하게 되고, 이런 작업속에서 문제가 생겼을 경우 검색엔진을 통해서 남이 먼저 한 삽질을 찾아내서 나의 삽질을 고치게 된다.

     

    이러한 부분을 IBatis.NET 을 이용하면 많은 부분이 해결된다.

     

    위의 코드를 IBatis 로 대입하면 아래와 같이 된다.

     

    1. 먼저 특정 테이블의 컬럼과 형식이 일치하는 객체를 만든다.

    2. 해당 객체에 사용자가 제출한 값을 입력한다.

    3. IBatis 를 입력하여 데이터를 저장한다.

     

    간략하게 소스를 보자

     

    --------------------------------------------------------------------

    // 테이블과 1:1로 대응하는 Object생성

    MemberItem memItem = new MemberItem();

     

    // 데이터베이스에 입력 할 값들을 Object에 입력

    // 아래 소스를 PropertyBinder.Bind(memItem) 처럼 자동화

    memItem.UserName = UserName.Text;

    memItem.UserId = UserId.Text;

    memItem.Passwd = Passwd.Text;

    memItem.Email = Email.Text;

    memItem.RegDate = DateTime.Now;

    memItem.Etc = Etc.Text;

     

    // IBatis 를 이용하여 데이터 입력

    IBatisNet.DataMapper.Mapper.Instance().Insert("createMember", memItem);

    ------------------------------------------------------------------------

     

    소스가 상당히 간략해 졌다.

     

    여기에서 중요한 부분이 있는데 SqlConnection, SqlCommand 를 생성한 부분이 없다.

    연결 문자열 같은 경우는 별도의 설정 파일에 미리 입력해 두면 되고, 이 정보를 이용하여

    IBatis 의 Insert() 가 호출 되면 데이터베이스 입력에 필요한 객체들이 자동으로 만들어 지게 된다.

     

    또한 위의 소스중에서 IBatisNet.DataMapper.Mapper.Instance().Insert("createMember", memItem);

    부분의 Insert 메소드에 "createMember" 라는 부분은 별도의 XML 파일에 정의된 쿼리를 지칭한다.

     

    아래의 xml 부분이 sql query 를 별도로 저장해 놓은 부분이다.

     

    <?xml version="1.0" encoding="utf-8" ?>

     

    <sqlMap namespace="LineItem" xmlns="http://ibatis.apache.org/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >

     

      <resultMaps>

         <resultMap id = "memberMap" class="Member.MemberDTO">

            <result property="idx" column="idx" />

            <result property="userId" column="userId" />

            <result property="passwd" column="passwd" />
            <result property="userName" column="userName" />
            <result property="email" column="email" />
            <result property="etc" column="etc" />
            <result property="regDate" column="regDate" />
         </resultMap>
      </resultMaps>

     

    <statements>
       <insert id="createMember" parameterClass="Member.MemberItem">
             INSERT INTO member (userName, userId, passwd, email, regDate, etc)
             VALUES (#userName#, #userId#, #passwd#, #email#, #regDate#, #etc#)
           <selectKey property="idx" type="post" resultClass="int">
              select @@IDENTITY as value
           </selectKey>
         </insert>
      </statements>
    </sqlMap>

     

    출처 : http://blog.daum.net/cycos88/8

    Posted by 당구치는 개발자
    |
    일상 2016. 9. 23. 16:35



    이해가 안 되는 부분까지도 

    이해해줘야 한다고 말하지만



    그게 말처럼 쉬우면

    다투는 연인은 없을 것이다.



    머리로는 이해가 되어도

    마음이 따라주지 않아서



    퉁명스럽게 말이 나오거나

    행동이 삐딱하게 나오는 것이다.



    상황이 아무리 힘들어도

    이겨내야 한다고 말하지만



    그게 말처럼 쉬우면

    헤어지는 연인은 없을 것이다.



    사랑도 현실 속에서

    주고받는 것인데



    현실을 완전히 외면하며

    연애를 하는 건 어려운 일이다.



    지겨울 만큼 수없이 다퉈도

    대화로 풀면 된다고 말하지만



    그게 말처럼 쉬우면

    불행한 연인은 없을 것이다.



    지긋지긋할 정도로 다투면

    남아있던 사랑조차 메말라서



    다툼을 피하기 위해

    상대방을 외면하는 순간이 온다.



    행복한 연애를 하는 방법은

    누구나 알고 있다.



    다만 그것이 생각만큼 쉽지 않아서

    많은 연인들이 헤어지는 것이다.



    말처럼 쉽지 않은 사랑을

    말처럼 사랑하고 있다면



    아마 당신이 죽을힘을 다해

    노력하고 있거나



    상대방이 자신의 속을 태우며

    노력하고 있는 것이다.



    두 사람이 사랑을 유지하기 위해

    애타게 노력하고 있다는 증이니



    사랑앞에서

    자만하지 말기를 바란다




    출처 (글) : https://www.pikicast.com/#!/menu=landing&content_id=186989

    출처 (사진) : http://allyouneedisdreamanddream.tumblr.com/

    '일상' 카테고리의 다른 글

    내가 하는 후회  (0) 2016.10.04
    달달함  (0) 2016.10.03
    IT 발전에대한 고찰  (0) 2016.09.30
    이해와 오해  (0) 2016.09.23
    선택의 결과와 적응  (0) 2016.09.22
    Posted by 당구치는 개발자
    |
    사이트 2016. 9. 23. 14:37

    *******************************************


    네이버 : http://www.naver.com/


    다음http://www.daum.net/


    구글https://www.google.com/


    *******************************************


    네이버 사전http://dic.naver.com/


    네이버 지하철http://map.naver.com/?menu=subway


    네이버 지도http://map.naver.com/


    구글 번역기https://translate.google.co.kr/


    *******************************************


    내 블로그http://jonghoit.tistory.com/


    *******************************************


    예비군http://www.yebigun1.mil.kr/


    국세청 http://www.nts.go.kr/


    홈택스 https://www.hometax.go.kr/









    Posted by 당구치는 개발자
    |