关于Mybatis插入对象时空值的处理
作者:梧桐zhbh 发布时间:2023-08-28 21:58:00
Mybatis插入对象时空值
Mybatis中经常会有插入数据的情景,有时传输的对象字段并不是完整的,如果不做任何处理则会抛出异常,影响程序执行。
如存在对象赋值不完整的情况可以在字段后添加 jdbcType 如:
INSERT INTO student(`uid`,`name`,`class`) VALUES(#{uid,jdbcType=VARCHAR},#{name,jdbcType=VARCHAR},#{class,jdbcType=VARCHAR})
然后再 mybatis-config.xml 中添加配置
<settings>
<setting name="jdbcTypeForNull" value="NULL" />
</settings>
如若是其它类型也可使用 <if> 标签
<if test="otherType != null and otherType!= ''" >
otherType = #{otherType}
</if>
这样在数据库未做限制时,就不会影响到数据的添加或修改。
需要注意的点MyBatis插入空值时,需要指定JdbcType
前天遇到一个问题 异常显示如下:
Exception in thread "main" org.springframework.jdbc.UncategorizedSQLException: Error setting null for parameter #6 with JdbcType OTHER . Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. Cause: java.sql.SQLException: 无效的列类型: 1111
; uncategorized SQLException for SQL []; SQL state [99999]; error code [17004]; 无效的列类型: 1111; nested exception is java.sql.SQLException: 无效的列类型: 1111
对应的sqlmap如下:
<insert id="insertCustomerLog" parameterType="map">
insert into customer_log
(
ID,
CUSTOMER_SERVICE_USER_NAME,
user_name,
CONTENT,
LOG_FIRST_TYPE,
STATUS,
LINKED_ID,
FEE,
ACCOUNT_FIRST_TYPE,
ACCOUNT_SECOND_TYPE,
ACCOUNT_THIRD_TYPE,
LOG_SECOND_TYPE,
LOG_IP,
MEMO
)
values
(
seq_customer_log.nextval ,
#{customerServiceUserName} ,
#{username},
#{content},
#{logFirstType},
#{status},
#{linkedId},
#{fee},
#{accountFirstType},
#{accountSecondType},
#{accountThirdType},
#{logSecondType},
#{logIp},
#{memo}
)
</insert>
查询了一下 一些资料说是
MyBatis 插入空值时,需要指定JdbcType ,mybatis insert空值报空值异常,但是在pl/sql不会提示错误,主要原因是mybatis无法进行转换。
<insert id="insertCustomerLog1" parameterType="com.diyicai.customer.domain.CustomerLog">
insert into customer_log
(
ID,
CUSTOMER_SERVICE_USER_NAME,
user_name ,
CONTENT,
LOG_FIRST_TYPE,
STATUS,
LINKED_ID,
FEE,
ACCOUNT_FIRST_TYPE,
ACCOUNT_SECOND_TYPE,
ACCOUNT_THIRD_TYPE,
LOG_SECOND_TYPE,
LOG_IP,
MEMO
)
values
(
seq_customer_log.nextval ,
#{customerServiceUserName,jdbcType=VARCHAR} ,
#{username,jdbcType=VARCHAR},
#{content,jdbcType=VARCHAR},
#{logFirstType,jdbcType=NUMERIC},
#{status,jdbcType=NUMERIC},
#{linkedId,jdbcType=VARCHAR},
#{fee,jdbcType=NUMERIC},
#{accountFirstType,jdbcType=NUMERIC},
#{accountSecondType,jdbcType=NUMERIC},
#{accountThirdType,jdbcType=NUMERIC},
#{logSecondType,jdbcType=NUMERIC},
#{logIp,jdbcType=VARCHAR},
#{memo,jdbcType=VARCHAR}
)
</insert>
错误日志是在:org.apache.ibatis.type.BaseTypeHandler这个类的第17行打出的。根据异常上面的代码 :
if (parameter == null) {
if (jdbcType == null) {
try {
ps.setNull(i, JdbcType.OTHER.TYPE_CODE);
} catch (SQLException e) {
throw new TypeException("Error setting null parameter. Most JDBC drivers require that the JdbcType must be specified for all nullable parameters. Cause: " + e, e);
}
} else {
ps.setNull(i, jdbcType.TYPE_CODE);
}
} else {
setNonNullParameter(ps, i, parameter, jdbcType);
}
可以看出,是因为你传入的参数的字段为null对象无法获取对应的jdbcType类型,而报的错误。 你只要在insert语句中insert的对象加上jdbcType就可以了,修改如下: #{menuTitle,jdbcType=VARCHAR} ,这样就可以解决以上错误了。
但是,如果我们为每个sql都指定jdbc类型,也比较麻烦,可以mybatis-config.xml种全局设置下:
<settings>
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
另外,再补充一点资料,可能更能让我们了解问题的真相:
适配oracle数据库的时候,mybatis报了Error setting null parameter,bug发现是参数出现了null值,对于Mybatis,如果进行操作的时候,没有指定jdbcType类型的参数,就可能导致问题。
postgreSQL,MySQL,SQLSERVER都支持JdbcType.NULL类型,Oracle是不支持,适配的时候也因为这个问题导致mybatis报错。
比如,之前配置#{submitDate},它会在oracle中报错:Error settingnull parameter
更改成#{submitDate,jdbcType=DATE},注意jdbcType是区分大小写的。
来源:https://blog.csdn.net/qq_37623765/article/details/79545525


猜你喜欢
- QTableView是Qt中用来把数据集以表格形式提供给用户的一个控件QTableView类实现表格视图,QTableView的数据由继承Q
- 这里我们给定一个集合strings一、写法1–循环for (int i = 0, len = strings.size(); i <
- 话不多说,先上图 &n
- 1. 准备工作需要提前安装好Elasticsearch,访问地址:http://127.0.0.1:9200/ 得到以下结果,得到clust
- 最近的需求有一个自动发布的功能, 需要做到每次提交都要动态的添加一个定时任务代码结构1. 配置类package com.orion.ops.
- 一个专门实现访问sql server数据库增删改查的操作代码,分享给大家,具体内容如下using System;using System.C
- 1、用字符串分隔: using System.Text.RegularExpressions; string str="aaajs
- AbstractQueuedSynchronizerAbstractQueuedSynchronizer 简称 AQS ,抽象队列同步器,用
- 前言这几天听朋友说JPA很好用,根本不用写sql。我在想一个程序员不写sql还能叫程序员?而且越高级的工具封装越多的工具,可拓展性和效率就非
- 第一步:配置管理器中新建解决方案配置第二步:定义条件编译符号:第三步:在代码中使用自定义的条件编译#if CustomDebugConsol
- Filter简介Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所
- 本文实例讲述了Android编程实现震动与振铃的方法。分享给大家供大家参考,具体如下:1、Android的震动实现——Vibrator类(1
- 一、统一全站字符编码通过配置参数charset指明使用何种字符编码,以处理Html Form请求参数的中文问题package me.gacl
- C#对文件的操作相当方便,主要涉及到四个类:File、FileInfo、Directory、DirectoryInfo,前两个提供了针对文件
- 使用DOM4J方式生成XML文件的步骤如下:引入JAR包通过DocumentHelper类的createDocument()创建Docume
- 本文实例为大家分享了Android实现图像切换器的具体代码,供大家参考,具体内容如下java代码:private int[] imageId
- Android 实现代码混淆的实例1、简介代码混淆(Obfuscated code)亦称花指令,是将计算机程序的代码,转换成一种功能上等价,
- 本文实例为大家分享了Android微信摇一摇功能的实现方法,供大家参考,具体内容如下import java.util.ArrayList;
- 在 Lock 接口中,获取锁的方法有 4 个:lock()、tryLock()、tryLock(long,TimeUnit)、lockInt
- 一、JMH vs JMeterJMeter可能是最常用的性能测试工具。它既支持图形界面,也支持命令行,属于黑盒测试的范畴,对非开发人员比较友