一、发现经历

事情是这样的,我今天本来要演示系统,就去前端同学的页面上点一点。不小心点到了其他同事编写的服务,然后界面就报错了。这给我吓得,这还能演示吗这。然后,我就去服务器查看了一下日志,发现了如下景象:

看到这景象啊,我第一件事情就是查看堆栈,也没找到自己写的代码啊,好好的咋就报错了。

于是,我第一件事情,复制报错信息找到百度网站。复制粘贴,往上一怼!好家伙,竟然找不到一个和我症状一样的。

那我只能自己处理了。

二、问题定位

从堆栈信息定位一个问题的位置其实是很简单的,但是要明白为什么错误,还是得多看一会儿的。

我定睛看了一阵子,发现了

at org.apache.ibatis.type.LocalDateTimeTypeHandler.getNullableResult(LocalDateTimeTypeHandler.java:38)

这一行报错,于是我就跟进源码查看。这个源码,写的也简单。

 1 /**
2 * Copyright 2009-2019 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.apache.ibatis.type;
17
18 import java.sql.CallableStatement;
19 import java.sql.PreparedStatement;
20 import java.sql.ResultSet;
21 import java.sql.SQLException;
22 import java.time.LocalDateTime;
23
24 /**
25 * @since 3.4.5
26 * @author Tomas Rohovsky
27 */
28 public class LocalDateTimeTypeHandler extends BaseTypeHandler<LocalDateTime> {
29
30 @Override
31 public void setNonNullParameter(PreparedStatement ps, int i, LocalDateTime parameter, JdbcType jdbcType)
32 throws SQLException {
33 ps.setObject(i, parameter);
34 }
35
36 @Override
37 public LocalDateTime getNullableResult(ResultSet rs, String columnName) throws SQLException {
38 return rs.getObject(columnName, LocalDateTime.class);
39 }
40
41 @Override
42 public LocalDateTime getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
43 return rs.getObject(columnIndex, LocalDateTime.class);
44 }
45
46 @Override
47 public LocalDateTime getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
48 return cs.getObject(columnIndex, LocalDateTime.class);
49 }
50 }

一共也就这么几行。报错的是:

public LocalDateTime getNullableResult(ResultSet rs, String columnName) throws SQLException {
return rs.getObject(columnName, LocalDateTime.class);
}
这个方法。这里面发生了空指针。

这时候,我发现还是最细的堆栈信息。于是,我到最细的那一层。

也就是这一行。

看到这里,我明白了。实际上就是

getTimestamp(columnIndex) 

这个获取时间的时候,数据库的submit_time字段没有值,然后cast的时候,发生了空指针。

三、问题解决

弄清了病症,也就好下药治疗了。我脑中浮现出两个想法:

1、让submit_time有值

这不简单吗,没值的时候有问题,我让你有值不就完事了。哈哈。开个玩笑,要结合业务处理的哈。这种方法明显不可取。

2、重写LocalDateTimeTypeHandler这个类,然后添加空指针判断。

这个方法不错,可以解决实际问题。

于是,我查看了其他类型的处理。

 1 /**
2 * Copyright 2009-2018 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.apache.ibatis.type;
17
18 import java.sql.CallableStatement;
19 import java.sql.PreparedStatement;
20 import java.sql.ResultSet;
21 import java.sql.SQLException;
22
23 /**
24 * @author Clinton Begin
25 */
26 public class DoubleTypeHandler extends BaseTypeHandler<Double> {
27
28 @Override
29 public void setNonNullParameter(PreparedStatement ps, int i, Double parameter, JdbcType jdbcType)
30 throws SQLException {
31 ps.setDouble(i, parameter);
32 }
33
34 @Override
35 public Double getNullableResult(ResultSet rs, String columnName)
36 throws SQLException {
37 double result = rs.getDouble(columnName);
38 return result == 0 && rs.wasNull() ? null : result;
39 }
40
41 @Override
42 public Double getNullableResult(ResultSet rs, int columnIndex)
43 throws SQLException {
44 double result = rs.getDouble(columnIndex);
45 return result == 0 && rs.wasNull() ? null : result;
46 }
47
48 @Override
49 public Double getNullableResult(CallableStatement cs, int columnIndex)
50 throws SQLException {
51 double result = cs.getDouble(columnIndex);
52 return result == 0 && cs.wasNull() ? null : result;
53 }
54
55 }

