当前位置:   article > 正文

Mybatis TypeHandler介绍使用举例

typehandler

目录

一、Mybatis工作原理简单回顾

(一)Mybatis框架分层

(二)原理分析

二、TypeHandler自定义转换类型介绍

(一)基本介绍

(二)注意事项和建议

三、业务使用基本分析展示

(一)自定义TypeHandler实现类

举例一:枚举类型的处理

举例二: LocalDateTime类型的处理

举例三: List 类型的处理

举例四: List 类型的处理

举例五:自定义TimePeriod 类型的处理

举例六: InetAddress 类型的处理

(二)在mapper.xml文件中进行反序列化配置

(三)在mapper.xml文件中进行序列化配置

(四)在mybatis的配置文件config.xml中配置typeHandlers


一、Mybatis工作原理简单回顾

(一)Mybatis框架分层

(二)原理分析

MyBatis 是一款优秀的持久层框架,它的核心原理包括以下几个方面:

  1. 配置文件解析:MyBatis 使用 XML 配置文件来描述数据库连接、SQL 映射关系、缓存等信息。在启动时,MyBatis 会解析配置文件,将配置信息加载到内存中,并构建相应的对象模型来表示这些配置。
  2. SqlSessionFactory:SqlSessionFactory 是 MyBatis 的核心接口,它是用于创建 SqlSession 的工厂。SqlSessionFactory 是基于配置文件构建的,通过读取配置文件中的信息,创建出 SqlSessionFactory 对象,以供后续的数据库操作使用。
  3. SqlSession:SqlSession 是 MyBatis 的核心接口之一,它提供了执行 SQL 语句、提交事务、关闭连接等数据库操作的方法。SqlSession 是基于 SqlSessionFactory 创建的,每个 SqlSession 对象都代表一个对数据库的会话,它提供了对数据库的各种操作方法。
  4. 映射器(Mapper)接口:在 MyBatis 中,我们可以使用接口来定义 SQL 映射关系,这些接口被称为映射器(Mapper)接口。映射器接口通过注解或 XML 配置与具体的 SQL 语句进行绑定,并提供了对数据库的操作方法。MyBatis 会为这些接口动态生成实现类,从而实现对数据库的访问。
  5. SQL 语句的解析与执行:MyBatis 通过解析映射文件或注解中的 SQL 语句,将其转换为对应的数据库操作。它支持动态 SQL,可以根据条件生成不同的 SQL 语句,从而实现更灵活的数据库操作。
  6. 参数处理:MyBatis 提供了对 SQL 语句中参数的处理支持。它可以根据参数的类型、注解或配置文件中的映射规则,将 Java 对象与 SQL 语句中的参数进行自动转换。
  7. 结果集映射:MyBatis 支持将查询结果映射为 Java 对象。通过配置文件或注解,可以定义查询结果与 Java 对象之间的映射关系,包括属性名、类型转换、关联关系等。MyBatis 使用反射机制将查询结果转换为对应的 Java 对象。
  8. 一级缓存和二级缓存:MyBatis 提供了缓存机制来提高数据库访问的性能。一级缓存是 SqlSession 级别的缓存,它缓存了查询的结果对象。二级缓存是全局级别的缓存,它可以被多个 SqlSession 共享,提供了跨会话的缓存功能。
  9. 事务管理:MyBatis 支持事务管理,可以通过配置文件或注解来指定事务的隔离级别、传播行为以及异常回滚规则。在进行数据库操作时,MyBatis 会根据配置的事务管理方式来开启、提交或回滚事务,确保数据的一致性和完整性。
  10. 插件机制:MyBatis 提供了插件机制,可以在 SQL 语句执行的前后进行拦截和扩展。开发者可以编写自定义的插件,并在配置文件中注册,从而对 SQL 的执行过程进行拦截和增强,实现自定义的功能扩展。

总的来说,MyBatis 的核心原理是基于配置文件和接口定义的,通过解析配置文件、创建工厂、会话管理和数据库操作等步骤来实现与数据库的交互。它提供了灵活的 SQL 映射、参数处理、结果集映射、缓存和事务管理等功能,让开发者能够方便地进行数据库操作。同时,MyBatis 还支持插件机制,提供了扩展性和定制化的能力,使得开发者能够根据具体需求进行功能的增强和定制。

