Tools iBatis 용 코드 생성기 Abator(iBATOR)

황제낙엽 2009.03.02 02:04 조회 수 : 194 추천:74

sitelink1  
sitelink2  
extra_vars5  
extra_vars6  
http://ibatis.apache.org/docs/tools/abator/http://kyungseo.pe.kr/blog/63지난 프로젝트에서 iBatis를 사용하면 어베이터(Abator 1.0.0-238)라는 코드 생성기를 함께 활용했었다(abator는 얼마전에 공식 명칭이 iBATOR로 변경되었다).

iBatis용 코드 생성기는 abator 말고도 몇가지가 더 있는데, 이왕이면 iBatis에서 권장하는 툴을 사용하는 것이 좋지 않겠나 하는 생각이 있었고 abator를 제외한 툴들은 더이상 업데이트가 안되고 있었는 것도 abator를 선택한 이유였다.

관련 코드를 자동으로 생성해주는 것 까진 좋았는데, 필드 및 메서드 마다 붙어버리는 abator 관련 주석들이 코드를 지저분하게 만들고 가독성을 떨어뜨리는 단점이 있다. 그리고 기본적인 CRUD를 제외한 쿼리들과 Stored Procedure의 경우는 어쩔 수 없이 수동으로 편집을 해야했기 때문에, 프로젝트 말미엔 abator의 활용도가 많이 떨어지지 않았었나 싶다.

누가 abator를 사용함으로써 개발 효율이 높아졌느냐고 물어본다면, 직접 써보고 판단하라고 얘기하고 싶다. 아무튼 득실을 따진다면 사견이지만, 잃을 건 없다라는 것.

아래는 개발자들을 위해서 작성했던 간단한 소개 자료를 첨삭한 내용이다.


Abator

Abator는 iBATIS를 위한 코드 생성기이다. Abator는 데이터베이스의 테이블에 접근하기 위한 iBATIS 연관 코드들인 Object와 환경 설정 파일(configuration file)을 생성하며, 기본적인 CRUD(Create, Retrieve, Update, Delete) 쿼리를 포함한다.

Abator 설치를 위한 특별한 의존성은 없지만 다음 조건을 만족해야 한다.

  • JRE 1.4 이상.
  • DatabaseMetaData 인터페이스를 구현하는 JDBC 드라이버가 필요하다.

Abator가 생성하는 코드(파일) 목록은 다음과 같다.

  • 테이블 구조에 매치되는 자바 POJOs
  • iBATIS 호환 SQL Map XML 파일들
  • DAO 인터페이스와 구현 클래스들


Abator 사용

1. 설정 파일 작성 - abatorConfig.xml

