一、关于Mysql的排序规则会导致数据表查询显示不存在
在项目启动后连接数据库时出现: Caused by: java.sql.SQLSyntaxErrorException: Table 'test.MDIY_CONFIG' doesn't exist。显示数据库表不存在,但仔细核对数据库名称无误后,也发现数据库表存在,只是不是按提示中的大写名称,怀疑问题出在此处。
at net.mingsoft.MSApplication.main(MSApplication.java:42) [classes/:?]
Caused by: java.sql.SQLSyntaxErrorException: Table 'test.MDIY_CONFIG' doesn't exist
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120) ~[mysql-connector-java-8.0.28.jar:8.0.28]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-java-8.0.28.jar:8.0.28]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953) ~[mysql-connector-java-8.0.28.jar:8.0.28]
知晓数据库的排序规则会影响此问题,于是查看刚建的数据库时我没有选择排序规则,其默认的字符集是: utf8mb4_0900_ai,未带有 _ci缀。ci 就是表示大小写不敏感(Case Insensitive)。所以需要选择字符集。一般常用 :utf8mb4_general_ci
排序规则即可。
但此处的问题并不是这般,在测试时发现我在MYSQL配置中如果增加相关的不区分大小写的配置项,启动的时候会报错:
Different lower_case_table_names settings for server ('1') and data dictionary ('0').
2. 解决方案
注: 在Docker容器中安装MySQL后遇到报错Different lower_case_table_names settings for server('1') and data dictionary('1'),本质是MySQL 8.0及以上版本对lower_case_table_names参数的严格限制所致。
2.1 参数特性
lower_case_table_names用于控制表名是否区分大小写(1不区分,0区分)。MySQL 8.0之后,该参数必须在初始化时(首次启动)设定,后续修改会导致数据字典(Data Dictionary)与当前配置冲突,即使两者的值相同也可能因历史数据残留引发错误。
若通过Docker挂载已有的数据目录(如-v /usr/local/mysql/data:/var/lib/mysql),即使重新启动容器,MySQL仍会读取旧数据字典中的配置,导致与当前配置不一致。
二、JAVA中使用 jdbcTemplate.queryForList 操作读取 MYSQL的tinyint字段成了 Boolean
在一次数据处理,在读取原MYSQL中的一个 tinyint 字段(有1-4)多个值,在处理时发现这个字段操作报错,通过打印从结果 map 中取出来的类型,发现其是: class java.lang.Boolean 类型。Mysql tinyint长度为1时在java中被转化成boolean型,真是巨大的坑!
解决的方法可以多种方式,比较方便的解决方法可以考虑,一是类似字段不多,可以将数据库里的 tinyint(1)字段,改成 tinyint(4),这样会让查询时自动转为Integer,另外可以在MYSQL的连接上增加内容:&tinyInt1isBit=false 从而在读取时自动转换。
datasource:
url: jdbc:mysql....useSSL=false&tinyInt1isBit=false
三、SpringBoot开发使用中的几个小技巧汇总
下面几个个人整理的技巧内容,可以更高效、更优雅地开发Spring Boot应用。
1. 快速获取当前运行环境
在Springboot 程序中有时想根据当前环境进行一些特殊处理,这时需要在运行中获取和判断环境,可以使用注解直接获取当前 active 的环境值。代码如下:
@Value("${spring.profiles.active}")
private String env;
2. 利用Lombok简化代码
Lombok库可以自动插入Java编辑器,通过注解来减少样板代码。例如,@Data可以自动生成getter、setter、equals、hashCode和toString方法,@Builder用于创建对象的构建器模式。还有用上无参构造、有参构造等注解。
3. 全局异常处理
使用@ControllerAdvice 和 @ExceptionHandler 注解来全局处理控制器中的异常,这样可以集中处理各种异常情况,提高代码的整洁性和可维护性。
4.利用Spring Boot DevTools进行热重载
添加 spring-boot-devtools 依赖可以实现应用的热重载,代码更改后不需要重启应用即可看到效果,极大提高了开发效率,省去经常重启麻烦。
5. 使用Spring Boot Actuator进行监控
Spring Boot Actuator提供了一系列生产准备功能,如应用信息、健康检查、度量指标等。通过添加spring-boot-starter-actuator依赖,你可以轻松地监控和管理你的应用。
6. 使用Spring Batch处理批量任务
对于需要执行大量数据处理的任务,使用Spring Batch可以非常高效地处理复杂的批量操作,包括读取、处理和写入记录到数据库或文件系统。
四、Mysql插入数据唯一索引冲突时避免自增字段增加的处理
在MySQL中,如果你遇到了唯一索引冲突的处理方式包括REPLACE INTO语句、INSERT IGNORE或INSERT ON DUPLICATE KEY UPDATE,但是各有区别:
REPLACE INTO会先尝试插入,如果违反了唯一索引约束,则先删除旧的记录再插入新的记录。不仅会增加而且是删除了原数据重新插入一条不可行。
而使用 使用INSERT IGNORE或INSERT ON DUPLICATE KEY UPDATE,我在MYSQL8.0上测试也依然会导致 自增ID增加。目前来看,在mysql8.0上,要想自增ID不要增加,只能手动处理唯一索引冲突在尝试插入之前先查询数据库以检查是否存在冲突,如果不存在,则插入;如果存在,则执行其他逻辑(如更新、忽略等)。代码就没有必要贴了。