二、TypeHandler自定义转换类型介绍

(一)基本介绍

在 Java 开发中,TypeHandler 是 MyBatis 框架中的一个核心组件,用于实现数据库与 Java 类型之间的相互转换。它允许开发人员自定义类型处理器,以满足特定的业务需求。

TypeHandler 的作用是在 MyBatis 执行 SQL 查询或更新操作时,将数据库中的列值转换为 Java 对象,并在将 Java 对象写入数据库时执行相反的转换。它提供了一种灵活且可扩展的方式,用于处理数据库类型与 Java 类型之间的映射关系。

以下是 TypeHandler 的一些关键特点和使用方式:

  1. 类型转换:TypeHandler 负责将数据库中的列值转换为 Java 对象,并将 Java 对象转换为数据库可接受的类型。
  2. 自定义类型处理器:MyBatis 提供了一些默认的类型处理器,例如处理整数、字符串、日期等常见类型。同时,开发人员可以根据需要自定义类型处理器,实现特定类型的转换逻辑
  3. 注册类型处理器:自定义的类型处理器需要在 MyBatis 的配置文件中进行注册,以便 MyBatis 在执行数据库操作时能够找到并使用它们。
  4. 支持复杂类型:TypeHandler 不仅可以处理基本类型,还可以处理复杂类型,例如枚举、自定义对象等。
  5. 映射规则:TypeHandler 的使用是基于映射规则的,即在 MyBatis 的映射文件中,通过指定列和属性之间的映射关系,TypeHandler 才能正确地进行类型转换。

(二)注意事项和建议

在 MyBatis 中使用自定义 TypeHandler 进行类型转换时,还有一些注意事项和建议:

  1. 数据库字段与 Java 对象属性类型的匹配:确保数据库字段的类型与 Java 对象属性的类型匹配。如果数据库字段的类型与自定义 TypeHandler 处理的 Java 对象类型不一致,可能会导致转换错误或数据丢失。
  2. 处理 NULL 值:在自定义 TypeHandler 中处理 NULL 值是很重要的。可以通过判断传入的参数或结果集中的值是否为 NULL,并在处理过程中进行相应的处理。例如,可以将 NULL 值转换为 Java 对象的默认值,或者通过特定的标识值来表示 NULL。
  3. 注册 TypeHandler:确保在 MyBatis 的配置文件中正确注册自定义的 TypeHandler。如果没有正确注册,MyBatis 将无法找到并使用该 TypeHandler,导致类型转换失败。
  4. 测试和验证:在使用自定义 TypeHandler 进行类型转换之前,建议进行充分的测试和验证。确保自定义 TypeHandler 能够正确地将数据库类型转换为相应的 Java 对象类型,并且在查询和更新操作中能够正常工作。
  5. 了解官方提供的默认 TypeHandler:MyBatis 提供了一些默认的 TypeHandler,用于常见的数据类型转换,如字符串、整数、日期等。在自定义 TypeHandler 之前,建议先查看官方文档,了解是否已经有现成的 TypeHandler 可以满足你的需求。
  6. 可重用性和扩展性:在设计自定义 TypeHandler 时,考虑其可重用性和扩展性。如果有多个字段需要进行相同的类型转换,可以将转换逻辑封装在一个通用的 TypeHandler 中,并在映射文件中多次引用它。另外,可以通过继承或组合的方式扩展已有的 TypeHandler,以满足不同的业务需求。
  7. 注意线程安全性:自定义 TypeHandler 应该是线程安全的,因为 MyBatis 在多线程环境下可能会同时使用同一个 TypeHandler 实例进行类型转换。确保在实现自定义 TypeHandler 时考虑线程安全性,并采取相应的线程安全措施,如使用线程局部变量或同步机制。

以上是关于使用自定义 TypeHandler 进行类型转换的注意事项和建议。根据具体的业务需求,可以根据以上的指导来创建适合自己的自定义 TypeHandler,并在 MyBatis 中应用它。但是如果害怕出错还是建议直接使用默认的来处理即可,相关不合理的可能就直接通过查询或插入时进行转换了。

三、业务使用基本分析展示

(一)自定义TypeHandler实现类

