Jdbctemplate操作mysql临时表

在数据库迁移的过程中可谓遇到了很多的坑,在原本的sqlserver中使用的with语句将产生表,而在改写到mysql时使用的是temporary表,在直接对这一大段sql进行执行时直接报错。sql如下:

DROP TABLE
IF
	EXISTS cte;
CREATE TEMPORARY TABLE cte AS (
SELECT
		 da.*
	FROM
		domains_map da,
		( SELECT @DATAS := getToId(?) ) x 
	WHERE
		find_in_set (da.ToId, @DATAS ) 
	);
DROP TABLE
IF
	EXISTS FromIds;
CREATE TEMPORARY TABLE FromIds AS(SELECT ToId FROM cte);

SELECT FromId FROM cte WHERE FromId NOT IN (SELECT * from FromIds)

而在java程序中使用的时候直接通过queryFor()语句进行操作时,报错:

Can not issue data manipulation statements with executeQuery() 经过查找原因说的query for()的语句底层代码都是走的query()而对于create,insert,update delete 操作底层均走executeUpdate()。想到这里大致知道了这个就是不能执行创建语句,所以把所有的语句给拆分起来进行分布执行。拆分下来走自己重写doInConnection方法执行如下图:

java业务中的临时表 java创建mysql临时表_jdbc


在这个拆分执行时却会报错:会出现你刚创建的临时表为什么就查询不到了呢。 xxxtable not exist ,但是这我已经不是在一个connection中了吗,但是通过调试后发现这还不是在同一个connection中。这个经过查询是因为connection不是同一个导致的,也就是说在当执行一个execute()方法后jdbctemplate会把当前的操作进行提交,这时的connection就不是同一个了,而mysql的临时表的操作必须在同一个会话中才可以使用,当会话结束后就会失效。所以会报错就找不到这个临时表,这时行到的解决办法有两种1.添加事务注解,锁定当前会话最后一次性提交。2.让jdbctemplate同时执行多条语句。

对于1.的时候添加事务了当前操作的sql会在最后一次性的提交让数据库执行,这个自然而然的是一个可行的办法。可以采纳

对于2.的时候在连接时加入的对象参数为allowMultiQueries=true 但是加入后无效。

所以最终采用加事务注解的形式和把sql进行拆分执行,执行到最后一个sql时通过查询语句进行查询出来。通过拆分sql后。加入事务注解。以后只要是包含临时表的必须加入事务,不加事务会报没有临时表的异常。