mybatis自定义类型转换(typeHandler)

本文介绍如何使用MyBatis自定义类型处理器实现Java布尔类型与数据库Char类型的自动转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


设有这样一个需求
有一个布尔型的字段需要保存到数据库中,但是数据库不支持布尔类型,因此采用一位字符(char(1))来存储这个布尔值,javabean中仍然采用boolean类型。
我们采用mybatis作为持久层框架,但是就有一个问题,数据库中使char型,而程序中是boolean型,如何实现数据类型自动转换?
解决办法
mybatis提供了对自定义的类型转换器(typeHandler)的支持,因此我们可以自己编写类型转换器来实现这一自动转换的功能。
实现步骤

第一步:编写自定义类型转换器

<strong><font class="Apple-style-span" color="#696969">package com.hotent.base.db.mybatis.handler;

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.TypeHandler;  

/** 
 * @author  
 * java中的boolean和jdbc中的char之间转换;true-Y;false-N 
 */  
public class BooleanTypeHandler  implements TypeHandler<Object>{
        /* (non-Javadoc) 
     * @see org.apache.ibatis.type.TypeHandler#getResult(java.sql.ResultSet, java.lang.String) 
     */  
    @Override  
    public Object getResult(ResultSet arg0, String arg1) throws SQLException {  
        String str = arg0.getString(arg1);  
        Boolean rt = Boolean.FALSE;  
        if (str.equalsIgnoreCase("Y")){  
            rt = Boolean.TRUE;  
        }  
        return rt;   
    }  
    @Override
        public Object getResult(ResultSet arg0, int arg1) throws SQLException {
                // TODO Auto-generated method stub
             Boolean b = arg0.getBoolean(arg1); 
                return b == true ? "Y" : "N";
        }  
    