自定义TypeHandler实现类,通常有两种方式:实现TypeHandler接口;继承BaseTypeHandler类。以扩展BaseTypeHandler类为例,说明如何实现想要转换成的数据库对象的具体逻辑。

举例一:枚举类型的处理

假设我们有一个订单实体类 Order,其中包含一个 Status 枚举类型的状态字段,在数据库中,我们将状态字段存储为一个字符串类型的列,例如 status。

  1. package org.zyf.javabasic.mybatis;
  2. /**
  3. * @author yanfengzhang
  4. * @description 订单实体类 Order
  5. * 其中包含一个 Status 枚举类型
  6. * @date 2023/5/13 23:34
  7. */
  8. public enum Status {
  9. CREATED,
  10. PROCESSING,
  11. COMPLETED,
  12. CANCELLED
  13. }

我们可以使用自定义的 TypeHandler 来实现 Status 枚举类型与数据库列值之间的转换。以下是一个示例的 TypeHandler 实现:

  1. package org.zyf.javabasic.mybatis;
  2. import org.apache.ibatis.type.BaseTypeHandler;
  3. import org.apache.ibatis.type.JdbcType;
  4. import java.sql.CallableStatement;
  5. import java.sql.PreparedStatement;
  6. import java.sql.ResultSet;
  7. import java.sql.SQLException;
  8. /**
  9. * @author yanfengzhang
  10. * @description 自定义的 TypeHandler 来实现 Status 枚举类型与数据库列值之间的转换
  11. * @date 2023/5/13 23:36
  12. */
  13. public class StatusTypeHandler extends BaseTypeHandler<Status> {
  14. @Override
  15. public Status getNullableResult(ResultSet rs, String columnName) throws SQLException {
  16. // 从 ResultSet 中获取列值
  17. int data = rs.getInt(columnName);
  18. // 将列值转换为枚举对象
  19. return Status.getEnumById(data);
  20. }
  21. @Override
  22. public Status getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
  23. int data = rs.getInt(columnIndex);
  24. return Status.getEnumById(data);
  25. }
  26. @Override
  27. public Status getNullableResult(CallableStatement callableStatement, int columnIndex) throws SQLException {
  28. int data = callableStatement.getInt(columnIndex);
  29. return Status.getEnumById(data);
  30. }
  31. @Override
  32. public void setNonNullParameter(PreparedStatement preparedStatement, int i, Status status, JdbcType jdbcType) throws SQLException {
  33. // 将枚举值的code存储到数据库中
  34. preparedStatement.setInt(i, status.getCode());
  35. }
  36. }

在上述示例中,我们自定义了一个 TypeHandler 类 StatusTypeHandler,用于处理 Status 枚举类型与数据库列值之间的转换。我们需要继承 BaseTypeHandler 并重写相应的方法来实现转换逻辑。

举例二: LocalDateTime类型的处理

假设我们有一个订单实体类 Order,其中包含一个 LocalDateTime 类型的创建时间字段,在数据库中,我们将创建时间字段存储为一个 DATETIME 类型的列,例如 create_time。

我们可以使用自定义的 TypeHandler 来实现 LocalDateTime 类型与数据库列值之间的转换。以下是一个示例的 TypeHandler 实现:

  1. package org.zyf.javabasic.mybatis;
  2. import org.apache.ibatis.type.BaseTypeHandler;
  3. import org.apache.ibatis.type.JdbcType;
  4. import java.sql.CallableStatement;
  5. import java.sql.PreparedStatement;
  6. import java.sql.ResultSet;
  7. import java.sql.SQLException;
  8. import java.sql.Timestamp;
  9. import java.time.LocalDateTime;
  10. /**
  11. * @author yanfengzhang
  12. * @description 自定义的 TypeHandler 来实现 LocalDateTime 类型与数据库列值之间的转换
  13. * @date 2023/5/14 10:28
  14. */
  15. public class LocalDateTimeTypeHandler extends BaseTypeHandler<LocalDateTime> {
  16. @Override
  17. public void setNonNullParameter(PreparedStatement ps, int i, LocalDateTime parameter, JdbcType jdbcType) throws SQLException {
  18. // 将 LocalDateTime 转换为 Timestamp 并设置到 PreparedStatement 中
  19. ps.setTimestamp(i, Timestamp.valueOf(parameter));
  20. }
  21. @Override
  22. public LocalDateTime getNullableResult(ResultSet rs, String columnName) throws SQLException {
  23. // 从 ResultSet 中获取 Timestamp 值
  24. Timestamp timestamp = rs.getTimestamp(columnName);
  25. // 将 Timestamp 转换为 LocalDateTime
  26. return timestamp != null ? timestamp.toLocalDateTime() : null;
  27. }
  28. @Override
  29. public LocalDateTime getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
  30. Timestamp timestamp = rs.getTimestamp(columnIndex);
  31. return timestamp != null ? timestamp.toLocalDateTime() : null;
  32. }
  33. @Override
  34. public LocalDateTime getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
  35. Timestamp timestamp = cs.getTimestamp(columnIndex);
  36. return timestamp != null ? timestamp.toLocalDateTime() : null;
  37. }
  38. }