看了Double的类型处理【1、wasNull设置标志位 2、获取的外面通过标志位判空】,我又看了Integer的类型处理。。。

 1  /**
2 * Copyright 2009-2018 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.apache.ibatis.type;
17
18 import java.sql.CallableStatement;
19 import java.sql.PreparedStatement;
20 import java.sql.ResultSet;
21 import java.sql.SQLException;
22
23 /**
24 * @author Clinton Begin
25 */
26 public class IntegerTypeHandler extends BaseTypeHandler<Integer> {
27
28 @Override
29 public void setNonNullParameter(PreparedStatement ps, int i, Integer parameter, JdbcType jdbcType)
30 throws SQLException {
31 ps.setInt(i, parameter);
32 }
33
34 @Override
35 public Integer getNullableResult(ResultSet rs, String columnName)
36 throws SQLException {
37 int result = rs.getInt(columnName);
38 return result == 0 && rs.wasNull() ? null : result;
39 }
40
41 @Override
42 public Integer getNullableResult(ResultSet rs, int columnIndex)
43 throws SQLException {
44 int result = rs.getInt(columnIndex);
45 return result == 0 && rs.wasNull() ? null : result;
46 }
47
48 @Override
49 public Integer getNullableResult(CallableStatement cs, int columnIndex)
50 throws SQLException {
51 int result = cs.getInt(columnIndex);
52 return result == 0 && cs.wasNull() ? null : result;
53 }
54 }

Integer的类型处理也是【1、wasNull设置标志位 2、获取的外面通过标志位判空】。

这真是好家伙,坐不住了。其他的类型都处理了,合着就我用的LocalDateTime没做空指针处理。这哪能行。重写,必须重写。

 1 package com.vsofo;
2
3 import org.apache.ibatis.type.LocalDateTimeTypeHandler;
4 import org.springframework.stereotype.Component;
5
6 import java.sql.ResultSet;
7 import java.sql.SQLException;
8 import java.time.LocalDateTime;
9
10 @Component
11 public class LocalDateTimeTypeHandlerPlus extends LocalDateTimeTypeHandler {
12
13 @Override
14 public LocalDateTime getResult(ResultSet rs, String columnName) throws SQLException {
15 Object object = rs.getObject(columnName);
16 if(object==null){
17 return null;
18 }
19 return super.getResult(rs, columnName);
20 }
21 }

我直接继承,然后重写获取逻辑。

1、先获取数据库的值

2、判空,如果值为空,直接返回。

3、如果,值不为空,进行原来的强转逻辑。

重写之后,问题完美解决了。

四、心得体会

我觉着吧,框架是个好东西,能让我们开发项目事半功倍。但是如果给你埋了一个大雷,也可能让你事倍功半。

所以,我们用框架开发的过程中,应该多用多测多实践。找出影响项目的问题,然后解决它。

分享结束,谢谢大家观看哈!



