前言
在日常开发中,批量操作数据库数据是常见场景,比如批量插入、批量修改、批量删除数据。MyBatis为批量操作数据提供了非常便利的方案。
当然,也可以在程序中自己拼接sql语句,在dao层传入该sql语句作为参数。要注意的是,采用这种方式时,不能使用 #
而是要使用 $
。
批量操作需要使用到比较复杂的标签,所以都在 xml
中实现。
需要注意的是,数据库配置中要将allowMultiQueries
置为true
,例如:
jdbc-url: jdbc:mysql://localhost:3306?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
1 批量insert
首先,看一下批量插入的xml
样板写法:
<insert id="addStudentBatch">
INSERT INTO mutest.student(id,name)
VALUES
<foreach collection="studentList" item="student" separator=",">
(#{student.id},#{student.name})
</foreach>
</insert>
上面实现了向 student表中批量插入student信息。
这个很简单,只要调用时,传入学生实体的list就可以了。
dao层:
int addStudentBatch(JSONArray studentList);
studentList的数据样板:
[
{
"id": 1,
"name": "爱因斯坦"
},
{
"id": 2,
"name": "法拉第"
},
{
"id": 1,
"name": "莱布尼兹"
}
]
1.1 根据一个主键批量插入
再看一个稍微复杂一些的场景,向年级表插入班级学生关联信息。表结构如下:
id | class_id | student_id |
---|---|---|
1 | 1 | 1 |
1 | 1 | 2 |
数据结构如下(JOSNObject student):
{
"id": 1,
"data": [
{
"classId": 1,
"studentId": 1
},
{
"classId": 1,
"studentId": 2
},{
"classId": 1,
"studentId": 3
}
]
}
与之对应的dao层(位于StudentDao.java中):
int addGradeStudentBatch(Long gradeId, JSONArray studentList);
service层:
Long gradeId = student.getLong("id");
JSONArray sutdnetList = student.getJSONArray("data");
studentDao.addGradeStudentBatch(gradeId,sutdnetList);
xml:
<insert id="addGradeStudentBatch">
INSERT INTO mutest.grade_student(gradeId,class_id,student_id)
VALUES
<foreach collection="studentList" item="student" separator=",">
(#{gradeId},#{student.classId},#{student.studentId})
</foreach>
</insert>
1.2 插入已存在数据自动更新
首先,已存在数据的判定由数据库通过唯一的主键或者索引实现的。
以上文向年级表插入班级学生关联信息为例,因为通过三个字段才能断定一条数据是否已存在,所以首先要将为这三个字段添加联合唯一索引:
alter table mutest.grade_student add unique index(id,class_id,student_id);
接下来只要在 xml 中略作修改即可:
<insert id="addGradeStudentBatch">
INSERT INTO mutest.grade_student(gradeId,class_id,student_id)
VALUES
<foreach collection="studentList" item="student" separator=",">
(#{gradeId},#{student.classId},#{student.studentId})
</foreach>
on duplicate key update
id = values(id),
class_id = values(class_id),
student_id = values(student_id)
</insert>
未完待续…