在上述示例中,我们自定义了一个 TypeHandler 类 LocalDateTimeTypeHandler,用于处理 LocalDateTime 类型与数据库列值之间的转换。我们需要继承 BaseTypeHandler 并重写相应的方法来实现转换逻辑。

现在,当使用 MyBatis 进行数据库查询时,会自动将数据库中的列值转换为对应的 LocalDateTime 对象,使我们能够方便地在 Java 代码中使用 LocalDateTime 类型。

举例三: List<String> 类型的处理

当处理 List 类型时,可以使用自定义的 TypeHandler 将 List 对象转换为字符串进行存储,或者从数据库中读取字符串并还原为 List 对象。

假设有一个订单实体类 Order,其中包含一个 List<String> 类型的商品列表字段(products),我们可以使用自定义的 TypeHandler 来实现 List<String> 类型与数据库列值之间的转换。以下是一个示例的 TypeHandler 实现:

  1. package org.zyf.javabasic.mybatis;
  2. import org.apache.ibatis.type.BaseTypeHandler;
  3. import org.apache.ibatis.type.JdbcType;
  4. import java.sql.CallableStatement;
  5. import java.sql.PreparedStatement;
  6. import java.sql.ResultSet;
  7. import java.sql.SQLException;
  8. import java.util.Arrays;
  9. import java.util.Collections;
  10. import java.util.List;
  11. /**
  12. * @author yanfengzhang
  13. * @description 自定义的 TypeHandler 来实现 List<String> 类型与数据库列值之间的转换
  14. * @date 2023/5/14 10:39
  15. */
  16. public class StringListTypeHandler extends BaseTypeHandler<List<String>> {
  17. private static final String DELIMITER = ",";
  18. @Override
  19. public void setNonNullParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType) throws SQLException {
  20. // 将 List<String> 转换为以逗号分隔的字符串
  21. String rolesString = String.join(DELIMITER, parameter);
  22. // 将字符串存储到数据库中
  23. ps.setString(i, rolesString);
  24. }
  25. @Override
  26. public List<String> getNullableResult(ResultSet rs, String columnName) throws SQLException {
  27. // 从 ResultSet 中获取字符串值
  28. String rolesString = rs.getString(columnName);
  29. // 将字符串转换为 List<String>
  30. return parseRolesString(rolesString);
  31. }
  32. @Override
  33. public List<String> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
  34. String rolesString = rs.getString(columnIndex);
  35. return parseRolesString(rolesString);
  36. }
  37. @Override
  38. public List<String> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
  39. String rolesString = cs.getString(columnIndex);
  40. return parseRolesString(rolesString);
  41. }
  42. private List<String> parseRolesString(String rolesString) {
  43. if (rolesString == null || rolesString.isEmpty()) {
  44. return Collections.emptyList();
  45. }
  46. // 将字符串按逗号分隔转换为 List<String>
  47. return Arrays.asList(rolesString.split(DELIMITER));
  48. }
  49. }

在上述示例中,我们自定义了一个 TypeHandler 类 StringListTypeHandler,用于处理 List<String> 类型与数据库列值之间的转换。我们需要继承 BaseTypeHandler 并重写相应的方法来实现转换逻辑。现在,当使用 MyBatis 进行数据库查询时,会自动将数据库中的列值转换为对应的 List<String> 对象,使我们能够方便地在 Java 代码中使用 List<String> 类型。

