MySql中对应字段属性为int取出来却为Long

本文记录了在使用Java ORM框架时遇到的类型转换错误:无法将Long类型的ID值赋给int类型字段的问题。详细解析了错误原因,即在数据库中ID字段设置为INT(10) UNSIGNED,导致查询结果类型不匹配。通过修改数据库表字段类型为INT,成功解决了该问题。

今天遇到了如题的问题,接下来看下控制台的报错信息:

java.lang.IllegalArgumentException: Can not set int field cn.zyx.po.User.id to java.lang.Long
	at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
	at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
	at sun.reflect.UnsafeIntegerFieldAccessorImpl.set(UnsafeIntegerFieldAccessorImpl.java:98)
	at java.lang.reflect.Field.set(Field.java:764)
	at cn.zyx.dao.impl.UserDaoImpl.queryUserList(UserDaoImpl.java:76)
	at cn.zyx.service.impl.UserServiceImpl.queryUsers(UserServiceImpl.java:28)
	at cn.zyx.test.SpringV1.test(SpringV1.java:39)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

报错说无法给对象中int属性的id值set为Long类型,百度发现是我在MySql中对id设置了属性为INT(10)UNSIGNED 这种无符号的int值取出来就是为Long,所以我用SQL把表中这个字段对应的属性设置为int,下面是我更改这个字段属性的SQL:

-- t_user是我这里对应的表明,id是字段名
ALTER TABLE t_user MODIFY id  INT(10);
<think>### MySQL整型字段类型对比:TINYINT vs INT vs BIGINT #### 核心区别总结(存储空间与数值范围) | 类型 | 存储空间 | 有符号范围(Signed) | 无符号范围(Unsigned) | 别名 | |------------|----------|--------------------------------------|----------------------------|---------------| | **TINYINT** | 1字节 | -128 ~ 127 | 0 ~ 255 | - | | **SMALLINT** | 2字节 | -32,768 ~ 32,767 | 0 ~ 65,535 | - | | **MEDIUMINT**| 3字节 | -8,388,608 ~ 8,388,607 | 0 ~ 16,777,215 | - | | **INT** | 4字节 | -2,147,483,648 ~ 2,147,483,647 | 0 ~ 4,294,967,295 | INTEGER | | **BIGINT** | 8字节 | -9.2×10¹⁸ ~ 9.2×10¹⁸ | 0 ~ 1.8×10¹⁹ | - | > *注:MySQL中没有单独命名为LONG的类型,但BIGINT相当于其他语言的Long类型* --- ### 关键特性详解 1. **TINYINT** - **典型用途**:状态标记(0/1)、枚举值(如性别:1男 2女) - **布尔替代**: ```sql is_active TINYINT(1) UNSIGNED DEFAULT 0 -- 0=false, 1=true ``` 2. **INT (INTEGER)** - **默认选择**:主键ID、数量计数、时间戳(秒级) - **范围示例**: ```sql user_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY -- 最多42亿用户 ``` 3. **BIGINT** - **超大范围需求**:金融金额(分单位)、毫秒时间戳、分布式ID - **示例**: ```sql snowflake_id BIGINT UNSIGNED NOT NULL -- 雪花算法ID ``` --- ### 使用注意事项 1. **显示宽度陷阱**: - 括号中数字仅影响显示格式(如`INT(11)`),**不改存储范围** - 实际存储由类型本身决定 2. **无符号使用建议**: - 明确不会出现负值时使用`UNSIGNED`(增加可用范围) - 注意运算溢出: ```sql -- 错误:无符号数相减结果为负会报错 SET @a = 1, @b = 2; SELECT @a - @b; -- 有符号:-1(正常) SELECT CAST(@a AS UNSIGNED) - CAST(@b AS UNSIGNED); -- 报错! ``` 3. **自动填充零(ZEROFILL)**: - MySQL 8.0已弃用,建议用应用层格式化 ```sql -- 旧版用法(显示宽度5位,不足补0) product_code INT(5) ZEROFILL -- 123 → '00123' ``` --- ### 类型选择决策树 ```mermaid graph TD A[需要存储的数值] --> B{是否超过42亿?} B -->|是| C[使用BIGINT] B -->|否| D{是否小于65535?} D -->|是| E{是否小于255?} E -->|是| F[使用TINYINT] E -->|否| G[使用SMALLINT/MEDIUMINT] D -->|否| H[使用INT] ``` §§相关问题§§ 1. 在MySQL中,使用无符号整型(UNSIGNED)进行减法运算时可能出现什么问题? 2. 如何正确选择SMALLINT、MEDIUMINTINT类型以优化存储空间? 3. MySQL 8.0版本为什么弃用ZEROFILL属性?替代方案是什么? 4. 当使用INT类型作为自增主键时,达到最大值42亿后会发生什么情况? </think> ### MySQL整型字段类型对比:TINYINT vs INT vs BIGINT #### 核心区别总结(存储空间与数值范围) | 类型 | 存储空间 | 有符号范围(Signed) | 无符号范围(Unsigned) | 别名 | |------------|----------|--------------------------------------|----------------------------|---------------| | **TINYINT** | 1字节 | -128 ~ 127 | 0 ~ 255 | - | | **SMALLINT** | 2字节 | -32,768 ~ 32,767 | 0 ~ 65,535 | - | | **MEDIUMINT**| 3字节 | -8,388,608 ~ 8,388,607 | 0 ~ 16,777,215 | - | | **INT** | 4字节 | -2,147,483,648 ~ 2,147,483,647 | 0 ~ 4,294,967,295 | INTEGER | | **BIGINT** | 8字节 | -9.2×10¹⁸ ~ 9.2×10¹⁸ | 0 ~ 1.8×10¹⁹ | - | > *注:MySQL中没有单独命名为LONG的类型,但BIGINT相当于其他语言的Long类型* --- ### 关键特性详解 1. **TINYINT** - **典型用途**:状态标记(0/1)、枚举值(如性别:1男 2女) - **布尔替代**: ```sql is_active TINYINT(1) UNSIGNED DEFAULT 0 -- 0=false, 1=true ``` 2. **INT (INTEGER)** - **默认选择**:主键ID、数量计数、时间戳(秒级) - **范围示例**: ```sql user_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY -- 最多42亿用户 ``` 3. **BIGINT** - **超大范围需求**:金融金额(分单位)、毫秒时间戳、分布式ID - **示例**: ```sql snowflake_id BIGINT UNSIGNED NOT NULL -- 雪花算法ID ``` --- ### 使用注意事项 1. **显示宽度陷阱**: - 括号中数字仅影响显示格式(如`INT(11)`),**不改存储范围** - 实际存储由类型本身决定 2. **无符号使用建议**: - 明确不会出现负值时使用`UNSIGNED`(增加可用范围) - 注意运算溢出: ```sql -- 错误:无符号数相减结果为负会报错 SET @a = 1, @b = 2; SELECT @a - @b; -- 有符号:-1(正常) SELECT CAST(@a AS UNSIGNED) - CAST(@b AS UNSIGNED); -- 报错! ``` 3. **自动填充零(ZEROFILL)**: - MySQL 8.0已弃用,建议用应用层格式化 ```sql -- 旧版用法(显示宽度5位,不足补0) product_code INT(5) ZEROFILL -- 123 → '00123' ``` --- ### 类型选择决策树 ```mermaid graph TD A[需要存储的数值] --> B{是否超过42亿?} B -->|是| C[使用BIGINT] B -->|否| D{是否小于65535?} D -->|是| E{是否小于255?} E -->|是| F[使用TINYINT] E -->|否| G[使用SMALLINT/MEDIUMINT] D -->|否| H[使用INT] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值