Mybatis通过TypeHandler对于数据库存储字段查询进行自定义转换

本文介绍如何在MyBatis中使用自定义TypeHandler,实现List类型与数据库字段之间的转换。通过创建ListTypeHandler类,继承BaseTypeHandler并重写方法,可以将List<Integer>类型的数据转换为逗号分隔的字符串存储到数据库,同时能从数据库读取字符串并转换回List<Integer>类型。

Mybatis通过TypeHandler对于数据库存储字段查询进行自定义转换

使用:

自定义Handler继承BaseTypeHandler

代码如下:

@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes({List.class})
public class ListTypeHandler extends BaseTypeHandler<List<Integer>> {
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, List<Integer> integers, JdbcType jdbcType) throws SQLException {
    StringBuffer sb = new StringBuffer();
    for (int j = 0; j < integers.size(); j++) {
        sb.append(integers.get(j)).append(",");
    }
    preparedStatement.setString(i, sb.toString().substring(0, sb.toString().length() - 1));
}

@Override
public List<Integer> getNullableResult(ResultSet resultSet, String s) throws SQLException {
    return getResult(resultSet.getString(s));
}

@Override
public List<Integer> getNullableResult(ResultSet resultSet, int i) throws SQLException {
    return getResult(resultSet.getString(i));
}

@Override
public List<Integer> getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
    return null;
}

private List<Integer> getResult(String str) {
    List<Integer> result = new ArrayList<>();
    if (StringUtils.isNotBlank(str)) {
        String[] array = str.split(",");
        for (int i = 0; i < array.length; i++) {
            result.add(Integer.valueOf(array[i]));
        }
    }
    return result;
}

}

测试:

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyBatisTest {

@Autowired
private MerchantMapper merchantMapper;


@Test
public void testInsertHandler() {
    Merchant merchant = new Merchant();
    merchant.setId(1);
    merchant.setSname("test数据");
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    merchant.setSrange(list);
    merchantMapper.insert(merchant);
}

@Test
public void testSelectHandler() {
    Merchant merchant = merchantMapper.selectOne(1);
    System.out.println(merchant);
}

}

setNonNullParameter可以对于传入的参数转换成用逗号连接
getNullableResult可以将数据库中逗号连接的值转换成List类型

<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 有何区别?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值