MyBatis 类型转换器
一 概述
MyBatis类型转换器是用于在Java类型和JDBC类型之间进行转换的工具。它可以将Java对象转换为JDBC可用的对象,也可以将JDBC对象转换为Java对象。Java类型是指在Java编程语言中定义的数据类型,如String、Integer、Date等。JDBC类型是指在关系型数据库中定义的数据类型,如VARCHAR、INTEGER、DATE等。
在MyBatis中,类型转换器是通过实现TypeHandler接口来完成的。它有两个主要方法:setNonNullParameter
和getNullableResult
。setNonNullParameter
方法用于将Java对象转换为JDBC可用的对象,并将其设置为PreparedStatement对象的参数。getNullableResult
方法用于从ResultSet对象中获取JDBC对象并将其转换为Java对象。 MyBatis默认提供了许多类型转换器,如StringTypeHandler、IntegerTypeHandler、DateTypeHandler等。如果需要自定义类型转换器,可以通过实现TypeHandler接口并在MyBatis配置文件中进行配置来实现。
为什么要用它,举一些可能出现的应用场景:
- 在数据库中采用varchar、text等字符串类型存储一个整形id集合,id间采用“,”分隔符分割,但在Java(MyBatis)实体中我们希望使用List ids来映射数据库中的字段;
- 做GIS开发的,PostGIS库中的geometry几何字段,但在Java(MyBatis)实体中我们希望使用GeoTools的Java几何类型来映射PostGIS数据库中的几何字段,此类实现参考我的另一篇文章 《使用MyBatis类型转换器将PostGIS中的几何字段转为PostGIS/GeoTools的几何Java对象》;
- …
二 MyBatis预设的一些TypeHandler
TypeHandler | JdbcType | JavaType |
---|---|---|
ArrayTypeHandler | ARRAY | Array |
BigDecimalTypeHandler | NUMERIC | BigDecimal, BigInteger |
BigIntegerTypeHandler | NUMERIC | BigInteger |
BlobTypeHandler | BLOB | Blob, byte[] |
BooleanTypeHandler | BIT | Boolean, boolean |
ByteTypeHandler | TINYINT | Byte, byte |
ByteObjectArrayTypeHandler | ARRAY | Byte[] |
ByteObjectTypeHandler | TINYINT | Byte |
CharacterTypeHandler | CHAR | Character, char |
ClobTypeHandler | CLOB | Clob, String |
DateOnlyTypeHandler | DATE | Date |
DateTypeHandler | TIMESTAMP | Date, java.sql.Date |
DoubleTypeHandler | DOUBLE | Double, double |
EnumOrdinalTypeHandler | INTEGER | Enum |
EnumTypeHandler | VARCHAR | Enum |
FloatTypeHandler | REAL | Float, float |
IntegerTypeHandler | INTEGER | Integer, int |
JdbcTypeHandler | OTHER | Object |
LocalDateTypeHandler | DATE | java.time.LocalDate |
LocalDateTimeTypeHandler | TIMESTAMP | java.time.LocalDateTime |
LongTypeHandler | BIGINT | Long, long |
ShortTypeHandler | SMALLINT | Short, short |
SqlTimeTypeHandler | TIME | java.sql.Time |
StringTypeHandler | VARCHAR | String |
TimeOnlyTypeHandler | TIME | java.sql.Time |
TimestampTypeHandler | TIMESTAMP | Timestamp |
三 使用步骤
- 确认数据库中字段存储的JDBC类型和你希望实体中使用的Java类型;
- 自定义类型转换器类,实现TypeHandler接口,在获取值、插入值的方法中进行类型转换的代码实现;
- 字段类型转换配置,MyBatis和MyBatisPlus的配置有所不同,后者做出的更进一步的简化(基于注解);
1 字段类型转换配置 MyBatisPlus(推荐)
MyBatisPlus对类型转换器的配置就变得更加便捷直观,首先在SpringBoot项目配置文件中MyBatisPlus节点中配置typeHandler的包目录,然后在对应实体的@TableField
注解中指定类型转换时使用的自定义类型转换器的类即可。
/**
* 班级包含的学生id列表
*/
@TableField(value = "student_ids", typeHandler = IntegerListTypeHandler.class)
private List<Integer> studentIds;
# mybatis-plus配置
mybatis-plus:
# 类型转换器,指定到包
type-handlers-package: com.xxx.entity.typeHandler
2 字段类型转换配置 MyBatis
(1)方式1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oxKMle2b-1684395901532)(https://cdn.nlark.com/yuque/0/2023/png/2968237/1684395089390-ad9464c5-75d7-4575-b99c-f9cb45c85ee7.png#averageHue=%2382754d&clientId=u24cbbbc3-cba1-4&from=paste&height=174&id=uec303ada&originHeight=174&originWidth=1050&originalType=binary&ratio=1&rotation=0&showTitle=false&size=26556&status=done&style=none&taskId=u25464c40-9559-44b8-a642-8b9f624e676&title=&width=1050)]
在对应实体的mapper.xml文件的resultMap节点下,对要进行转换处理的result节点中指定jdbcType、javaType和typeHandler即可。
- jdbcType:关系型数据库中定义的数据类型
- javaType:要转换的Java类型
- typeHandler:自定义的类型转换器
(2)方式2
在自定义类型转换器上添加映射类型与映射Jdbc类型注解
@MappedTypes({List.class})
@MappedJdbcTypes({JdbcType.VARCHAR})
public class IntegerListTypeHandler extends BaseTypeHandler<List<Integer>> {
...
}
在mybatis配置文件中添加如下配置:
<typeHandlers>
<typeHandler handler="com.test.model.entity.IntegerListTypeHandler"/>
</typeHandlers>
四 自定义类型转换器示例
在数据库中采用varchar、text等字符串类型存储一个整形id集合,id间采用“,”分隔符分割,但在Java(MyBatis)实体中我们希望使用List ids来映射数据库中的字段。
public class IntegerListTypeHandler extends BaseTypeHandler<List<Integer>> {
public static final String IdSplitter = ",";
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<Integer> parameter, JdbcType jdbcType) throws SQLException {
// 将List<Integer>类型的属性转换成数据库中的字符串
StringBuilder sb = new StringBuilder();
for (int num : parameter) {
sb.append(num).append(",");
}
sb.deleteCharAt(sb.length() - 1);
ps.setString(i, sb.toString());
}
@Override
public List<Integer> getNullableResult(ResultSet rs, String columnName) throws SQLException {
// 将数据库中的字符串转换成List<Integer>类型的属性
String str = rs.getString(columnName);
return integerStringToIntegerList(str, IdSplitter);
}
@Override
public List<Integer> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String str = rs.getString(columnIndex);
return integerStringToIntegerList(str, IdSplitter);
}
@Override
public List<Integer> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String str = cs.getString(columnIndex);
return integerStringToIntegerList(str, IdSplitter);
}
/**
* 将由指定分隔符形成的整型数列表字符串分割,返回整形List
* <p>
* integerListString:”1,2,3,4,5,6“
* regex:","
* result:new List<Integer>(){1,2,3,4,5,6}
*
* @param integerListString
* @param regex
* @return
*/
private static List<Integer> integerStringToIntegerList(String integerListString, String regex) {
if (integerListString != null && !integerListString.isEmpty()) {
String[] nums = integerListString.split(regex);
List<Integer> list = new ArrayList<>();
for (String num : nums) {
list.add(Integer.valueOf(num));
}
return list;
}
return new ArrayList<>();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」