ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException——Mybatis批量处理错误处理

2019-09-09 17:02:51  阅读:299  来源: 互联网

标签:语句 jdbc jdbc4 批量 sql project SQL Mybatis Cause


在进行批量处理的时候,在后台发现报错,日志部分如下:

bad SQL grammar []; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Syntax error:

出现了badSQlgrammar错误,在(某一个表中)出现了delete错误。
由于在批量操作的时候,我们是通过生成多条SQL语句,然后进行拼接,再用Mybatis进行处理,但是遇到了问题。

<update id="setWeiboEmotionByList" parameterType="java.util.List">
        <foreach collection="list" item="item" open="" close="" separator=";">
            UPDATE weibo_content
            SET
                EMOTION = #{item.emotion}
            WHERE
                WEIBO_ID = #{item.weibo_id}
        </foreach>
    </update>

类似上面的操作方式,使用foreach来对list中的语句进行拼接和遍历最后多条SQL语句进行执行
在这里插入图片描述
由上图所示,但是却触发了JDBC4 的MySQLSyntaxErrorException,经过资料查询,观察MySQLSyntaxErrorException实例:

public void create(Project project) throws IllegalArgumentException, DAOException {
	if (project.getProjectId() != 0) {
		throw new IllegalArgumentException("Project is already created, the project ID is not null.");
	}

	Object[] values = { project.getProjectNumber(), project.getProjectName(), 
			project.getActivity(), project.getPerNumber(),
			toSqlDate(project.getDate()), project.getTime()}; 
		
	try (Connection connection = daoFactory.getConnection();
		PreparedStatement statement = prepareStatement(connection, 
			SQL_INSERT_PROJECT, true, values);) {
		int affectedRows = statement.executeUpdate();
		if (affectedRows == 0) {
			throw new DAOException("Creating user failed, no rows affected.");
		}
		try (ResultSet generatedKeys = statement.getGeneratedKeys()) {
			if (generatedKeys.next()) {
				project.setProjectId(generatedKeys.getLong(1));
			} else {
				throw new DAOException("Creating user failed, no generated key obtained.");
			}
		}
	} catch (SQLException e) {
		throw new DAOException(e);
	}
}

可以看到,出错原因有大概如下原因:

  • 1、其中SQL语句有的出错导致。
  • 2、Mybatis中字段部分与SQl关键字冲突。
  • 3、由于是多条执行(delete xxx……;delete xxx……; delete xxx……;),可能Mybatis不能支持这种批量方式。
  • 4、对于参数传值的时候,使用"#{}“和使用”${}"传值时,会出现不同的问题。**

对这四种错误进行排查:

  • 通过在Navicat中执行每条SQL,发现并无报错,应该不是SQL语句有问题。
  • 在其他单条SQL语句处理和批量查找、批量更新都发现没有此问题。
  • Mybatis是默认不支持这种操作的,但是我们可以通过在mysql配置链接里加上allowMultiQueries参数并置为true。但是还是报同样的错误(也可能和服务器端的配置有关,需要进一步查看)。
  • 很明显全部使用的"#{}",当使用$时是默认无防注入的。其中#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
    sql{}表示拼接sql串,通过表示拼接sql串,通过{}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换,$ {}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,$ {}括号中只能是value。

究其原因(一般原因):

经过查找资料,发现大多数问题都是处在第三条上——对与adllowMultiQueries参数没有置为true,
但是,我们使用的是OceanBase的数据库,虽然理论上支持MySQL中的所有语句,但是在解决问题的两天后,我在阿里巴巴官方文档中看到了:

在这里插入图片描述
确实,这个问题解决了,但是下一个问题出现了:如何换一种方案呢

经过大佬们的商议,决定根据偏移量来进行Mybatis分段的批量操作,

后面继续谈。

标签:语句,jdbc,jdbc4,批量,sql,project,SQL,Mybatis,Cause
来源: https://blog.csdn.net/qq_38892842/article/details/100600105

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有