举例四: List<Long> 类型的处理

同样的,可以自定义 TypeHandler 中将 VARCHAR 类型的数据库列与 List<Long> 类型的 Java 对象进行转换

  1. package org.zyf.javabasic.mybatis;
  2. import org.apache.ibatis.type.BaseTypeHandler;
  3. import org.apache.ibatis.type.JdbcType;
  4. import java.sql.CallableStatement;
  5. import java.sql.PreparedStatement;
  6. import java.sql.ResultSet;
  7. import java.sql.SQLException;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10. import java.util.stream.Collectors;
  11. /**
  12. * @author yanfengzhang
  13. * @description 自定义 TypeHandler 中将 VARCHAR 类型的数据库列与 List<Long> 类型的 Java 对象进行转换
  14. * @date 2023/5/14 10:48
  15. */
  16. public class LongListTypeHandler extends BaseTypeHandler<List<Long>> {
  17. private static final String DELIMITER = ",";
  18. @Override
  19. public void setNonNullParameter(PreparedStatement ps, int i, List<Long> parameter, JdbcType jdbcType) throws SQLException {
  20. String joinedString = parameter.stream().map(String::valueOf).collect(Collectors.joining(DELIMITER));
  21. ps.setString(i, joinedString);
  22. }
  23. @Override
  24. public List<Long> getNullableResult(ResultSet rs, String columnName) throws SQLException {
  25. String columnValue = rs.getString(columnName);
  26. return convertStringToList(columnValue);
  27. }
  28. @Override
  29. public List<Long> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
  30. String columnValue = rs.getString(columnIndex);
  31. return convertStringToList(columnValue);
  32. }
  33. @Override
  34. public List<Long> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
  35. String columnValue = cs.getString(columnIndex);
  36. return convertStringToList(columnValue);
  37. }
  38. private List<Long> convertStringToList(String columnValue) {
  39. if (columnValue == null || columnValue.isEmpty()) {
  40. return null;
  41. }
  42. List<Long> resultList = new ArrayList<>();
  43. String[] values = columnValue.split(DELIMITER);
  44. for (String value : values) {
  45. resultList.add(Long.valueOf(value));
  46. }
  47. return resultList;
  48. }
  49. }

举例五:自定义TimePeriod 类型的处理

同样的,可以自定义 TypeHandler 中将数据库中的时间段(以秒为单位)与 Java 对象中的 TimePeriod 类型进行转换。

首先,定义 TimePeriod 类表示时间段:

  1. package org.zyf.javabasic.mybatis;
  2. import lombok.Data;
  3. import java.time.LocalDateTime;
  4. /**
  5. * @author yanfengzhang
  6. * @description
  7. * @date 2023/5/14 10:58
  8. */
  9. @Data
  10. public class TimePeriod {
  11. private LocalDateTime startTime;
  12. private LocalDateTime endTime;
  13. public TimePeriod(LocalDateTime startTime, LocalDateTime endTime) {
  14. this.startTime = startTime;
  15. this.endTime = endTime;
  16. }
  17. }

