mybatis-自定義TypeHandler

步驟1:實(shí)現(xiàn)TypeHandler接口

import java.sql.CallableStatement;
import java.sql.PreparedStatement;    
import java.sql.ResultSet;    
import java.sql.SQLException;    
    
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;
    
/**  
 * @author   
 * java中的boolean和jdbc中的char之間轉(zhuǎn)換;true-Y;false-N  
 */
//方式一:
@MappedJdbcTypes(JdbcType.CHAR)
@MappedTypes(Boolean.class)
public class BooleanTypeHandler implements TypeHandler {    
    
    /* (non-Javadoc)  
     * @see org.apache.ibatis.type.TypeHandler#getResult(java.sql.ResultSet, java.lang.String)  
     */    
    @Override    
    public Object getResult(ResultSet resultSet, String columnLabel) throws SQLException {
        String str = resultSet.getString(columnLabel);
        Boolean rt = Boolean.FALSE;    
        if (str.equalsIgnoreCase("Y")){
            rt = Boolean.TRUE;    
        }    
        return rt;     
    }

    @Override
    public Object getResult(ResultSet resultSet, int columnIndex) throws SQLException {
        String str = resultSet.getString(columnIndex);
        Boolean rt = Boolean.FALSE;
        if (str.equalsIgnoreCase("Y")){
            rt = Boolean.TRUE;
        }
        return rt;
    }

    /* (non-Javadoc)  
     * @see org.apache.ibatis.type.TypeHandler#getResult(java.sql.CallableStatement, int)  
     */    
    @Override    
    public Object getResult(CallableStatement arg0, int arg1)    
            throws SQLException {    
        Boolean b = arg0.getBoolean(arg1);    
        return b == true ? "Y" : "N";    
    }    
    
    /* (non-Javadoc)  
     * @see org.apache.ibatis.type.TypeHandler#setParameter(java.sql.PreparedStatement, int, java.lang.Object, org.apache.ibatis.type.JdbcType)  
     */    
    @Override    
    public void setParameter(PreparedStatement arg0, int arg1, Object arg2,    
            JdbcType arg3) throws SQLException {    
        Boolean b = (Boolean) arg2;    
        String value = (Boolean) b == true ? "Y" : "N";    
        arg0.setString(arg1, value);    
    }    
}    

步驟2:在Mybatis配置中注冊(cè)該TypeHandler

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="mapperLocations" value="classpath:dao/mapper/*.xml"></property>
        <property name="typeHandlers" >
            <array>
                <bean class="com.sankuai.travel.csc.test.dao.typehandler.BooleanTypeHandler" />
            </array>
        </property>
        <property name="plugins">
            <array>
                <bean class="com.sankuai.travel.csc.test.dao.interceptor.SqlMonitorInterceptor" />
            </array>
        </property>
    </bean>

步驟3:在映射配置文件中使用該TypeHander(如果第一步使用了注解,此處可以省略)

3.1在resultMap的定義中對(duì)對(duì)應(yīng)列定義typeHandler

<resultMap id="BaseResultMap" type="com.sankuai.travel.csc.test.dao.domain.CategoryDO" >
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="category_type" property="categoryType" jdbcType="INTEGER" />
    <result column="category_name" property="categoryName" jdbcType="VARCHAR" />
    <result column="allocate_time" property="allocateTime" jdbcType="INTEGER" />
    <result column="promise_time" property="promiseTime" jdbcType="INTEGER" />
    <result column="last_operator" property="lastOperator" jdbcType="VARCHAR" />
    <result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />

    <!--寫(xiě)在這里豺裆,僅對(duì)select語(yǔ)句有效斧蜕,typeHandler="com.sankuai.travel.csc.test.dao.typehandler.BooleanTypeHandler" -->
    <result column="is_cancel" property="isCancel" jdbcType="CHAR" typeHandler="com.sankuai.travel.csc.test.dao.typehandler.BooleanTypeHandler"/>

    <result column="status1" property="status1" jdbcType="CHAR" />
    <result column="status2" property="status2" jdbcType="CHAR" />
    <result column="phone_list" property="phoneList" jdbcType="VARCHAR" />
    <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
  </resultMap>