    /* (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);  
    }
}</font></strong>

第二步:注册类型转换器
在mybatis的配置文件中添加typeHandlers节点,在配置该节点时最好按照官方文档提供的节点顺序添加,否则可能会出现以下错误信息:

The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,plugins?,environments?,mappers?)". 

官方文档的配置文件节点顺序为:properties,setting,typeAliases,typeHandles,objectFactory,plugins,environments,mappins
以下为xml代码:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-config.dtd">
<configuration>
         
        <properties resource="conf/x5-base-db.properties"/>
        
        <settings >
                <setting name="cacheEnabled" value="false"/>
        </settings> 
        <typeHandlers>
                <typeHandler javaType="Boolean" jdbcType="CHAR"   handler="com.hotent.base.db.mybatis.handler.BooleanTypeHandler" />  
    </typeHandlers> 
        <plugins>
                <plugin interceptor="com.hotent.base.db.mybatis.OffsetLimitInterceptor">
                        <property name="dbType" value="${jdbc.dbType}"/>
                        <property name="Dialect.oracle" value="com.hotent.base.db.mybatis.dialect.OracleDialect"/>
                        <property name="Dialect.mssql" value="com.hotent.base.db.mybatis.dialect.SQLServer2005Dialect"/>
                        <property name="Dialect.mysql" value="com.hotent.base.db.mybatis.dialect.MySQLDialect"/>
                        <property name="Dialect.db2" value="com.hotent.base.db.mybatis.dialect.DB2Dialect"/>
                        <property name="Dialect.h2" value="com.hotent.base.db.mybatis.dialect.H2Dialect"/>
                        
                </plugin>
        </plugins>
         
</configuration>

第三步: 指定类型转换isFolder字段为例,下面贴出其mapping代码

<?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="com.hotent.platform.system.model.Resources">
        <resultMap id="Resources" type="com.hotent.platform.system.model.Resources">
                <id property="id" column="ID_" jdbcType="VARCHAR"/>
                <result property="name" column="NAME_" jdbcType="VARCHAR"/>
                <result property="alias" column="ALIAS" jdbcType="VARCHAR"/>
                <result property="sn" column="SN_" jdbcType="VARCHAR"/>
                <result property="icon" column="ICON_" jdbcType="VARCHAR"/>
                <result property="parentId" column="PARENT_ID_" jdbcType="VARCHAR"/>
                <result property="defaultUrl" column="DEFAULT_URL_" jdbcType="VARCHAR"/>
                <result property="isFolder" column="IS_FOLDER_" jdbcType="CHAR"/>
                <result property="displayInMenu" column="DISPLAY_IN_MENU_" jdbcType="VARCHAR"/>
                <result property="isOpen" column="IS_OPEN_" jdbcType="VARCHAR"/>
                <result property="systemId" column="SYSTEM_ID_" jdbcType="VARCHAR"/>
                <result property="path" column="PATH_" jdbcType="VARCHAR"/>
        </resultMap>

        <insert id="create" parameterType="com.hotent.platform.system.model.Resources">
                INSERT INTO sys_res_resources
                (ID_,NAME_,ALIAS,SN_,ICON_,PARENT_ID_,DEFAULT_URL_,IS_FOLDER_,DISPLAY_IN_MENU_,IS_OPEN_,SYSTEM_ID_,PATH_)
                VALUES 
                (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{alias,jdbcType=VARCHAR}, #{sn,jdbcType=VARCHAR}, #{icon,jdbcType=VARCHAR}, #{parentId,jdbcType=VARCHAR}, #{defaultUrl,jdbcType=VARCHAR}, #{isFolder,jdbcType=CHAR,javaType=Boolean}, #{displayInMenu,jdbcType=VARCHAR}, #{isOpen,jdbcType=VARCHAR}, #{systemId,jdbcType=VARCHAR}, #{path,jdbcType=VARCHAR})
        </insert>

        <update id="update" parameterType="com.hotent.platform.system.model.Resources">
                UPDATE sys_res_resources SET
                NAME_=#{name,jdbcType=VARCHAR},
                ALIAS=#{alias,jdbcType=VARCHAR},
                SN_=#{sn,jdbcType=VARCHAR},
                ICON_=#{icon,jdbcType=VARCHAR},
                PARENT_ID_=#{parentId,jdbcType=VARCHAR},
                DEFAULT_URL_=#{defaultUrl,jdbcType=VARCHAR},
                IS_FOLDER_=#{isFolder, jdbcType=CHAR,javaType=Boolean},
                DISPLAY_IN_MENU_=#{displayInMenu,jdbcType=VARCHAR},
                IS_OPEN_=#{isOpen,jdbcType=VARCHAR},
                SYSTEM_ID_=#{systemId,jdbcType=VARCHAR},
                PATH_=#{path,jdbcType=VARCHAR}
                WHERE
                ID_=#{id}
        </update>

        </mapper>
这样mybatis就能将数据库中的类型与java中的类型自动做转换了。其他类型转方法同上





<think>首先,用户的问题是关于MyBatisTypeHandler的使用,具体是查询结果转换的实现方法。用户意图是查找如何在MyBatis中使用TypeHandler转换查询结果。 从系统指令中,我需要: - 所有行内数学表达式用$...$格式。 - 独立公式用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾添加引用标识,如[^1]。 - 回答结构清晰,逐步解决问题。 - 参考提供的引用内容。 提供的引用内容: - [^1]: TypeHandler类型处理器是MyBatis/MyBatisPlus很重要的一部分内容,用于数据表和JavaBean之间的转换。 - [^2]: 在Spring项目中配置TypeHandler的示例,包括声明bean和注入到SqlSessionFactory。 - [^3]: TypeHandler接口的定义,包括setParameter和getResult方法。 用户的问题:"请问MyBatis 查询结果通过 TypeHandler 转换的实现方法",意思是"How to implement the conversion of query results through TypeHandler in MyBatis?"。 我的回答需要结构清晰,逐步解释实现方法。 大纲回答结构: 1. **介绍TypeHandler**:简要解释TypeHandler的作用,引用[^1]。 2. **实现步骤**: - 创建自定义TypeHandler类。 - 实现TypeHandler接口或继承BaseTypeHandler。 - 重写方法,特别是getResult方法用于查询结果转换。 - 配置TypeHandlerMyBatis中。 3. **示例代码**:提供一个简单的示例,展示如何实现一个TypeHandler转换查询结果。 4. **配置方法**:解释如何在MyBatis或Spring中配置TypeHandler,引用[^2]。 5. **总结**:简要回顾关键点。 6. **生成相关问题**:基于主题生成相关问题。 确保使用中文回答。 生成相关问题: - 类似于系统指令中的示例,生成2-3个相关问题。 - 例如:如何配置TypeHandlerTypeHandler的其他应用?常见问题等。 引用标识:在引用段落末尾添加[^1]、[^2]等。 由于引用内容有限,我会基于我的知识补充,但尽量使用提供的引用。 最终回答格式: - 标题或开头明确。 - 分步骤解释。 - 代码块用```包裹。 - 结束添加相关问题。</think>### MyBatis 查询结果通过 TypeHandler 转换的实现方法 在 MyBatis 中,TypeHandler 是用于处理 Java 类型与 JDBC 类型之间转换的核心组件。当执行查询操作TypeHandler 的 `getResult` 方法负责将数据库返回的结果集(如 `ResultSet`)转换为 Java 对象。这在处理自定义类型(如枚举、日期格式或复杂对象)特别有用。以下是实现查询结果转换的逐步方法,基于 MyBatisTypeHandler 机制。实现过程主要涉及创建自定义 TypeHandler、重写关键方法,并在 MyBatis 中注册配置[^1]。 #### 步骤 1: 创建自定义 TypeHandler 类 首先,定义一个类实现 `TypeHandler<T>` 接口或继承 `BaseTypeHandler<T>` 类(推荐后者,因为它提供了默认实现)。这里,`T` 是您要转换的目标 Java 类型。例如,假设我们需要将数据库中的字符串(如 "ENABLED" 或 "DISABLED") 转换为 Java 枚举 `Status`。 ```java import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class StatusTypeHandler extends BaseTypeHandler<Status> { // 重写 getResult 方法,处理查询结果的转换 @Override public Status getResult(ResultSet rs, String columnName) throws SQLException { String value = rs.getString(columnName); // 从结果集获取列值 return convertToStatus(value); // 调用自定义转换逻辑 } @Override public Status getResult(ResultSet rs, int columnIndex) throws SQLException { String value = rs.getString(columnIndex); return convertToStatus(value); } @Override public Status getResult(CallableStatement cs, int columnIndex) throws SQLException { String value = cs.getString(columnIndex); return convertToStatus(value); } // 自定义转换逻辑:将字符串映射到枚举 private Status convertToStatus(String value) { if ("ENABLED".equalsIgnoreCase(value)) { return Status.ENABLED; } else if ("DISABLED".equalsIgnoreCase(value)) { return Status.DISABLED; } return Status.UNKNOWN; // 默认值 } // setParameter 方法用于写入操作,此处可忽略或实现 @Override public void setParameter(PreparedStatement ps, int i, Status parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter.name()); // 示例:将枚举转为字符串存储 } } // 定义枚举类 public enum Status { ENABLED, DISABLED, UNKNOWN } ``` 关键点: - `getResult` 方法有三个重载版本,分别处理不同来源的结果集(列名、列索引或存储过程)。在查询MyBatis自动调用这些方法将 JDBC 类型转换为 Java 类型。 - `convertToStatus` 是自定义逻辑,用于映射数据库值到 Java 对象[^3]。 #### 步骤 2: 配置 TypeHandlerMyBatis TypeHandler 需要在 MyBatis 配置中注册,才能生效。配置方式取决于项目环境(纯 MyBatis 或 Spring 集成)。 - **纯 MyBatis 配置(XML 方式)**:在 `mybatis-config.xml` 文件中添加 TypeHandler。 ```xml <configuration> <typeHandlers> <typeHandler handler="com.example.StatusTypeHandler" javaType="com.example.Status" jdbcType="VARCHAR"/> </typeHandlers> </configuration> ``` 这里,`javaType` 指定目标 Java 类型,`jdbcType` 指定数据库类型(如 VARCHAR)。 - **Spring 项目配置(引用自 [^2])**:在 Spring 的 XML 配置中声明 TypeHandler bean 并注入到 `SqlSessionFactory`。 ```xml <!-- 声明 TypeHandler bean --> <bean id="statusTypeHandler" class="com.example.StatusTypeHandler"/> <!-- 配置 SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- 注入 TypeHandler --> <property name="typeHandlers" ref="statusTypeHandler"/> </bean> ``` #### 步骤 3: 在 Mapper 中使用 TypeHandler查询语句中,无需额外代码,MyBatis自动应用已注册的 TypeHandler。例如,在 Mapper XML 文件中: ```xml <select id="selectUser" resultType="com.example.User"> SELECT id, name, status FROM users WHERE id = #{id} </select> ``` 如果 `User` 类有一个 `status` 字段(类型为 `Status` 枚举),MyBatis 会使用 `StatusTypeHandler` 将数据库中的字符串转换为 `Status` 对象。 #### 注意事项 - **性能考虑**:TypeHandler转换逻辑应保持简单高效,避免复杂计算,以免影响查询性能。 - **错误处理**:在 `getResult` 方法中添加异常处理(如无效值),确保健壮性。 - **测试验证**:编写单元测试,模拟 `ResultSet` 验证转换逻辑是否正确。 通过以上步骤,您可以实现 MyBatis 查询结果的自动转换TypeHandler 简化了数据映射,特别适合处理自定义类型或格式转换需求[^1][^3]。 ### 相关问题 1. 如何在 MyBatis 中处理日期类型的自定义转换? 2. TypeHandler 在插入数据如何工作? 3. MyBatisPlus 的 TypeHandler 与原生 MyBatis 有何区别?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值