然后,定义 TimePeriodTypeHandler 类实现 TypeHandler 接口来处理 TimePeriod 类型的转换:

  1. package org.zyf.javabasic.mybatis;
  2. import org.apache.ibatis.type.JdbcType;
  3. import org.apache.ibatis.type.TypeHandler;
  4. import java.sql.CallableStatement;
  5. import java.sql.PreparedStatement;
  6. import java.sql.ResultSet;
  7. import java.sql.SQLException;
  8. import java.sql.Timestamp;
  9. import java.sql.Types;
  10. import java.time.LocalDateTime;
  11. /**
  12. * @author yanfengzhang
  13. * @description 自定义 TypeHandler 中将数据库中的时间段(以秒为单位)与 Java 对象中的 TimePeriod 类型进行转换
  14. * @date 2023/5/14 10:52
  15. */
  16. public class TimePeriodTypeHandler implements TypeHandler<TimePeriod> {
  17. @Override
  18. public void setParameter(PreparedStatement ps, int i, TimePeriod parameter, JdbcType jdbcType) throws SQLException {
  19. // 将 Java 对象转换为数据库类型,并设置到 PreparedStatement 中的指定参数位置
  20. if (parameter != null) {
  21. ps.setTimestamp(i, Timestamp.valueOf(parameter.getStartTime()));
  22. ps.setTimestamp(i + 1, Timestamp.valueOf(parameter.getEndTime()));
  23. } else {
  24. ps.setNull(i, Types.TIMESTAMP);
  25. ps.setNull(i + 1, Types.TIMESTAMP);
  26. }
  27. }
  28. @Override
  29. public TimePeriod getResult(ResultSet rs, String columnName) throws SQLException {
  30. // 从 ResultSet 中获取指定列名的数据库值,并将其转换为对应的 Java 对象
  31. LocalDateTime startTime = rs.getTimestamp(columnName).toLocalDateTime();
  32. LocalDateTime endTime = rs.getTimestamp(columnName + "_end").toLocalDateTime();
  33. return new TimePeriod(startTime, endTime);
  34. }
  35. @Override
  36. public TimePeriod getResult(ResultSet rs, int columnIndex) throws SQLException {
  37. // 从 ResultSet 中获取指定列索引的数据库值,并将其转换为对应的 Java 对象
  38. LocalDateTime startTime = rs.getTimestamp(columnIndex).toLocalDateTime();
  39. LocalDateTime endTime = rs.getTimestamp(columnIndex + 1).toLocalDateTime();
  40. return new TimePeriod(startTime, endTime);
  41. }
  42. @Override
  43. public TimePeriod getResult(CallableStatement cs, int columnIndex) throws SQLException {
  44. // 从 CallableStatement 中获取指定列索引的数据库值,并将其转换为对应的 Java 对象
  45. LocalDateTime startTime = cs.getTimestamp(columnIndex).toLocalDateTime();
  46. LocalDateTime endTime = cs.getTimestamp(columnIndex + 1).toLocalDateTime();
  47. return new TimePeriod(startTime, endTime);
  48. }
  49. }

举例六: InetAddress 类型的处理

假设我们有一个订单实体类 Order,其中包含一个 InetAddress 类型的 IP 地址字段,在数据库中,我们将 IP 地址存储为一个字符串类型的列,例如 ip_address。

我们可以使用自定义的 TypeHandler 来实现 InetAddress 类型与数据库列值之间的转换。以下是一个示例的 TypeHandler 实现:

  1. package org.zyf.javabasic.mybatis;
  2. import org.apache.ibatis.type.BaseTypeHandler;
  3. import org.apache.ibatis.type.JdbcType;
  4. import java.net.InetAddress;
  5. import java.net.UnknownHostException;
  6. import java.sql.CallableStatement;
  7. import java.sql.PreparedStatement;
  8. import java.sql.ResultSet;
  9. import java.sql.SQLException;
  10. /**
  11. * @author yanfengzhang
  12. * @description 用于处理 InetAddress 类型与数据库列值之间的转换
  13. * @date 2023/5/14 11:20
  14. */
  15. public class InetAddressTypeHandler extends BaseTypeHandler<InetAddress> {
  16. @Override
  17. public void setNonNullParameter(PreparedStatement ps, int i, InetAddress parameter, JdbcType jdbcType) throws SQLException {
  18. // 获取 IP 地址的字符串表示
  19. String ipAddressString = parameter.getHostAddress();
  20. // 将字符串存储到数据库中
  21. ps.setString(i, ipAddressString);
  22. }
  23. @Override
  24. public InetAddress getNullableResult(ResultSet rs, String columnName) throws SQLException {
  25. // 从 ResultSet 中获取字符串值
  26. String ipAddressString = rs.getString(columnName);
  27. // 将字符串转换为 InetAddress
  28. return parseIpAddressString(ipAddressString);
  29. }
  30. @Override
  31. public InetAddress getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
  32. String ipAddressString = rs.getString(columnIndex);
  33. return parseIpAddressString(ipAddressString);
  34. }
  35. @Override
  36. public InetAddress getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
  37. String ipAddressString = cs.getString(columnIndex);
  38. return parseIpAddressString(ipAddressString);
  39. }
  40. private InetAddress parseIpAddressString(String ipAddressString) {
  41. try {
  42. // 将字符串解析为 InetAddress
  43. return InetAddress.getByName(ipAddressString);
  44. } catch (UnknownHostException e) {
  45. // 处理解析错误,例如返回默认的 IP 地址或抛出异常
  46. return null;
  47. }
  48. }
  49. }