【MybatisPlus】数据库的datetime类型字段为空的时候,报错空指针?的更多相关文章

  1. Mysql 数据库date, datetime类型设置0000-00-00默认值(default)报错问题

    Mysql 数据库date, datetime类型设置0000-00-00默认值报错问题 现象:MySQL5.7版本之后,date, datetime类型设置默认值"0000-00-00&q ...

  2. DataTable 数据导入MS ACCESS 数据库中 数字类型字段为空的解决办法

    string strSql = "insert into GongCheng (GCSY,GCBH,GCBHOLD,GCMC,GCKCJD,GCJSDW,GCSJDW,GCKCDW,GCSG ...

  3. Oracle数据库在给表添加字段的sql中用comment报错

    原因:不同于mysql,Oracle数据库在添加表字段时不能直接用comment,而是单独写一个sql语句,如下: alter table SYS_USER add SENDMSG_LASTTIME ...

  4. 如何把datetime类型字段修改为int类型

    如何把datetime类型字段修改为int类型 我有一个表为:table1 其中有一个datetime类型的字段  a    现在我想我想把字段a的类型改为int类型 当我执行以下命令时报如下的错误a ...

  5. C# WebAPI中DateTime类型字段在使用微软自带的方法转json格式后默认含T的解决办法

    原文:C# WebAPI中DateTime类型字段在使用微软自带的方法转json格式后默认含T的解决办法 本人新手,在.Net中写WebAPI的时候,当接口返回的json数据含有日期时间类型的字段时, ...

  6. 多线程中,ResultSet为空,报错空指针

    最近在数据库查询数据时,由于数据量太大,使用了多线程,通过线程池建了好几个线程,然后调用了一个封装好的jdbc查询语句. 结果在多线程中,ResultSet报错空指针. 仔细查阅后,才发现多个线程访问 ...

  7. 解决Entity Framework中DateTime类型字段异常

    从 datetime2 数据类型到 datetime 数据类型的转换产生一个超出范围的值 具体的错误原因是:C#中的DateTime类型比SqlServer中的datetime范围大.SqlServe ...

  8. MSSQL数据库中Text类型字段在PHP中被截断之解 (转)

    在PHP中使用了MSSQL数据库,恰巧数据库中又使用了Text类型字段,于是问题产生了.每次从数据库中查询得到的数据总是被莫名的截断,一开始是以为我使用的PHP框架中对字符串的长度有所限制,后来发现这 ...

  9. 数据库中float类型字段,转化到前端显示,统一保留两位小数

    客户的一个需求,mybatis查询到的数据库的数据进行转换,采用TypeHandler<T>的方式.float保留两位精度可以采用DecimalFormat 直接贴上最终的解决代码(事情没 ...

随机推荐

  1. Python 面像对象编程(上)

    一: 对象的概念 "面向对象"的核心是"对象"二字,而对象的精髓在于"整合",什么意思? 所有的程序都是由"数据"与&q ...

  2. Springboot+Vue前后端分离的博客项目

    项目介绍 演示站(服务器已过期):http://blog.hanzhe.site 开源项目地址 ( 求给个Star ):https://gitee.com/zhang_hanzhe/blog 前端采用 ...

  3. git 让忽略.gitignore文件马上生效

    在.gitignore文件里面输入 *.zip 表示所有zip文件忽略更改 /bin 表示忽略整个根目录的bin文件夹 /src/aa.jar 表示忽略/src/aa.jar文件 设置完.gitign ...

  4. Python中如何生成requirements.txt文件

    Python项目中一般都包含一个名为 requirements.txt 文件,用来记录当前项目所有的依赖包和版本号,在一个新环境下通过该文件可以更方便的构建项目所需要的运行环境. 生成requirem ...

  5. 13- jmeter性能测试案例

    配置原件 HTTP请求默认值 前置处理程序 定时器 取样器 后置处理器:正则表达式提取器 断言 监听器 性能测试流程 1.评估获取性能测试需求(访问量大,操作频繁) 2.确定性能测试目标 : 并发用户 ...

  6. windows内核开发环境的简易搭建

    一.windows内核开发需要的软件 1.WDK 2.WinDbg 3.virtualKD 4.DebugView 5.Visual C++ 6.0 6.VMware Workstation 二.wi ...

  7. hdu4923 f(A,B)分段处理

    题意:        给你序列A,让你构造序列B然后求出最小的f(A <B),其中A 是0,或者1组成的,而B是[0,1]的实数,f(A,B) = 求和(i从1到n) (Ai - Bi)^ 2. ...

  8. Windows XP sp3 系统安装 Windbg 符号文件 Symbols 时微软失去支持的解决方案

    0x01 前言 Windbg 是微软的正宗调试器,在正常的情况下调试一些程序并没有什么问题,但是如果需要调试分析程序的堆栈,或者是一些特殊的功能时则需要微软的符号文件的支持,所以符号文件是非常重要的, ...

  9. 安装google cloud sdk报错解决方法总结(超全)

    前提:python环境最好是2.7,如果是python3可能会出很多小毛病:能用64位系统就尽量用64位,32位系统安装也很多毛病 一.Error1:Unzip Failed: Error openi ...

  10. OpenStack+kvm虚拟机xml格式解析

    配置说明 首先介绍一下配置结构: xml配置遵循<keyword> xxxxxx </keyword>的格式,即一个配置段以<keyword>开头,以</ke ...