적절한 설정 파일을 생성한다. 설정은 적어도 다음 요소들을 포함하여야 한다(Abator 사이트 참고).

  • A <jdbcConnection> element to specify how to connect to the target database
  • A <javaModelGenerator> element to specify target package and target project for generated Java model objects
  • A <sqlMapGenerator> element to specify target package and target project for generated SQL map files
  • (Optionally) A <daoGenerator> element to specify target package and target project for generated DAO interfaces and classes (you can omit the <daoGenerator> element if you don't wish to generate DAOs)
  • At least one database <table> element

다음은 abatorConfig.xml의 예제이다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE abatorConfiguration
  PUBLIC "-//Apache Software Foundation//DTD Abator for iBATIS Configuration 1.0//EN"
  "http://ibatis.apache.org/dtd/abator-config_1_0.dtd">
 
<!-- ===================================================================== -->
<!-- Abator Config File                                                    -->
<!-- XXX Project, Kyungseo.Park@gmail.com, 2007.10                         -->
<!-- ===================================================================== -->
 
<abatorConfiguration>
  <abatorContext id="SybaseTables" generatorSet="Java5">
 
    <!-- ================================================================= -->
    <!-- jdbcConnection                                                    -->
    <!-- ================================================================= -->
 
   
<jdbcConnection driverClass="com.sybase.jdbc3.jdbc.SybDriver"
        connectionURL="jdbc:sybase:Tds:192.168.1.5:3000/sybdb"
        userId="sybdb"
        password="sybdb">

      <classPathEntry location="jconn3.jar" />
    </jdbcConnection>
 
   
<!--
    <jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver"
        connectionURL="jdbc:oracle:thin:@129.110.30.30:1521:oradb"
        userId="oradb"
        password="oradb">

      <classPathEntry location="classes12.jar" />
    </jdbcConnection>
    -->
 
    <!-- ================================================================= -->
    <!-- javaTypeResolver                                                  -->
    <!-- ================================================================= -->
 
    <javaTypeResolver >
      <property name="forceBigDecimals" value="false" />
    </javaTypeResolver>
 
    <!-- ================================================================= -->
    <!-- javaModelGenerator                                                -->
    <!-- ================================================================= -->
 
   
<javaModelGenerator targetPackage="xxx.business.sys.domain"
targetProject="XxxProjectsrc">

      <property name="enableSubPackages" value="true" />
      <property name="trimStrings" value="true" />
      <property name="rootClass" value="xxx.framework.base.BaseObject" />
    </javaModelGenerator>
 
    <!-- ================================================================= -->
    <!-- sqlMapGenerator                                                   -->
    <!-- ================================================================= -->
 
   
<sqlMapGenerator targetPackage="xxx.resources.sql.sys"
targetProject="XxxProjectsrc">

      <property name="enableSubPackages" value="true" />
    </sqlMapGenerator>
 
    <!-- ================================================================= -->
    <!-- daoGenerator                                                      -->
    <!-- ================================================================= -->
 
   
<daoGenerator type="IBATIS" targetPackage="xxx.business.sys.dao"
targetProject="XxxProjectsrc">

      <property name="enableSubPackages" value="true" />
      <property name="rootInterface" value="xxx.framework.base.BaseDao" />
    </daoGenerator>
 
    <!-- ================================================================= -->
    <!-- table                                                             -->
    <!-- ================================================================= -->
 
    <table tableName="TM_XXX_ROLE" domainObjectName="Role" >
      <property name="useActualColumnNames" value="true"/>
    </table>
 
  </abatorContext>
</abatorConfiguration>


2. Abator 실행(Run)

커맨드 라인을 열고 다음과 같이 입력하여 Abator를 실행할 수 있다. 단, 설정 파일에 정의된 targetProject의 대상 디렉토리는 반드시 미리 존재해야 한다.

java -jar abator.jar abatorConfig.xml false
java -jar abator.jar abatorConfig.xml true
java -cp abator.jar org.apache.ibatis.abator.api.AbatorRunner abatorConfig.xml false
java -cp abator.jar org.apache.ibatis.abator.api.AbatorRunner abatorConfig.xml true

여기서 파라미터의 의미는 다음과 같다.

  • 첫번째 파라미터: 환경 파일의 경로
  • 두번째 파라미터: 파일이 이미 존재할 경우 overwrite 여부

abator 실행을 위한 간단한 배치 파일을 만들어 놓으면 편하다.  예를 들어 “abator.bat” 파일을 만들어 다음과 같이 편집한다.

java -jar abator.jar abatorConfig.xml true

3. Abator 실행 후 작업

다음과 같은 마무리 작업이 필요하다.

  • SqlMapConfig.xml 파일을 생성하거나 편집한다.
  • iBATIS DAO Framework를 사용할 경우, dao.xml 파일을 생성하거나 편집한다.


Abator로 생성된 코드 예제

1. Java Model Classes

Domain Class

package xxx.business.sys.domain;
 
import xxx.framework.base.BaseObject;
import java.util.Date;
 
public class Role extends BaseObject {
   
/**
     * This field was generated by Abator for iBATIS.
     * This field corresponds to the database column TM_XXX_ROLE.role_nmbr
     *
     * @abatorgenerated Wed Nov 28 17:31:32 KST 2007.
     */

    private
Integer role_nmbr;
 
   
/**
     * This field was generated by Abator for iBATIS.
     * This field corresponds to the database column TM_XXX_ROLE.role_nm
     *
     * @abatorgenerated Wed Nov 28 17:31:32 KST 2007.
     */

    private
String role_nm;
 
    ...
    // member field 들에 대한 setter 및 getter
    ...
 
}


Domain Example Classes

package xxx.business.sys.domain;
 
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class RoleExample {
   
/**
     * This field was generated by Abator for iBATIS.
     * This field corresponds to the database table TM_XXX_ROLE
     *
     * @abatorgenerated Wed Nov 28 17:31:32 KST 2007.
     */

    private
String orderByClause;
 
   
/**
     * This field was generated by Abator for iBATIS.
     * This field corresponds to the database table TM_XXX_ROLE
     *
     * @abatorgenerated Wed Nov 28 17:31:32 KST 2007.
     */

    private List<Criteria> oredCriteria = new ArrayList<Criteria>();
 
   
/**
     * This method was generated by Abator for iBATIS.
     * This method corresponds to the database table TM_XXX_ROLE
     *
     * @abatorgenerated Wed Nov 28 17:31:32 KST 2007.
     */

    public void setOrderByClause(
String orderByClause) {
        this.orderByClause = orderByClause;
    }
 
   
/**
     * This method was generated by Abator for iBATIS.
     * This method corresponds to the database table TM_XXX_ROLE
     *
     * @abatorgenerated Wed Nov 28 17:31:32 KST 2007.
     */

    public
String getOrderByClause() {
        return orderByClause;
    }
 
   
/**
     * This method was generated by Abator for iBATIS.
     * This method corresponds to the database table TM_XXX_ROLE
     *
     * @abatorgenerated Wed Nov 28 17:31:32 KST 2007.
     */

    public List<Criteria> getOredCriteria() {
        return oredCriteria;
    }
 
    ...
 
}


2. SQL Map Files

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd" >
<sqlMap namespace="TM_XXX_ROLE" >
  <resultMap id="abatorgenerated_RoleResult" class="xxx.business.sys.domain.Role" >
   
<!--
      WARNING - This element is automatically generated by Abator for iBATIS, do not modify.
      This element was generated on Wed Nov 28 17:31:32 KST 2007.
    -->

    <result column="role_nmbr" property="role_nmbr" jdbcType="INTEGER" />
    <result column="role_nm" property="role_nm" jdbcType="VARCHAR" />
    <result column="rmrk" property="rmrk" jdbcType="VARCHAR" />
    <result column="sys_mngm_ysno" property="sys_mngm_ysno" jdbcType="CHAR" />
    <result column="rgsr" property="rgsr" jdbcType="CHAR" />
    <result column="rgsr_dttm" property="rgsr_dttm" jdbcType="TIMESTAMP" />
    <result column="amnd" property="amnd" jdbcType="CHAR" />
    <result column="amnd_dttm" property="amnd_dttm" jdbcType="TIMESTAMP" />
  </resultMap>
  <sql id="abatorgenerated_Example_Where_Clause" >
   
<!--
      WARNING - This element is automatically generated by Abator for iBATIS, do not modify.
      This element was generated on Wed Nov 28 17:31:32 KST 2007.
    -->

    <iterate property="oredCriteria" conjunction="or" prepend="where" removeFirstPrepend="iterate" >
      (
      <iterate prepend="and" property="oredCriteria[].criteriaWithoutValue" conjunction="and" >
        $oredCriteria[].criteriaWithoutValue[]$
      </iterate>
      <iterate prepend="and" property="oredCriteria[].criteriaWithSingleValue" conjunction="and" >
        $oredCriteria[].criteriaWithSingleValue[].condition$
          #oredCriteria[].criteriaWithSingleValue[].value#
      </iterate>
      <iterate prepend="and" property="oredCriteria[].criteriaWithListValue" conjunction="and" >
        $oredCriteria[].criteriaWithListValue[].condition$
        <iterate property="oredCriteria[].criteriaWithListValue[].values" open="(" close=")" conjunction="," >
          #oredCriteria[].criteriaWithListValue[].values[]#
        </iterate>
      </iterate>
      <iterate prepend="and" property="oredCriteria[].criteriaWithBetweenValue" conjunction="and" >
        $oredCriteria[].criteriaWithBetweenValue[].condition$
        #oredCriteria[].criteriaWithBetweenValue[].values[0]# and
        #oredCriteria[].criteriaWithBetweenValue[].values[1]#
      </iterate>
      )
    </iterate>
  </sql>
  <select id="abatorgenerated_selectByPrimaryKey" resultMap="abatorgenerated_RoleResult" parameterClass="xxx.business.sys.domain.Role" >
   
<!--
      WARNING - This element is automatically generated by Abator for iBATIS, do not modify.
      This element was generated on Wed Nov 28 17:31:32 KST 2007.
    -->

    select role_nmbr, role_nm, rmrk, sys_mngm_ysno, rgsr, rgsr_dttm, amnd, amnd_dttm
    from TM_XXX_ROLE
    where role_nmbr = #role_nmbr:INTEGER#
  </select>
  <select id="abatorgenerated_selectByExample" resultMap="abatorgenerated_RoleResult" parameterClass="xxx.business.sys.domain.RoleExample" >
   
<!--
      WARNING - This element is automatically generated by Abator for iBATIS, do not modify.
      This element was generated on Wed Nov 28 17:31:32 KST 2007.
    -->

    select role_nmbr, role_nm, rmrk, sys_mngm_ysno, rgsr, rgsr_dttm, amnd, amnd_dttm
    from TM_XXX_ROLE
    <isParameterPresent >
      <include refid="TM_XXX_ROLE.abatorgenerated_Example_Where_Clause" />
      <isNotNull property="orderByClause" >
        order by $orderByClause$
      </isNotNull>
    </isParameterPresent>
  </select>
  <delete id="abatorgenerated_deleteByPrimaryKey" parameterClass="xxx.business.sys.domain.Role" >
   
<!--
      WARNING - This element is automatically generated by Abator for iBATIS, do not modify.
      This element was generated on Wed Nov 28 17:31:32 KST 2007.
    -->

    delete from TM_XXX_ROLE
    where role_nmbr = #role_nmbr:INTEGER#
  </delete>
  <delete id="abatorgenerated_deleteByExample" parameterClass="xxx.business.sys.domain.RoleExample" >
   
<!--
      WARNING - This element is automatically generated by Abator for iBATIS, do not modify.
      This element was generated on Wed Nov 28 17:31:32 KST 2007.
    -->

    delete from TM_XXX_ROLE
    <include refid="TM_XXX_ROLE.abatorgenerated_Example_Where_Clause" />
  </delete>
  <insert id="abatorgenerated_insert" parameterClass="xxx.business.sys.domain.Role" >
   
<!--
      WARNING - This element is automatically generated by Abator for iBATIS, do not modify.
      This element was generated Wed Nov 28 17:31:32 KST 2007.
    -->

    insert into TM_XXX_ROLE (role_nmbr, role_nm, rmrk, sys_mngm_ysno, rgsr, rgsr_dttm, amnd,
      amnd_dttm)
    values (#role_nmbr:INTEGER#, #role_nm:VARCHAR#, #rmrk:VARCHAR#, #sys_mngm_ysno:CHAR#,
      #rgsr:CHAR#, #rgsr_dttm:TIMESTAMP#, #amnd:CHAR#, #amnd_dttm:TIMESTAMP#)
  </insert>
  <update id="abatorgenerated_updateByPrimaryKey" parameterClass="xxx.business.sys.domain.Role" >
   
<!--
      WARNING - This element is automatically generated by Abator for iBATIS, do not modify.
      This element was generated on Wed Nov 28 17:31:32 KST 2007.
    -->

    update TM_XXX_ROLE
    set role_nm = #role_nm:VARCHAR#,
      rmrk = #rmrk:VARCHAR#,
      sys_mngm_ysno = #sys_mngm_ysno:CHAR#,
      rgsr = #rgsr:CHAR#,
      rgsr_dttm = #rgsr_dttm:TIMESTAMP#,
      amnd = #amnd:CHAR#,
      amnd_dttm = #amnd_dttm:TIMESTAMP#
    where role_nmbr = #role_nmbr:INTEGER#
  </update>
  <update id="abatorgenerated_updateByPrimaryKeySelective" parameterClass="xxx.business.sys.domain.Role" >
   
<!--
      WARNING - This element is automatically generated by Abator for iBATIS, do not modify.
      This element was generated on Wed Nov 28 17:31:32 KST 2007.
    -->

    update TM_XXX_ROLE
    <dynamic prepend="set" >
      <isNotNull prepend="," property="role_nm" >
        role_nm = #role_nm:VARCHAR#
      </isNotNull>
      <isNotNull prepend="," property="rmrk" >
        rmrk = #rmrk:VARCHAR#
      </isNotNull>
      <isNotNull prepend="," property="sys_mngm_ysno" >
        sys_mngm_ysno = #sys_mngm_ysno:CHAR#
      </isNotNull>
      <isNotNull prepend="," property="rgsr" >
        rgsr = #rgsr:CHAR#
      </isNotNull>
      <isNotNull prepend="," property="rgsr_dttm" >
        rgsr_dttm = #rgsr_dttm:TIMESTAMP#
      </isNotNull>
      <isNotNull prepend="," property="amnd" >
        amnd = #amnd:CHAR#
      </isNotNull>
      <isNotNull prepend="," property="amnd_dttm" >
        amnd_dttm = #amnd_dttm:TIMESTAMP#
      </isNotNull>
    </dynamic>
    where role_nmbr = #role_nmbr#
  </update>
</sqlMap>


3. Java DAO Classes(optional)

DAO Interface

package xxx.business.sys.dao;
 
import xxx.business.sys.domain.Role;
import xxx.business.sys.domain.RoleExample;
import xxx.framework.base.BaseDao;
import java.util.List;
 
public interface RoleDAO extends BaseDao {
   
/**
     * This method was generated by Abator for iBATIS.
     * This method corresponds to the database table TM_XXX_ROLE
     *
     * @abatorgenerated Wed Nov 28 17:31:32 KST 2007
     */

    void insert(Role record);
 
   
/**
     * This method was generated by Abator for iBATIS.
     * This method corresponds to the database table TM_XXX_ROLE
     *
     * @abatorgenerated Wed Nov 28 17:31:32 KST 2007
     */

    int updateByPrimaryKey(Role record);
 
   
/**
     * This method was generated by Abator for iBATIS.
     * This method corresponds to the database table TM_XXX_ROLE
     *
     * @abatorgenerated Thu Dec 13 16:43:17 KST 2007
     */

    int updateByPrimaryKeySelective(Role record);
 
    ...
 
}


DAO Implement

package xxx.business.sys.dao;
 
import xxx.business.sys.domain.Role;
import xxx.business.sys.domain.RoleExample;
import com.ibatis.dao.client.DaoManager;
import com.ibatis.dao.client.template.SqlMapDaoTemplate;
import java.util.List;
 
public class RoleDAOImpl extends SqlMapDaoTemplate implements RoleDAO {
 
   
/**
     * This method was generated by Abator for iBATIS.
     * This method corresponds to the database table TM_XXX_ROLE
     *
     * @abatorgenerated Wed Nov 28 17:31:32 KST 2007
     */

    public RoleDAOImpl(DaoManager daoManager) {
        super(daoManager);
    }
 
   
/**
     * This method was generated by Abator for iBATIS.
     * This method corresponds to the database table TM_XXX_ROLE
     *
     * @abatorgenerated Wed Nov 28 17:31:32 KST 2007
     */

    public void insert(Role record) {
        insert("TM_XXX_ROLE.abatorgenerated_insert", record);
    }
 
    ...
 
}



참고 사이트