在做项目的时候,数据库中的所有字段被设置为全都不能为null,但是在我们开发过程中,插入一些记录的时候,实体类中的一些字段如果页面没有传入,则默认就会被设置为null,这样的话,在执行插入语句的时候,数据库就会报错,说指定的列不能为null,这样数据就无法插入。
在网上找了一下,都没有这种处理的方式,但是找到了mybatis的类型转换,说的是在java中的类型和数据库中的类型不一致的时候,需要自己处理数据库类型和java中类型之间的转换,这个就是通过mybatis的typehandler来处理的。
查看typehandler这个接口发现有一下几个需要实现的方法:

public String getResult(ResultSet rs, String columnName) throws SQLException;
public String getResult(ResultSet rs, int columnIndex) throws SQLException;
public String getResult(CallableStatement cs, int columnIndex) throws SQLException;
public void setParameter(PreparedStatement pstmt, int index, String value, JdbcType jdbcType) throws SQLException;

在这4个需要实现的方法中,我们只需要关注第4个方法,因为这个方法是mybatis在给参数设置值的时候,会调用到此方法,基于这样的原因,如果我们在 setParameter中判断当前参数传入的值,如果value=null,我们就将参数的值设置为空的字符串,这样就避免了在执行插入语句的时候,传入null的情况,数据库中也不会报错,问题就解决了。

代码:
package zzt.ssm.controller.typehandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;

public class NullValueHandler implements TypeHandler<String> {

    @Override
    public String getResult(ResultSet rs, String columnName) throws SQLException {
        return rs.getString(columnName);
    }

    @Override
    public String getResult(ResultSet rs, int columnIndex) throws SQLException {
        return rs.getString(columnIndex);
    }

    @Override
    public String getResult(CallableStatement cs, int columnIndex) throws SQLException {
        return cs.getString(columnIndex);
    }

    @Override
    public void setParameter(PreparedStatement pstmt, int index, String value, JdbcType jdbcType) throws SQLException {
        if(value == null && jdbcType == JdbcType.VARCHAR){//判断传入的参数值是否为null
            pstmt.setString(index,"");//设置当前参数的值为空字符串
        }else{
            pstmt.setString(index,value);//如果不为null,则直接设置参数的值为value
        }
    }

}

以上是已经定义好的一个typehandler类,但是还需要我们在配置文件中注册我们自定义的typehandler,因为使用了和spring继承的配置,所以注册typehandler的配置在spring的配置文件中的配置如下:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- 指定mapper文件位置 -->
        <property name="mapperLocations" value="classpath*:**/dao/*Mapper.xml" />
        <!-- 指定别名 -->
        <property name="typeAliasesPackage" value="zzt.ssm.domain" />
         <property name="typeHandlersPackage" value="zzt.ssm.c ontroller.typehandler"/>
    </bean>
这里指定了 typeHandlersPackage属性,value为自定义的typehandler的包名,这样mybatis会将这个包下面的所有的类注册为对应的TypeHandler类。

到这里我们的自定义的TypeHandler就配置好了,
下面在我们的mybatis的mapper中,指定对应的typehandler为自定义的TypeHandler类就可以了

