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

记一下在 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:\Code\Java\SecKill\target\classes\mapper\SecKillDao.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 id="queryById" 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 id="queryById" 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:\Code\Java\SecKill\target\classes\mapper\SecKillDao.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>
posted @ 2021-01-25 20:42  绯狱丸丶  阅读(2128)  评论(0编辑  收藏  举报