這里只能是在select的時(shí)候才會(huì)使用自定義的TypeHandler處理對(duì)應(yīng)的映射關(guān)系,如果要在insert或者update時(shí)使用則需要在sql定義中添加相應(yīng)的內(nèi)容

3.2在resultMap的定義中對(duì)對(duì)應(yīng)列定義typeHandler

<insert id="insert" parameterType="com.sankuai.travel.csc.test.dao.domain.CategoryDO" >
    <selectKey resultType="java.lang.Integer" keyProperty="id" order="AFTER" >
      SELECT LAST_INSERT_ID()
    </selectKey>
    insert into hotel_order_category (category_type, category_name, allocate_time, 
      promise_time, last_operator, update_time, 
      is_cancel, status1, status2, 
      phone_list, create_time)
    values (#{categoryType,jdbcType=INTEGER}, #{categoryName,jdbcType=VARCHAR}, #{allocateTime,jdbcType=INTEGER}, 
      #{promiseTime,jdbcType=INTEGER}, #{lastOperator,jdbcType=VARCHAR}, #{updateTime,jdbcType=TIMESTAMP}, 
      <!--寫(xiě)在這里蛇数,僅對(duì)insert有效挪钓,注意,沒(méi)有雙引號(hào): typeHandler=com.sankuai.travel.csc.test.dao.typehandler.BooleanTypeHandler -->
      #{isCancel,jdbcType=CHAR,typeHandler=com.sankuai.travel.csc.test.dao.typehandler.BooleanTypeHandler},
      #{status1,jdbcType=CHAR}, #{status2,jdbcType=CHAR},
      #{phoneList,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP})
  </insert>

#mybatis-enumtypehandler和enumordinaltypehandler的區(qū)別

mybatis對(duì)枚舉類(lèi)型提供了兩種類(lèi)型支持:EnumTypeHandler和EnumOrdinalTypeHandler耳舅。

  • EnumTypeHandler是mybatis默認(rèn)的枚舉類(lèi)型轉(zhuǎn)換器碌上,如果pojo類(lèi)中使用了枚舉類(lèi)型,而配置文件沒(méi)有指定類(lèi)型轉(zhuǎn)換類(lèi),mybatis將使用EnumTypeHandler處理枚舉屬性馏予。EnumTypeHandler的將把枚舉類(lèi)的name進(jìn)行存儲(chǔ)天梧,枚舉類(lèi)的name即枚舉類(lèi)名。參考:http://mybatis.github.io/mybatis-3/zh/configuration.html
  • EnumOrdinalTypeHandler是mybatis提供的另一種轉(zhuǎn)換器吗蚌,顧名思義這個(gè)轉(zhuǎn)換類(lèi)使用了枚舉類(lèi)的ordinal屬性作為數(shù)據(jù)庫(kù)存儲(chǔ)信息腿倚,由于ordinal屬性是int類(lèi)型的,按照官網(wǎng)的說(shuō)明數(shù)據(jù)庫(kù)中對(duì)應(yīng)資源應(yīng)該是int或double類(lèi)型的蚯妇,但是個(gè)人測(cè)試過(guò)程中MYSQL的varchar字段也可以存儲(chǔ)敷燎。
  • 總結(jié):EnumTypeHandler和EnumOrdinalTypeHandler的區(qū)別主要是數(shù)據(jù)庫(kù)中存儲(chǔ)字段的類(lèi)型差別,由于EnumOrdinalTypeHandler使用枚舉類(lèi)型的ordinal作為存儲(chǔ)箩言,所以必須使用數(shù)字類(lèi)型字段存儲(chǔ)硬贯。
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="mapperLocations" value="classpath:dao/mapper/*.xml"></property>
        <property name="typeHandlers" >
            <array>
                <bean class="com.sankuai.travel.csc.test.dao.typehandler.BooleanTypeHandler" />
                <bean class="com.sankuai.travel.csc.test.dao.typehandler.StringArrayTypeHandler" />
  <!--不需要EnumTypeHandler,默認(rèn)包含 -->
                <bean class="org.apache.ibatis.type.EnumTypeHandler" >
                    <constructor-arg name="type" value="com.sankuai.travel.csc.test.enums.SimpleStatusEnum" />
                </bean>
<!--需要EnumOrdinalTypeHandler陨收,默認(rèn)包含 -->
                <bean class="org.apache.ibatis.type.EnumOrdinalTypeHandler" >
                    <constructor-arg name="type" value="com.sankuai.travel.csc.test.enums.SimpleStatusEnum" />
                </bean>
            </array>
        </property>
        <property name="plugins">
            <array>
                <bean class="com.sankuai.travel.csc.test.dao.interceptor.SqlMonitorInterceptor" />
            </array>
        </property>
    </bean>
<resultMap id="BaseResultMap" type="com.sankuai.travel.csc.test.dao.domain.CategoryDO" >
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="category_type" property="categoryType" jdbcType="INTEGER" />
    <result column="category_name" property="categoryName" jdbcType="VARCHAR" />
    <result column="allocate_time" property="allocateTime" jdbcType="INTEGER" />
    <result column="promise_time" property="promiseTime" jdbcType="INTEGER" />
    <result column="last_operator" property="lastOperator" jdbcType="VARCHAR" />
    <result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />

    <!--方式二:寫(xiě)在這里饭豹,僅對(duì)select語(yǔ)句有效,typeHandler="com.sankuai.travel.csc.test.dao.typehandler.BooleanTypeHandler" -->
    <result column="is_cancel" property="isCancel" jdbcType="CHAR" />
<!--EnumTypeHandler默認(rèn)處理類(lèi)务漩,不需要配置 -->
    <result column="status1" property="status1" jdbcType="CHAR" />
<!--EnumOrdinalTypeHandler需要單獨(dú)配置 -->
    <result column="status2" property="status2" jdbcType="CHAR" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler" />
    <result column="phone_list" property="phoneList" jdbcType="VARCHAR" />
    <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
  </resultMap>


參考文章

https://my.oschina.net/amoshuang/blog/134199
mybatis-enumtypehandler和enumordinaltypehandler的區(qū)別

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拄衰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子饵骨,更是在濱河造成了極大的恐慌翘悉,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件居触,死亡現(xiàn)場(chǎng)離奇詭異妖混,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)轮洋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)制市,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人弊予,你說(shuō)我怎么就攤上這事祥楣。” “怎么了块促?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵荣堰,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我竭翠,道長(zhǎng)振坚,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任斋扰,我火速辦了婚禮渡八,結(jié)果婚禮上啃洋,老公的妹妹穿的比我還像新娘。我一直安慰自己屎鳍,他們只是感情好宏娄,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著逮壁,像睡著了一般孵坚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上窥淆,一...
    開(kāi)封第一講書(shū)人閱讀 51,692評(píng)論 1 305
  • 那天卖宠,我揣著相機(jī)與錄音,去河邊找鬼忧饭。 笑死扛伍,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的词裤。 我是一名探鬼主播刺洒,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼吼砂!你這毒婦竟也來(lái)了逆航?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤渔肩,失蹤者是張志新(化名)和其女友劉穎纸泡,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體赖瞒,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年蚤假,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了栏饮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡磷仰,死狀恐怖袍嬉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情灶平,我是刑警寧澤伺通,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站逢享,受9級(jí)特大地震影響罐监,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瞒爬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一弓柱、第九天 我趴在偏房一處隱蔽的房頂上張望沟堡。 院中可真熱鬧,春花似錦矢空、人聲如沸航罗。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)粥血。三九已至,卻和暖如春酿箭,著一層夾襖步出監(jiān)牢的瞬間复亏,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工七问, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蜓耻,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓械巡,卻偏偏與公主長(zhǎng)得像刹淌,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子讥耗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容