(二)在mapper.xml文件中进行反序列化配置

该写法只对返回此resultMap的查询语句有效

  1. <resultMap id="BaseResultMap" type="org.zyf.javabasic.mybatis.domain.Order">
  2. <id column="id" jdbcType="BIGINT" property="id"/>
  3. <result column="name" jdbcType="VARCHAR" property="name"/>
  4. <result column="status" jdbcType="INTEGER" property="status"
  5. typeHandler="org.zyf.javabasic.mybatis.StatusTypeHandler" />
  6. <result column="limit_period" jdbcType="VARCHAR" property="limitPeriod"
  7. typeHandler="org.zyf.javabasic.mybatis.TimePeriodHandler"/>
  8. <result column="create_time" jdbcType="DATETIME" property="createTime"
  9. typeHandler="org.zyf.javabasic.mybatis.LocalDateTimeTypeHandler"/>
  10. <result column="sku_ids" jdbcType="VARCHAR" property="skuIds"
  11. typeHandler="org.zyf.javabasic.mybatis.LongListTypeHandler"/>/>
  12. <result column="products" jdbcType="VARCHAR" property="products"
  13. typeHandler="org.zyf.javabasic.mybatis.StringListTypeHandler"/>
  14. <result column="ip_address" jdbcType="VARCHAR" property="ipAddress"
  15. typeHandler="org.zyf.javabasic.mybatis.InetAddress"/>
  16. <result column="cname" jdbcType="VARCHAR" property="cname"/>
  17. <result column="uname" jdbcType="VARCHAR" property="uname"/>
  18. </resultMap>

(三)在mapper.xml文件中进行序列化配置

如果希望在写入数据库的时候,按照指定规则对写入对象进行序列化,则需要在写入sql语句处显式指定typeHandler

  1. <update id="update" parameterType="map" >
  2. UPDATE
  3. <include refid="Table_Name"/>
  4. SET
  5. name = #{order.name},
  6. limit_period = #{order.limitPeriod, typeHandler=org.zyf.javabasic.mybatis.TimePeriodHandlerer},
  7. sku_ids =#{order.skuIds, typeHandler=org.zyf.javabasic.mybatis.LongListTypeHandler},
  8. uname = #{order.uname},
  9. utime = unix_timestamp()
  10. where id = #{order.id}
  11. </update>

(四)在mybatis的配置文件config.xml中配置typeHandlers

方法一:启动时会扫描包下的所有文件

  1. <typeHandlers>
  2. <package name="org.zyf.javabasic.mybatis"/>
  3. </typeHandlers>

方法二:或单个写入要注册的TypeHandler

  1. <typeHandlers>
  2. <typeHandler handler="org.zyf.javabasic.mybatis.TimePeriodHandler"
  3. javaType="org.zyf.javabasic.mybatis.TimePeriod"
  4. jdbcType="VARCHAR"/>
  5. <typeHandler handler="org.zyf.javabasic.mybatis.LongListHandler"
  6. javaType="java.util.List"
  7. jdbcType="VARCHAR"/>
  8. </typeHandlers>

参考文章链接

  1. Mybatis之工作原理_mybatis 的原理_Javxuan的博客-CSDN博客
  2. MyBatis 官方文档 - TypeHandlers:MyBatis 官方文档中关于 TypeHandler 的详细说明和使用示例。
  3. MyBatis TypeHandler 使用详解:一篇博客文章介绍了如何使用 MyBatis 中的 TypeHandler,并提供了详细的示例和说明。
  4. MyBatis TypeHandler 的自定义与应用:该文章介绍了如何自定义 TypeHandler,并通过示例演示了各种类型转换的场景。
  5. MyBatis 之 TypeHandler 实现原理:一篇知乎专栏文章,深入解析了 MyBatis 中的 TypeHandler 实现原理和相关的核心类。
  6. MyBatis 之 TypeHandler 源码解析:该文章通过分析 MyBatis 中的 TypeHandler 源码,解释了其内部工作原理和实现细节。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/683357
推荐阅读
相关标签
  

闽ICP备14008679号