개발자의 끄적끄적

[java / spring] ibatis 란?[펌] 본문

개발/java & jsp

[java / spring] ibatis 란?[펌]

효벨 2019. 12. 12. 00:55
728x90
반응형

[java / spring] ibatis 란?[펌]

 

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



출처: https://jonghoit.tistory.com/73 [당구치는 개발자]

반응형
Comments