记一下在 Spring + MyBatis 整合中遇到的问题以及解决方案

摘要:
也可能是属性注入失败。属性注入失败的原因可能是注入字段的#{PARAME}中的PARAME名称与方法中的属性名称不同。建议在声明方法时添加@Param来命名属性,例如interduceNumber;但一般来说,这不是问题^^这也是我遇到的问题。错误代码如下:useseckill;选择秒杀id、名称、编号、开始时间、结束时间、从秒杀创建时间˂!检查并查询官方文件,并将其更改为正确的拼写。

记一下在 Spring + MyBatis 整合中遇到的问题以及解决方案

org.springframework.jdbc.BadSqlGrammarException

org.springframework.jdbc.BadSqlGrammarException: 
### Error querying database.  Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select seckill_id,name,number,start_time,end_time,create_time
        from secki' at line 2
### The error may exist in file [D:CodeJavaSecKill	argetclassesmapperSecKillDao.xml]
### The error may involve org.seckill.dao.SecKillDao.queryById-Inline
### The error occurred while setting parameters
### SQL: use seckill;         select seckill_id,name,number,start_time,end_time,create_time         from seckill.seckill         where seckill_id = ?
### Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select seckill_id,name,number,start_time,end_time,create_time
        from secki' at line 2
; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select seckill_id,name,number,start_time,end_time,create_time
        from secki' at line 2

