前言
在日常開發中,批量操作數據庫數據是常見場景,比如批量插入、批量修改、批量刪除數據。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>
未完待續…