<!-- 添加人员信息 -->
    <insert id="insertPerson" parameterType="Person">
        insert into person(name,sex,address)
            values( #{name,jdbcType=VARCHAR,typeHandler=zzt.ssm.controller.typehandler.NullValueHandler},#{sex},#{address} )
    </insert>

这里在name参数上指定了 typeHandler配置,这样在数据插入的时候,mybatis会调用自定义的TypeHandler类来处理name参数的值,即,如果name的值为null则设置为空字符串,如果不为空,则直接设置值。

现在如果我们测试,在前端如果没有传入name属性的情况下,数据库中插入的数据是否为空字符串,而不是null

直接在浏览器的地址栏中输入, http://localhost:8080/springmvcmybatis/person/savePerson.action?address=dddd
这里我们什么参数都没有传入,那么在springmvc中Controller中,就会将对应的实体的属性值设置为null

现在我们看到,页面传入的属性值已经被注入到对应的实体的属性中,没有传入的属性全都是null。

此时查看数据库中插入的记录,可以看到name的值为空字符串,而没有处理的sex的值为null

实现自定义的除了使用以上这种实现 TypeHandler接口的方式外,还可以直接继承BaseTypeHandler来实现。
mybatis官方文档: http://mybatis.org/mybatis-3/zh/configuration.html#typeHandlers

mybatis插入数据时处理为null的属性的更多相关文章

  1. 用注解的方式实现Mybatis插入数据时返回自增的主键Id

    一.背景 我们在数据库表设计的时候,一般都会在表中设计一个自增的id作为表的主键.这个id也会关联到其它表的外键. 这就要求往表中插入数据时能返回表的自增id,用这个ID去给关联表的字段赋值.下面讲一 ...

  2. mybatis 插入数据时返回主键

    在使用MyBatis做持久层时,insert语句默认是不返回记录的主键值,而是返回插入的记录条数:显然,假如主键是你生成后插入的,自然你已经有主键了,显然不需要我们再去获得,所以我们这里处理的是当主键 ...

  3. mysql数据库使用mybatis 插入数据时返回主键

    为了体现题目,特指的是mysql,先贴上代码: <insert id="saveBizProdOrderDetail" useGeneratedKeys="true ...

  4. MyBatis框架——mybatis插入数据返回主键(mysql、oracle)

    向数据库中插入数据时,大多数情况都会使用自增列或者UUID做为主键.主键的值都是插入之前无法知道的,但很多情况下我们在插入数据后需要使用刚刚插入数据的主键,比如向两张关联表A.B中插入数据(A的主键是 ...

  5. 在MyBatis中查询数据、涉及多参数的数据访问操作、插入数据时获取数据自增长的id、关联表查询操作、动态SQL、关于配置MyBatis映射没有代码提示的解决方案

    1. 单元测试 在单元测试中,每个测试方法都需要执行相同的前置代码和后置代码,则可以自定义2个方法,分别在这2个方法中执行前置代码和后置代码,并为这2个方法添加@Before和@After注解,然后, ...

  6. Mybatis + Mysql 插入数据时中文乱码问题

    近日跟朋友一起建立一个项目,用的是spring+mybatis+mysql. 今天碰到一个mybatis向mysql中插入数据时,中文显示为'???'的问题,拿出来说下. 对于数据库操作中出现的中文乱 ...

  7. mybatis 需要注意的点 MyBatis 插入空值时,需要指定JdbcType (201

    转自:https://blog.csdn.net/snakemoving/article/details/76052875 前天遇到一个问题 异常显示如下: 引用 Exception in threa ...

  8. 触发器修改后保存之前的数据 表中插入数据时ID自动增长

    create or replace trigger t before update on test5 for each rowbegin insert into test55 values (:old ...

  9. mysql插入数据时,中文乱码

    MySQL 插入数据时,中文乱码问题的解决(转) 当向 MySQL 数据库插入一条带有中文的数据形如 insert into employee values(null,'张三','female','1 ...

随机推荐

  1. Git:分布式版本控制系统

    参考廖雪峰的 Git 教程:https://www.liaoxuefeng.com/wiki/896043488029600  讲解很详细,这里只做一些个人笔记: 各系统安装 Git :https:/ ...

  2. IDEA连接Mysql数据库之后,在Mapper.xml编写SQL时不会自动提示表信息问题(非常详细!)

    1.首先得连接上数据库 (一)点击IDEA右侧数据库模块 (二)选择MySql进行连接 (三)填写数据库相关配置 (四)重点!!! 这个时候点击测试连接是连接不上的,需要设置时区 (按照如下设置) ( ...

  3. Batch Normalization和Layer Normalization

    Batch Normalization:对一个mini batch的样本,经过一个nueron(或filter)后生成的feature map中的所有point进行归一化.(纵向归一化) Layer ...

  4. 获取HTML网页中option标签元素的值

    在进行表单元素的操作时,难免会遇到对option元素的挑选,下面的示例代码能够很好的获取到你option元素选择的值,如果要传递给后端,可通过ajax或者其他方式传递即可. 示例代码 <!doc ...

  5. python 包(package)和模块(module)的创建和引入(import)

    python 包(package)和模块(module)的创建和引入(import) 名词解释 实际上,Python中的函数(Function).类(Class).模块(Module).包库(Pack ...

  6. 【学习转载】MyBatis源码解析——日志记录

    声明:转载自前辈:开心的鱼a1 一 .概述 MyBatis没有提供日志的实现类,需要接入第三方的日志组件,但第三方日志组件都有各自的Log级别,且各不相同,但MyBatis统一提供了trace.deb ...

  7. 2020.10.10--pta阶梯赛练习2补题

    7-3.N个数求和 本题的要求很简单,就是求N个数字的和.麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式. 输入格式: 输入第一行给出一个正整数N(≤100).随后 ...

  8. 一文弄懂CGAffineTransform和CTM

    一文弄懂CGAffineTransform和CTM 一些概念 坐标空间(系):视图(View)坐标空间与绘制(draw)坐标空间 CTM:全称current transformation matrix ...

  9. javascript高级程序设计第三版书摘

    在HTML 中使用JavaScript <script>元素 在使用<script>元素嵌入 JavaScript 代码时,只须为<script>指定 type 属 ...

  10. Java中的函数式编程(四)方法引用method reference

    写在前面 我们已经知道,lambda表达式是一个匿名函数,可以用lambda表达式来实现一个函数式接口.   很自然的,我们会想到类的方法也是函数,本质上和lambda表达式是一样的,那是否也可以用类 ...