这是我的报错信息,导致这个问题的原因有很多,但归根结底是 mapper 的 xml 中 SQL 语句的问题

  1. xml 中的 SQL 语句中的表名或者字段名含有 SQL 数据库的关键字,比如 ORDER , INSERT 之类的,这个时候要么改字段名(注意一般不要将字段名设置为关键字),要么把相应的字段名用 ` 引号括起来,表明这不是 SQL 关键字。
  2. 也有可能是属性注入失败的问题,关于属性注入失败的原因可能是注入字段的 #{PARANAME} 中的 PARANAME 名跟方法中的属性名不同,这里建议在声明方法时加上 @Param("name") 的方式命名属性,比如
int reduceNumber(@Param("secKillId") long secKillId,@Param("killTime") Date killTime);

​ 但一般来说都不是这个问题^^

  1. 这个情况也是我遇到的问题,出错的代码如下:

        <select   resultType="SecKill" parameterType="long">
            use seckill;
            select seckill_id,name,number,start_time,end_time,create_time
            from seckill	<!-- 我的数据库名和表名都是 seckill -->
            where seckill_id = #{secKillId}
        </select>
    

    我的 SQL 语句中有了分号,所以导致的 SQL 语法不对,解决办法是去掉分号,然后改写 SQL 语句为:

        <select   resultType="SecKill" parameterType="long">
    #         use seckill;
            select seckill_id,name,number,start_time,end_time,create_time
            from seckill.seckill
            where seckill_id = #{secKillId}
        </select>
    

    这也说明了在 MyBatis 的 mapper.xml 文件中 SQL 语句不要有分号。

java.lang.IllegalStateException: Failed to load ApplicationContext

错误信息给的很明确:加载应用上下文失败,也就是加载某个配置文件失败。具体是哪个配置文件就需要看详细的错误信息了

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [spring/spring-dao.xml]: Invocation of init method failed; nested exception is org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [mybatis-config.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: The setting useColumnabel is not known.  Make sure you spelled it correctly (case sensitive).

从这里可以看到是在初始化 sqlSessionFactory 的地方出了错,再往下面看就能看到具体的位置是 The setting useColumnabel is not known 也就是说拼写出错,这可能是由不熟悉配置文件的属性值或者马虎导致的。检查并查询官方文档更改为正确的拼写即可。

JDBC 驱动

这里顺带提一句,MySQL 数据库的 JDBC 驱动地址不再是 com.mysql.jdbc.Driver (虽然也能用),而是新的 com.mysql.cj.jdbc.Driver

org.mybatis.spring.MyBatisSystemException

详细信息:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: Connections could not be acquired from the underlying database!
### The error may exist in file [D:CodeJavaSecKill	argetclassesmapperSecKillDao.xml]
### The error may involve org.seckill.dao.SecKillDao.queryById
### The error occurred while executing a query
### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: Connections could not be acquired from the underlying database!

错误信息显示是获取数据库连接出错,这个错误出现的也有几种情况

  1. 顺着上面的错误信息再往下找能找到 Caused by: java.sql.SQLSyntaxErrorException: Unknown database 'seckil',可以发现数据库连接池 jdbcUrl 的属性值配置本身就有问题 ,比如少写了个啥字母之类的,这个不必多说检查出来,改正确就行了
  2. 数据库连接地址没问题,但是还是报了这个错,这是我遇到的问题。老规矩,继续往下找,错误信息越往后位置越精确!
Caused by: java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the 'serverTimezone' configuration property) to use a more specific time zone value if you want to utilize time zone support.

​ 然后发现这么个错,说服务器的时区配置未被认可或者超过了一个时区的数量限制,你必须配置 JDBC 或者 服务器的 serverTimezone 属性中的任何一个,本来的代码是 jdbcUrl = jdbc:mysql://localhost:3306/seckill 压根儿就没配置时区,报错。解决方案:

jdbcUrl = jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC 解决时区和中文乱码问题

java.lang.ClassNotFoundException: "com.mysql.cj.jdbc.Driver"

先上数据库参数配置代码

# 数据库驱动
driver = "com.mysql.cj.jdbc.Driver"
# 数据库连接
# jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC 解决时区和中文乱码问题
jdbcUrl = jdbc:mysql://localhost:3306/seckill?serverTimezone=UTC
# USER_NAME
user_name = root
# PWD
pwd = 201313

这个问题就是属性值写法的问题了,properties 里面的所有数据都是以键值对的方式进行存储的,value 值都不用双引号,并且后面不能跟空格,输完直接回车

java.lang.AbstractMethodError:Methodcom/mchange/v2/c3p0/impl/NewProxyResultSet.isClosed()Z is abstract

出现了这个错,本应被废弃的 isClose() 被调用了!解决方案就是不用就可以了,isClose() 方法在 c3p0 version 0.9.2.x 之后的版本就被废弃了,所以只需要将 maven 依赖的 c3p0 版本更换为 0.9.2.x 之后的版本就行,推荐 0.9.5.5 最新版。同时配置方式也发生了一些变化:

<!-- Old version setting  -->
<dependency>
	<groupId>c3p0</groupId>
	<artifactId>c3p0</artifactId>
	<version>0.9.1.2</version>
</dependency>

<!-- New version setting  -->
<dependency>
	<groupId>com.mchange</groupId>
	<artifactId>c3p0</artifactId>
	<version>0.9.5.5</version>
</dependency>

免责声明:文章转载自《记一下在 Spring + MyBatis 整合中遇到的问题以及解决方案》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Error:Unexpected lock protocol found in lock file. Expected 3, found 49.使用Advanced Installer 自动部署 Arcgis Engine Runtime 10.0下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

天气插件(vue)和风天气插件

&lt:“center”:“left”:&lt:v=2.0(函数(d){varc=d.createElement('link')c.rel='stylesheet'.href='http://t.zoukankan.com/https;v=1.4.0'vars=d.createElement;...

Debian 命令行方式配置网络

确保未在文件/etc/network/interfaces中手动配置网络,即应删除上述1和2中配置的内容。打开nmtui的图形界面并直接进行配置。当然,您也可以在此处设置无线连接。...

ThinkPHP

ThinkPHP的开发模式是define//Debug mode define//当运行模式控制器的操作系统找不到请求的方法时,它将定位__Empty()方法处理。使用此机制,我们可以统一处理用户请求的所有不存在的操作。模块分组大A函数和大R函数有什么区别?关联数组易于操作,信息量相对较大...

四、安装es-head插件

此时,es数据库可以通过弹性搜索头等第三方插件进行管理。在5.0版本之前,弹性搜索头插件可以以插件的形式直接安装。5.0版之后,需要支持nodejs环境,并且需要安装nodejs。这里使用源代码来安装npm,可以立即解压并使用。...

【646】灰度图array转为RGB三通道array

可以使用两种方法:numpy可以通过cv2.cvtColor函数自行实现。灰度图像可以转换为RGB的所谓灰度图像,分成三个通道,这意味着三个通道都是相同的信息,相当于相同维度信息的重复。主要通过numpy实现。阵列,其可以类似于广播的形式实现。...

图论介绍(Graph Theory)

G-v具有比G更多的连通分支,因此v被称为G的截断点G-e具有比G多的连通分支。定理:连通图G,其中e是桥e不属于G的任何环有顶点u,v,使得任何路径u-v都通过e连通图G;而w是存储在顶点u,v处的割点,使得任意路径u-v通过w定义:顶点之间的距离x-y:所有x-y路径的最小长度。...