Mybatis插入数据null的的解决方案

本文介绍如何解决MyBatis在插入允许为空的字段时遇到的问题,通过正确配置javaType和jdbcType确保能顺利插入空值。示例中详细展示了配置方法及支持的数据类型对照表。

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

传入一个数据库允许为null的paramterType对象,Mybatis报错插入不能为空,此时不仅需要配置javaType,还有为其指定jdbcType,例如下面的name属性便可轻松插入空数值。

<?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="cn.czyfwpla.xm.mapper.SpotMapper" >
<resultMap id="SpotResultMap" type="cn.czyfwpla.xm.model.Spot">
<id column="id" property="id" javaType="java.lang.String" />
<id column="name" property="name" javaType="java.lang.String" jdbcType="VARCHAR" />
<id column="description" property="description" javaType="java.lang.String" />
<id column="headImg" property="headImg" javaType="java.lang.String" />
<id column="price" property="price" javaType="java.math.BigDecimal" />
<id column="route" property="route" javaType="java.lang.String" />
<id column="strategy" property="strategy" javaType="java.lang.String" />
</resultMap>
<insert id="addSpot" parameterType="cn.czyfwpla.xm.model.Spot" >
INSERT INTO
spot
(id,name,description,headImg,price,route,strategy)
VALUES
(#{id}, #{name}, #{description},#{headImg},#{price},#{route},#{strategy})
</insert>
</mapper>

 附录:javaType与jdbcType的对照表

JDBC Type            Java Type  
CHAR                 String  
VARCHAR              String  
LONGVARCHAR          String  
NUMERIC              java.math.BigDecimal  
DECIMAL              java.math.BigDecimal  
BIT                  boolean  
BOOLEAN              boolean  
TINYINT              byte  
SMALLINT             short  
INTEGER              int  
BIGINT               long  
REAL                 float  
FLOAT                double  
DOUBLE               double  
BINARY               byte[]  
VARBINARY            byte[]  
LONGVARBINARY        byte[]  
DATE                 java.sql.Date  
TIME                 java.sql.Time  
TIMESTAMP            java.sql.Timestamp  
CLOB                 Clob  
BLOB                 Blob  
ARRAY                Array


### MyBatis 插入 Enum 数据的方法 在 MyBatis插入 `Enum` 类型的数据可以通过多种方式进行处理,其中最常用的是使用默认的 `EnumTypeHandler` 或者自定义 `TypeHandler`。 #### 使用默认的 `EnumTypeHandler` 当数据库字段为字符串类型时,MyBatis 默认会自动将 Java 的 `Enum` 转换为其名称(即调用 `name()` 方法),并将其存储到数据库中。如果数据库字段是整数类型,则会转换成枚举类型的序号(即调用 `ordinal()` 方法)。这种方式适用于简单的场景[^1]。 ```java public enum Gender { MALE, FEMALE; } ``` 对于上述枚举类,假设有一个名为 `User` 的实体对象: ```java public class User { private Integer id; private String name; private Gender gender; // getters and setters... } ``` 以及相应的表结构如下所示: | Column Name | Type | |-------------|-------------| | id | INT | | name | VARCHAR(50) | | gender | VARCHAR(20) | 此时可以编写如下的 Mapper XML 文件来实现插入操作而无需额外配置处理器: ```xml <insert id="insertUser" parameterType="com.example.User"> INSERT INTO users (id, name, gender) VALUES (#{id}, #{name}, #{gender}) </insert> ``` 这里的关键在于 `#{gender}` 这个占位符可以直接接受来自 Java 层面传递过来的 `Gender` 枚举实例,并由 MyBatis 自动完成必要的类型转换工作。 #### 定制化解决方案——创建自定义 `TypeHandler` 然而,在某些情况下,默认行为可能不符合需求;比如想要保存枚举成员的具体描述而非其名字或索引值的时候就需要构建一个专门针对特定业务逻辑设计过的 `TypeHandler` 来满足这些特殊的要求了。 下面是一个例子展示了怎样制作这样一个定制化的处理器以便于把性别信息存入数据库的同时也能够读取出来: 首先定义一个新的枚举类型带有更详细的说明属性: ```java public enum DetailedGender { MALE("Male"), FEMALE("Female"); private final String description; DetailedGender(String desc){ this.description = desc; } public String getDescription(){ return description; } } ``` 接着我们需要开发一个继承自 `BaseTypeHandler<DetailedGender>` 的新类用于控制如何序列化/反序列化此枚举至数据库列: ```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 DetailedGenderTypeHandler extends BaseTypeHandler<DetailedGender> { @Override public void setNonNullParameter(PreparedStatement ps, int i, DetailedGender parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter.getDescription()); } @Override public DetailedGender getNullableResult(ResultSet rs, String columnName) throws SQLException { String descrption = rs.getString(columnName); if (rs.wasNull()) { return null; } else { for(DetailedGender g : DetailedGender.values()){ if(g.getDescription().equals(descrption)){ return g; } } throw new IllegalArgumentException("Unknown detailed gender " + descrption); } } @Override public DetailedGender getNullableResult(ResultSet rs, int columnIndex) throws SQLException { String descrption = rs.getString(columnIndex); if (rs.wasNull()) { return null; } else { for(DetailedGender g : DetailedGender.values()){ if(g.getDescription().equals(descrption)){ return g; } } throw new IllegalArgumentException("Unknown detailed gender " + descrption); } } @Override public DetailedGender getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { String descrption = cs.getString(columnIndex); if (cs.wasNull()) { return null; } else { for(DetailedGender g : DetailedGender.values()){ if(g.getDescription().equals(descrption)){ return g; } } throw new IllegalArgumentException("Unknown detailed gender " + descrption); } } } ``` 最后一步是在 MyBatis 配置文件里注册这个新的 `TypeHandler` 并指定给哪个 SQL 列应用它: ```xml <mappers> <!-- Other mappers --> <typeHandlers> <typeHandler handler="com.yourpackage.DetailedGenderTypeHandler"/> </typeHandlers> ... </mappers> ``` 现在每当涉及到 `DetailedGender` 类型的操作都会按照所设定的方式来进行处理了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值