MySQL字段类型和Java实体类型的转换问题 |
您所在的位置:网站首页 › 数据库double类型的字段怎么配置 › MySQL字段类型和Java实体类型的转换问题 |
1. MySQL的字段类型和Java类型的对应关系
MySQL Connector/J( MySQL官方JDBC驱动程序)在处理MySQL数据类型和Java数据类型之间的转换方面非常灵活。 通常,任何MySQL数据类型都可以转换为java.lang.String。 可以将字符串和任何数字类型转换为任何Java数字类型,尽管可能会发生舍入、溢出或精度损失。从Connector/J 3.1.0开始,JDBC驱动程序会发出警告或引发JDBC规范所要求的DataTruncation异常(数据截断异常),除非通过使用jdbcCompliantTruncation属性并将其设置为false来将连接配置为不这样做。 MySQL和Java类型之间始终保证有效的转换 MySQL类型可转换的Java类型char, varchar, blob, text, enum, setjava.lang.String , java.io.InputStream, java.io.Reader,java.sql.Blob,java.sql.Clobfloat, real, double, precision, numeric, decimal , tinyint, smallint, mediumint, integer, bigintjava.lang.String , java.lang.Short, java.lang.Integer,java.lang.Long,java.lang.Double, java.math.BigDecimaldate, time, datetime, timestampjava.lang.String ,java.sql.Date, java.sql.Timestamp注意 如果选择的Java数字数据类型的精度或容量低于要转换的MySQL数据类型,则可能会发生舍入、溢出或精度损失。 案例
表格中的对应关系仅仅是推荐的,具体如何映射可以根据业务需求进行变更 ,并不是定死就这样,如:Mysql中字段类型是Decimal类型,在满足业务需求的情况下,可以在Java类型中可以使用Double在对应的数据接收。 3. Sql中decimal、float、double类型的区别与用法 3.1 三者的区别介绍float:浮点型,含字节数为4,32bit,数值范围为-3.4E383.4E38(7个有效位) double:双精度实型,含字节数为8,64bit数值范围-1.7E3081.7E308(15个有效位) decimal:数字型,128bit,不存在精度损失,常用于银行帐目计算。(28个有效位) 3.2 decimal的详细介绍 定义decimal(a,b) 参数说明 a 指定指定小数点左边和右边可以存储的十进制数字的最大个数,最大精度38。 b 指定小数点右边可以存储的十进制数字的最大个数。小数位数必须是从 0 到 a之间的值。默认小数位数是 0。 3.3 对比案例 float f = 345.98756f; --结果显示为345.9876,只显示7个有效位,对最后一位数四舍五入。 double d=345.975423578631442d; --结果显示为345.975423578631,只显示15个有效位,对最后一位四舍五入。 --注:float和double的相乘操作,数字溢出不会报错,会有精度的损失。 decimal dd=345.545454879..--可以支持28位,对最后一位四舍五入。 --:当对decimal类型进行操作时,数值会因溢出而报错。 4. Mybatis中JdbcType的作用个人疑问的由来:今天在学习公司项目代码的时候惊奇的发现Mybatis中的映射类型和Java中的映射类型不一致,Mysql中设置的字段类型是Decimal类型,但是在Java中实体对应属性的数据类型缺选择使用的是Double作为对应,并且在查看代码的时候发现属性映射中有使用到JdbcType这个字段,一开始怀疑是JdbcType的作用,查阅了资料有了以下的答案 对于如下一条insert语句(这里只是做测试,实际中肯定不会这么写),如果我们的age传的空,那么对于mysql数据库可以正常插入,对于oracle数据库,会报错“无效的列类型”。 也就是说对于mysql数据库的插入来说,jdbcType是没用的,oracle数据库是有用的(值为null时有用)。 insert into test(id, name, age) values (7, #{name,jdbcType=VARCHAR},#{age})我没有测试更新的情况,但是我猜测结论应该是一样的。**对于查询操作,在mybatis配置时也可以指定jdbcType,这里的jdbcType至少在我测试时也没发现有什么作用(mysql, oracle都是),**当然可能只是我没发现,不代表没有作用,不作为编码建议。 4.1 问题产生insert操作时jdbcType的作用测试这里只分析insert操作时,为什么mysql和oracle表现会不同。 我们用如下代码来进行测试。 mybatis mapper中的sql如下,因为oracle自增主键比较麻烦,这里为了方便写死了id,仅测试用。 insert into t_user(id, name, age) values (7, #{name,jdbcType=VARCHAR}, #{age})java测试代码如下,这里就不贴全部代码了,用过mybatis应该都能看懂。 User user = new User(); user.setName("zzj"); user.setAge(null); mapper.testJdbcType(user);然后我们分别连接mysql和oracle 查看执行结果 mysql可以正常插入 但是oracle数据库会报如下错误(Error setting null for parameter #2 with JdbcType OTHER . java.sql.SQLException: 无效的列类型)mybatis中的增删改查基本都是用PreparedStatement来实现的,PreparedStatement有个setNull方法 ,方法签名如下: void setNull(int parameterIndex, int sqlType) throws SQLException;当我们要插入的值是null时,mybatis就会调用PreparedStatement的setNull来设置对应的参数。 我们跟踪下mybatis执行过程,可以发现是在org.apache.ibatis.scripting.defaults.DefaultParameterHandler#setParameters这个方法中进行sql的参数设置。我们断点执行到这个方法,如下图
我们先来看mysql的setNull方法,如下图。
可以看到,尽管第2个参数为sqlType,但是mysql实现中并没有用到这个参数,所以jdbcType的值对mysql是没有什么用的。 我们再来看oracle是如何实现setNull的 如下图,由于下载不到源码,所以oracle的代码看起来没那么直观,不过对于分析完全够用了。 有了上面的分析,我们就知道mybatis在插入数据时是怎么使用jdbcType的了,由此也可得出结论,对于插入操作,如果某个字段值为null,jdbcType的设置对mysql数据库没什么用,对oracle数据库有用。 资料来源 MySQL字段类型与Java实体类类型对应转换关系 mybatis jdbcType的作用,无效的列类型错误解决办法 mybatis jdbcType的作用,无效的列类型错误解决办法 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |