当前位置: 移动技术网 > IT编程>开发语言>Java > Mybatis+Oracle搭配insert空值报错之myBatis+mysql驱动+oracle驱动的源码分析

Mybatis+Oracle搭配insert空值报错之myBatis+mysql驱动+oracle驱动的源码分析

2020年04月15日  | 移动技术网IT编程  | 我要评论

为了便于测试,先给出demo代码:

mybatis-oracle-config.xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!doctype configuration public "-//mybatis.org//dtd config 3.0//en"
 3         "http://mybatis.org/dtd/mybatis-3-config.dtd">
 4 
 5 <configuration>
 6     <properties>
 7         <property name="driver" value="oracle.jdbc.driver.oracledriver"/>
 8         <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521/orcl"/>
 9     </properties>   
10     <environments default="dev">
11         <environment id="dev">        
12             <transactionmanager type="jdbc" />
13                <datasource type="pooled">
14                 <property name="driver" value="${driver}"></property>
15                 <property name="url" value="${url}"></property>
16                 <property name="username" value="gys"></property>
17                 <property name="password" value="gys"></property>
18             </datasource>
19         </environment>
20 
21     </environments>
22     <mappers>       
23         <mapper resource="mapper/oracle/user.xml"></mapper>
24     </mappers>
25 </configuration>

user.xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!doctype mapper public "-//mybatis.org//dtd mapper 3.0//en"
 3         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 4 <mapper namespace="dao.oracle.iusermapper">
 5     <insert id="insertuser" parametertype="model.oracle.user">
 6         insert into users
 7         (name,age)
 8         values
 9         (#{name},#{age})
10     </insert>
11 
12 </mapper>

main()入口方法

public static void main(string[] args) throws exception{  
        sqlsessionfactorybuilder builder=new sqlsessionfactorybuilder();
        sqlsessionfactory sqlsessionfactory=builder.build(resources.getresourceasstream("mybatis-oracle-config.xml"),"dev");
        sqlsession sqlsession=sqlsessionfactory.opensession(true);
        iusermapper usermapper=sqlsession.getmapper(iusermapper.class);
        user user=new user();
        //user.setname("a");//故意注释,不设置。模拟空值
        user.setage(20);
        int count=usermapper.insertuser(user);
        system.out.println(count == 1 ? "插入成功" : "插入失败");
        list<user> list=usermapper.getuserlist();
        for (user user1 : list) {
            system.out.println(user1.tostring());
        }
        sqlsession.close();
    }

源码分析请参考这篇博客:mybatis+oracle搭配insert空值报错之mybatis+mysql驱动+oracle驱动的源码分析

总结一下空值报错的原因:

mybatis在build阶段,不知道这个参数的具体jdbctype类型,mybatis会给他一个默认的1111编号;

在mybatis运行阶段,空值 +111编号条件就使得mybatis去调用了oracle驱动中预编译器的setnull()方法;

因为oracle不识别1111编号,所以直接就抛出了异常。

方法1:构建时办法

在user.xml的sql中,给参数指明具体的jdbctype类型,让oracle预编译器能够知道以varchar或者numeric方式处理这种空值。

修改后的代码如下红色地方。 

<?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="dao.oracle.iusermapper">
    <insert id="insertuser" parametertype="model.oracle.user">
        insert into users
        (name,age)
        values
        (#{name,jdbctype=varchar},#{age})
    </insert>
</mapper>

 方法2:运行时办法 

编写自定义的typehandler。

当mybatis不知道具体的jdbctype类型时,在自定义typehandler中指定jdbctype。

数据库中常用的就两种字段,一个varchar字段,一个numberic字段。所以定义两个typehandler。

public class mynumbernulltypehandler extends integertypehandler {
    @override
    public void setparameter(preparedstatement ps, int i, integer parameter, jdbctype jdbctype) throws sqlexception {
        super.setparameter(ps, i, parameter, jdbctype.numeric);
    }
}
public class mystringnulltypehandler extends stringtypehandler {
    @override
    public void setparameter(preparedstatement ps, int i, string parameter, jdbctype jdbctype) throws sqlexception {       
        super.setparameter(ps,i,parameter,jdbctype.varchar);
    }
}

mybatis-oracle-config.xml中的properties后面添加如下配置

  <typehandlers>
       <typehandler handler="handler.oracle.mystringnulltypehandler" />
        <typehandler handler="handler.oracle.myintegernulltypehandler" />
    </typehandlers>

综合比较后感觉方法2是一个一劳永逸的方法。

 

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网