ibator是iBATIS的一个代码生成工具,关于它的定制,可以参考JavaEye上两篇博文:
但在决定对ibator定制前,有几个问题需要思考:
其中最需要注意的是编码规范问题,否则定制出来的代码不符合规范,大家还是需要花时间调整。
结合我们这边的一些实际情况,就这几个问题分别进行下解答。
【注:我们定制的是ibator 1.2.2 使用的iBATIS版本号 2.3.4.726】
1.为什么要定制
原有版本的问题
2.哪些功能需要定制
对ibator的定制动作对代码的调整类型上可以分为三类:
如:
update类 调整DAO方法顺序为 增 删 改 查 其他
delete类 删除Model[POJO、Domain]类getter/setter方法注释、删除默认生成的示例方法或类
insert类 在Model类中覆盖Object的toString() 提取表字段注释为Model属性文档注释 为DAO增加翻页等常用方法 增加生成Service Action等代码 增加自动调整配置文件
可以先从简单做起,不要想着一下子做完美
3.编码规范
Model、DAO、DAO实现、sqlmap XML的编码规范分别,结合实际代码进行说明:
Model类
package mov.common.domain; import org.apache.commons.lang.builder.ToStringBuilder; /** * Ip段 */ public class IpSection { /** IP段编号 */ private Integer sectionId; /** 开始IP */ private Long sIp; /** 结束IP */ private Long eIp; /** 开始IP */ private String startIp; /** 结束IP */ private String endIp; /** 国家编码:1中国 -1未知 */ private Integer countryCode; /** 国家编码:1中国 -1未知 */ private Integer provinceCode; /** 国家编码:1中国 -1未知 */ private Integer areaCode; /** 国家编码:1中国 -1未知 */ private Integer subAreaCode; /** 网络接入商类型, 1联通 2电信 4铁通 5长城宽带 6教育网 -1未知 */ private Integer networkProvider; /** 地域描述 */ private String areaDesc; @Override public String toString() { return ToStringBuilder.reflectionToString(this); } // getter && setters 省略 }
Model类一般约定:
1.property尽量使用包装类而非基本类型,以便于判断用户是否输入内容
2.property使用文档注释,尽量只占用一行
3.覆盖Object#toString()方法,并且toString()方法在getter、setter方法前
DAO接口
package mov.common.dao; import mov.common.domain.IpSection; /** * IP段DAO接口 */ public interface IpSectionDAO { Integer insert(IpSection record); Integer insertSelective(IpSection record); int deleteByPrimaryKey(int sectionId); int updateByPrimaryKey(IpSection record); int updateByPrimaryKeySelective(IpSection record); IpSection selectByPrimaryKey(int sectionId); }
DAO接口一般约定:
1.根据主键删除、根据主键获取单行尽量使用基本类型
2.方法按照增、删、改、查的前后顺序分组排列
3.增 删 改返回值类型保存ibator原有返回值,增加返回Integer 删除 修改 返回int
DAO实现类
package mov.common.dao.impl; import mov.common.dao.IpSectionDAO; import mov.common.domain.IpSection; import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport; /** * IP段DAO实现 */ public class IpSectionDAOImpl extends SqlMapClientDaoSupport implements IpSectionDAO { public Integer insert(IpSection record) { return (Integer) getSqlMapClientTemplate().insert( "ip_section.insert", record); } public Integer insertSelective(IpSection record) { return (Integer) getSqlMapClientTemplate().insert( "ip_section.insertSelective", record); } public int deleteByPrimaryKey(int sectionId) { return getSqlMapClientTemplate().delete( "ip_section.deleteByPrimaryKey", sectionId); } public int updateByPrimaryKey(IpSection record) { return getSqlMapClientTemplate().update( "ip_section.updateByPrimaryKey", record); } public int updateByPrimaryKeySelective(IpSection record) { return getSqlMapClientTemplate().update( "ip_section.updateByPrimaryKeySelective", record); } public IpSection selectByPrimaryKey(int sectionId) { return (IpSection) getSqlMapClientTemplate().queryForObject( "ip_section.selectByPrimaryKey", sectionId); } }
DAO实现一般约束:
1.尽量减少中间变量,ibator原版中生成的方法体有些冗余
2.应用的SQL需要使用命名空间
sqlmap XML
<?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="ip_section" > <typeAlias alias="IpSection" type="cn.xxt.common.domain.IpSection"/> <resultMap id="BaseResultMap" class="IpSection" > <result column="section_id" property="sectionId" jdbcType="INTEGER" /> <result column="s_ip" property="sIp" jdbcType="INTEGER" /> <result column="e_ip" property="eIp" jdbcType="INTEGER" /> <result column="start_ip" property="startIp" jdbcType="VARCHAR" /> <result column="end_ip" property="endIp" jdbcType="VARCHAR" /> <result column="country_code" property="countryCode" jdbcType="INTEGER" /> <result column="province_code" property="provinceCode" jdbcType="INTEGER" /> <result column="area_code" property="areaCode" jdbcType="INTEGER" /> <result column="sub_area_code" property="subAreaCode" jdbcType="INTEGER" /> <result column="network_provider" property="networkProvider" jdbcType="TINYINT" /> <result column="area_desc" property="areaDesc" jdbcType="VARCHAR" /> </resultMap> <sql id="Base_Column_List" > section_id, s_ip, e_ip, start_ip, end_ip, country_code, province_code, area_code, sub_area_code, network_provider, area_desc </sql> <!-- ======================================================================== INSERT ========================================================================= --> <insert id="insert" parameterClass="IpSection" > <selectKey resultClass="java.lang.Integer" keyProperty="sectionId" > SELECT nextval('s_ip_section') </selectKey> insert into ip_section (section_id, s_ip, e_ip, start_ip, end_ip, country_code, province_code, area_code, sub_area_code, network_provider, area_desc) values (#sectionId:INTEGER#, #sIp:INTEGER#, #eIp:INTEGER#, #startIp:VARCHAR#, #endIp:VARCHAR#, #countryCode:INTEGER#, #provinceCode:INTEGER#, #areaCode:INTEGER#, #subAreaCode:INTEGER#, #networkProvider:TINYINT#, #areaDesc:VARCHAR#) </insert> <insert id="insertSelective" parameterClass="IpSection" > <selectKey resultClass="java.lang.Integer" keyProperty="sectionId" > SELECT nextval('s_ip_section') </selectKey> insert into ip_section <dynamic prepend="(" > <isNotNull prepend="," property="sectionId" > section_id </isNotNull> <isNotNull prepend="," property="sIp" > s_ip </isNotNull> <isNotNull prepend="," property="eIp" > e_ip </isNotNull> <isNotNull prepend="," property="startIp" > start_ip </isNotNull> <isNotNull prepend="," property="endIp" > end_ip </isNotNull> <isNotNull prepend="," property="countryCode" > country_code </isNotNull> <isNotNull prepend="," property="provinceCode" > province_code </isNotNull> <isNotNull prepend="," property="areaCode" > area_code </isNotNull> <isNotNull prepend="," property="subAreaCode" > sub_area_code </isNotNull> <isNotNull prepend="," property="networkProvider" > network_provider </isNotNull> <isNotNull prepend="," property="areaDesc" > area_desc </isNotNull> ) </dynamic> values <dynamic prepend="(" > <isNotNull prepend="," property="sectionId" > #sectionId:INTEGER# </isNotNull> <isNotNull prepend="," property="sIp" > #sIp:INTEGER# </isNotNull> <isNotNull prepend="," property="eIp" > #eIp:INTEGER# </isNotNull> <isNotNull prepend="," property="startIp" > #startIp:VARCHAR# </isNotNull> <isNotNull prepend="," property="endIp" > #endIp:VARCHAR# </isNotNull> <isNotNull prepend="," property="countryCode" > #countryCode:INTEGER# </isNotNull> <isNotNull prepend="," property="provinceCode" > #provinceCode:INTEGER# </isNotNull> <isNotNull prepend="," property="areaCode" > #areaCode:INTEGER# </isNotNull> <isNotNull prepend="," property="subAreaCode" > #subAreaCode:INTEGER# </isNotNull> <isNotNull prepend="," property="networkProvider" > #networkProvider:TINYINT# </isNotNull> <isNotNull prepend="," property="areaDesc" > #areaDesc:VARCHAR# </isNotNull> ) </dynamic> </insert> <!-- ======================================================================== DELETE ========================================================================= --> <delete id="deleteByPrimaryKey" parameterClass="int" > delete from ip_section where section_id = #sectionId:INTEGER# </delete> <!-- ======================================================================== UPDATE ========================================================================= --> <update id="updateByPrimaryKey" parameterClass="IpSection" > update ip_section set s_ip = #sIp:INTEGER#, e_ip = #eIp:INTEGER#, start_ip = #startIp:VARCHAR#, end_ip = #endIp:VARCHAR#, country_code = #countryCode:INTEGER#, province_code = #provinceCode:INTEGER#, area_code = #areaCode:INTEGER#, sub_area_code = #subAreaCode:INTEGER#, network_provider = #networkProvider:TINYINT#, area_desc = #areaDesc:VARCHAR# where section_id = #sectionId:INTEGER# </update> <update id="updateByPrimaryKeySelective" parameterClass="IpSection" > update ip_section <dynamic prepend="set" > <isNotNull prepend="," property="sIp" > s_ip = #sIp:INTEGER# </isNotNull> <isNotNull prepend="," property="eIp" > e_ip = #eIp:INTEGER# </isNotNull> <isNotNull prepend="," property="startIp" > start_ip = #startIp:VARCHAR# </isNotNull> <isNotNull prepend="," property="endIp" > end_ip = #endIp:VARCHAR# </isNotNull> <isNotNull prepend="," property="countryCode" > country_code = #countryCode:INTEGER# </isNotNull> <isNotNull prepend="," property="provinceCode" > province_code = #provinceCode:INTEGER# </isNotNull> <isNotNull prepend="," property="areaCode" > area_code = #areaCode:INTEGER# </isNotNull> <isNotNull prepend="," property="subAreaCode" > sub_area_code = #subAreaCode:INTEGER# </isNotNull> <isNotNull prepend="," property="networkProvider" > network_provider = #networkProvider:TINYINT# </isNotNull> <isNotNull prepend="," property="areaDesc" > area_desc = #areaDesc:VARCHAR# </isNotNull> </dynamic> where section_id = #sectionId:INTEGER# </update> <!-- ======================================================================== SELECT ========================================================================= --> <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterClass="int" > select <include refid="ip_section.Base_Column_List" /> from ip_section where section_id = #sectionId:INTEGER# </select> </sqlMap>
sqlmap XML一般约束
1.按照resultMap sql片段 增 删 改 查的顺序分组排列
2.由于XML文件一般长度会较长,建议对增 删 改 查 增加类似示例中的注释以方便快速
这些规范仅仅是我们这儿的一些粗略约定,读者需要根据所在公司的实际情况进行认真、细致的分析
定制ibator并不是特别难,但是要定制一个实用、符合规范的ibator必须做好这些准备工作,否则事倍功半,何苦折腾呢!