项目用的ORM框架是用springdatajpa来做的,有些批量数据操作的话,用这个效率太低,所以用mybatis自己写sql优化一下。
一般情况,我们肯定是先查询,有就修改,没有就添加,这样的话,单个操作还好,如果是大量数据的话,每次都需要先查后改(如果用springdatajpa的话,添加之前还得查一遍),太消耗资源了。
那么mysql有没有解决的办法呢?当然是有的,我查了一些资料,有两种办法,一种是使用使用replace into ,还有一种是on duplicate key update来解决,我先来演示一下这两种办法的区别。
首先创建一个表(我设置的username列唯一,用户名不可重复)
CREATE TABLE user_table( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(10) UNIQUE KEY, address VARCHAR(10) )
添加一条数据
INSERT INTO user_table (id,username,address) VALUE (NULL,'胡俊杰','北京')
目的:先查询数据是否存在,再修改(用一条语句实现),胡俊杰不在北京了,跑去黑龙江了
REPLACE INTO user_table(id,username,address) VALUE (NULL,'胡俊杰','黑龙江')
sql运行之后,显示2行收到影响。
之后再观察数据库的数据,姓名没变,地址变了,而且id也变了
说明replace into是先删除原来的,再新增。
这个显然是不好的,加入有个场景,这个表的id是一个表的外键,那么这样就会造成错误,所以我们引入方法2来解决。
方法二:
现在,把胡俊杰在安排回北京。sql语句如下
INSERT INTO user_table(id,username,address) VALUE (NULL,'胡俊杰','北京') ON DUPLICATE KEY UPDATE address = '北京'
INSERT INTO user_table(id,username,address) VALUE (NULL,'胡俊杰','北京') ON DUPLICATE KEY UPDATE address = VALUES(address) //这两种方法都可以,下面这个可以动态绑定传来的值
这次依旧是2行发生改变,我们再看数据库的数据
id没有改变,只改变了地址,这种办法是最实用的了。
接下来演示一下mybatis传入list批量修改该怎么做
@Insert("<script> insert into user_table (username,age,address)"+ " values <foreach collection ='users' item='item' index= 'index' separator =','> " + "(#{item.username},#{item.age},#{item.address}) </foreach >" + " ON DUPLICATE KEY UPDATE username = values(username), age = values(age) ,address = values(commaddr) </script>") void insert(@Param("users") List<User> users);
有不懂的可以留言给我,希望可以帮到你!!!