在代码层面上解决由于Java用有符号数值类型映射MySQL无符号数值类型而导致的数值溢出问题
2018-01-25 14:27
597 查看
在代码层面上解决由于Java用有符号数值类型映射MySQL无符号数值类型而导致的数值溢出问题。
如果MySQL数据库中定义一个无符号的数值类型字段,这样在Java中如果用工具生成实体类时,会自动使用一个比特位数相同的有符号数值类型属性映射了这个字段,所以数值范围减半,偏离了设计逻辑。
比如给User表定义一个年龄字段age,类型是无符号的TINYINT(定义有符号的不合逻辑),在Java中用工具生成User表的实体类后,对应的年龄属性被定义成一个Byte类型。
尽管Byte与数据库的TINYINT比特位数相同,但是Byte是有符号的,所以正数范围减半了。
那么怎么解决这个问题呢?很多人首先想到的是修改数据库,定一个大点的数值类型,比如定义成INT。个人认为不建议这么做,原因有三:
1. 年龄数值范围0~255足够用,如果定义成大类型,一方面不合逻辑(不需要那么大的数值范围),另一方面占用存储空间(别小觑多了三个字节,积小成多,量大就惊人了!)。
2. 坚持逻辑设计原则,出现问题,如果不是因为数据库设计不合理而引起的,那就不要在数据库上打主意,因为数据库是根基,根基怎能随便乱动!
3. 即使修改了数据库,改为一个大的数值类型,还是要修改Java代码,修改实体类对应的属性类型以及相关联的代码。
基于上述三个原因,不修改数据,能不能只在代码层面上解决这个问题呢?
答案是肯定的,而且很简单,只需把age属性类型改为Integer即可,如下:
在实际工程中已经检验通过,包括前端提交数据、写数据库、从数据库读取数据在前端显示,都正常。
问题解决!
如果MySQL数据库中定义一个无符号的数值类型字段,这样在Java中如果用工具生成实体类时,会自动使用一个比特位数相同的有符号数值类型属性映射了这个字段,所以数值范围减半,偏离了设计逻辑。
比如给User表定义一个年龄字段age,类型是无符号的TINYINT(定义有符号的不合逻辑),在Java中用工具生成User表的实体类后,对应的年龄属性被定义成一个Byte类型。
public class User { private Long id; private String name; private Byte age; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Byte getAge() { return age; } public void setAge(Byte age) { this.age = age; } }
尽管Byte与数据库的TINYINT比特位数相同,但是Byte是有符号的,所以正数范围减半了。
那么怎么解决这个问题呢?很多人首先想到的是修改数据库,定一个大点的数值类型,比如定义成INT。个人认为不建议这么做,原因有三:
1. 年龄数值范围0~255足够用,如果定义成大类型,一方面不合逻辑(不需要那么大的数值范围),另一方面占用存储空间(别小觑多了三个字节,积小成多,量大就惊人了!)。
2. 坚持逻辑设计原则,出现问题,如果不是因为数据库设计不合理而引起的,那就不要在数据库上打主意,因为数据库是根基,根基怎能随便乱动!
3. 即使修改了数据库,改为一个大的数值类型,还是要修改Java代码,修改实体类对应的属性类型以及相关联的代码。
基于上述三个原因,不修改数据,能不能只在代码层面上解决这个问题呢?
答案是肯定的,而且很简单,只需把age属性类型改为Integer即可,如下:
public class User { private Long id; private String name; private Integer age; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
在实际工程中已经检验通过,包括前端提交数据、写数据库、从数据库读取数据在前端显示,都正常。
问题解决!
相关文章推荐
- 解决mysql 数据库中日期类型00:00:00 的问题 设置xml数据类型:java.util.Date
- 记一次由于Java泛型类型擦除而导致的问题,及解决办法
- mysql无符号整型溢出问题及解决办法
- 解决由于升级的Win10周年版本后Oracle VM VirtualBox无法运行导致的eNSP V390里面的路由器和防火墙等设备无法启动的问题(错误代码40)
- 解决项目中由于前端页面数据类型跟数据库类型不一致,导致获取数据为空引起问题
- 《对“XXX::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们》的问题的解决方法
- java实现插入mysql二进制文件,blob类型,遇到问题及解决办法
- java实现插入mysql二进制文件,blob类型,遇到问题及解决办法
- java替换文本中所有的正则符号 Java问题通用解决代码
- hibernate+mysql java中boolean类型的映射问题+struts2取boolean值
- java代码的分层,解决一个文件有太多行的代码导致维护阅读困难的问题
- 类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们的问题的解决方法 续集
- 解决mysql 数据库中日期类型00:00:00 的问题 设置xml数据类型:java.util.Date
- java实现动态代理代码实例(死循环溢出的问题的解决)
- 实验过程中遇到的mysql DateTime类型与java Calendar问题与解决过程记录
- 关于mysql中由于类型转换导致索引无法使用的问题
- 由于mysql隐式类型转换导致的索引失效的问题
- 类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们的问题的解决方法
- 怎样解决thephile中的数据库由于排序造成的问题:对 text 数据类型不支持代码页转换。从: 1252 到: 936