- 由于前端传递的数值超过了mysql数据库中tinyint类型的取值范围,所以就会报错。
Caused by: com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Out of range value for column 'allow_invite' at row 1
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:104)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:974)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1113)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1061)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1381)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1046)
at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_executeUpdate(FilterChainImpl.java:2843)
at com.alibaba.druid.filter.FilterAdapter.preparedStatement_executeUpdate(FilterAdapter.java:1091)
at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_executeUpdate(FilterEventAdapter.java:491)
at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_executeUpdate(FilterChainImpl.java:2841)
at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.executeUpdate(PreparedStatementProxyImpl.java:194)
at com.alibaba.druid.pool.DruidPooledPreparedStatement.executeUpdate(DruidPooledPreparedStatement.java:256)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:175)
... 146 more
-- auto-generated definition
create table invite_codes
(
id int auto_increment
primary key,
admin_id int null,
bound_phone varchar(20) null,
bound_wx_uid varchar(255) null,
created_date timestamp default CURRENT_TIMESTAMP not null,
expire_time datetime null,
generated_date datetime not null,
invite_code varchar(255) not null,
invite_level int null,
is_locked tinyint(1) default 0 null,
last_modified_date timestamp null on update CURRENT_TIMESTAMP,
remark text null,
status tinyint default 0 not null,
user_id int null,
weixin_headimg varchar(255) null,
weixin_nickname varchar(255) null,
invitor int not null,
allow_invite tinyint default 0 not null
)
engine = MyISAM;
create index FKnqn27fyjlgio5y60eieohi0bf
on invite_codes (invitor);
根据你提供的数据库创建脚本,allowInvite
字段在数据库中的定义如下:
allow_invite tinyint default 0 not null
分析
- 数据类型:
tinyint
- 默认值:
0
- 是否为空:
not null
关键点
-
有符号 vs 无符号:
- 默认情况下,
tinyint
在 MySQL 中是有符号的,取值范围是-128
到127
。 - 无符号:如果字段定义中包含
unsigned
关键字,则取值范围是0
到255
。
- 默认情况下,
-
你的字段定义:
- 在你的创建脚本中,
allow_invite
字段没有unsigned
关键字,因此它是有符号的tinyint
。
- 在你的创建脚本中,
结论
- 取值范围:
allow_invite
字段的取值范围是-128
到127
。 - 前端传递
999
的结果:由于999
超出了有符号tinyint
的最大值127
,前端传递999
会导致数据库插入或更新时报错。
解决方案
为了支持 999
或更大的值,你可以将 allow_invite
字段改为无符号的 tinyint
或者更大的数据类型。以下是两种解决方案:
1. 将 allow_invite
改为无符号的 tinyint
ALTER TABLE invite_codes MODIFY COLUMN allow_invite tinyint unsigned default 0 not null;
2. 将 allow_invite
改为 smallint
ALTER TABLE invite_codes MODIFY COLUMN allow_invite smallint default 0 not null;
smallint
的取值范围是-32768
到32767
(有符号)或0
到65535
(无符号),可以更好地支持更大的值。
示例:修改为无符号的 tinyint
ALTER TABLE invite_codes MODIFY COLUMN allow_invite tinyint unsigned default 0 not null;
示例:修改为 smallint
ALTER TABLE invite_codes MODIFY COLUMN allow_invite smallint default 0 not null;
更新实体类
确保在 Java 实体类中更新相应的字段定义,以匹配数据库的变化。例如,如果改为无符号的 tinyint
:
@Column(columnDefinition = "tinyint unsigned default 0")
@ApiModelProperty(value = "允许邀请的层级,默认为0(不允许)," +
"1表示该用户可以生成邀请码,但其生成的邀请码对应的用户不能继续生成邀请码;" +
"2表示该用户可以生成邀请码,其生成的邀请码对应的用户也可以生成邀请码,但再下一级用户不能生成邀请码;" +
"999表示用户可以生成邀请码,并且可以无限传递下去;", required = true, example = "1")
private Integer allowInvite;
或者如果改为 smallint
:
@Column(columnDefinition = "smallint default 0")
@ApiModelProperty(value = "允许邀请的层级,默认为0(不允许)," +
"1表示该用户可以生成邀请码,但其生成的邀请码对应的用户不能继续生成邀请码;" +
"2表示该用户可以生成邀请码,其生成的邀请码对应的用户也可以生成邀请码,但再下一级用户不能生成邀请码;" +
"999表示用户可以生成邀请码,并且可以无限传递下去;", required = true, example = "1")
private Integer allowInvite;
通过这些修改,你可以确保 allowInvite
字段能够支持 999
或更大的值,从而避免前端传递 999
时出现数据库错误。