Dynamic SQL Foreach batch operation
foreword
Recently, I am studying the dynamic SQL of Mybatis, and I just learned the foreach element. In the past, the foreach element of Mybatis was often used in project development for batch operations. But sometimes it will be used incorrectly, so I sorted out and summarized the method of using foreach to add, delete, modify and check. Through this blog, the use of foreach will be more proficient and efficient.
prerequisite knowledge
Before learning Mybatis's foreach, we need to know how to write mysql batch statements. If you don’t know how to write mysql batch statements, then using the foreach element of Mybatis to perform batch operations is like a headless fly. The principle is very simple. Mybatis is a persistence layer framework. One of its functions is to splice SQL and hand it over to the database to execute SQL. So in mybatis, we need to splice batches of SQL statements successfully, so we will use how to write SQL for batch operations, and then how to combine it with the syntax of Mybatis.
Let's take a look at how to write and execute the results of batch CRUD SQL statements.
MySQL batch insert
INSERT INTO tar_course_content_info ( id, course_assembly_id, assembly_content, create_time, created_id, created_by, update_time, updated_id, updated_by, is_delete )
VALUES
(
301906655392563202,
301906577433034752,
'语文课',
'2022-07-12 19:13:44',
'EmE6TKu4okhu3qK5M1AGQ4',
'张三',
'2022-07-12 19:13:44',
'PWeDZyRPADjsdxCNWnSWxZ',
'王五',
0
),(
301906655392563203,
301906577433034752,
'数学课',
'2022-07-12 19:13:44',
'EmE6TKu4okhu3qK5M1AGQ4',
'张三',
'2022-07-12 19:13:44',
'PWeDZyRPADjsdxCNWnSWxZ',
'王五',
0
)
Execution result
The number of rows affected is 2 rows
MySQL batch query
Use the in keyword, the function of the in keyword is to query data within a certain range
SELECT * FROM tar_course_content_info WHERE is_delete = 0 AND ( created_by, course_assembly_id ) IN (( '张三', 305107474690605056 ),( '李四', 308290117053710337 ))
Results of the
MySQL batch modification
UPDATE tar_course_content_info SET created_by='王五' WHERE course_assembly_id IN( 305107474690605056,308290117053710337)
Execution result
The number of rows affected is 13 rows
MySQL batch delete
DELETE FROM tar_course_content_info where (created_by,id) in (('张三',301906655392563202),('张三',301906655392563203))
After the execution result
knows the batch operation of mysql sql statement, let's see how to use foreach in mybatis to perform batch operation in the actual project development process.
Use foreach in mybatis for batch operations
Attributes of the foreach tag
collection indicates the name of the iterative collection
item indicates the elements obtained in this iteration, if the collection is List, Set, or Array, it indicates the elements in it; if the collection is may, it indicates the value in the key-value, this parameter is required Select
open to indicate what the statement starts with, the commonly used left bracket "(", mybatis will splice the string before the sql statement wrapped in foreach, and only splice it once, this parameter is optional. close indicates what the statement
starts with Staying overnight, the commonly used right bracket ")", mybatis will splice the string after the SQL statement wrapped in foreach, and splice it only once. This parameter is optional.
separator mybatis will add the characters specified by the separate attribute to sql after each iteration, and this parameter is optional.
In List, Set and Array, index represents the current iteration position. In Map, index represents the key in key-value. This parameter is optional.
nullable indicates whether the collection can be null, the default is false, when set to true, the collection is null and no exception is thrown
batch insert
<!--批量插入-->
<insert id="insertBatch">
INSERT INTO tar_course_content_info (
id,
course_assembly_id,
assembly_content,
create_time,
created_id,
created_by,
update_time,
updated_id,
updated_by,
is_delete
) values
<foreach collection="list" item="item" separator="," >
( #{item.id},
#{item.courseAssemblyId},
#{item.assemblyContent},
#{item.createTime},
#{item.createdId},
#{item.createdBy},
#{item.updateTime},
#{item.updatedId},
#{item.updatedBy},
#{item.iselete}
)
</foreach>
</insert>
Results of the
batch query
<!--根据创建人和课程组件id进行批量查询 -->
<select id="queryAllCourseContentByCreatedByAndCourseAssemblyId" resultMap="courseContentMap">
SELECT *
FROM tar_course_content_info
WhERE
is_delete=0
and
(created_by, course_assembly_id)
in
<foreach collection="list" item="item" open="(" close=")" separator="," nullable="false">
(#{item.createdBy},#{item.courseAssemblyId})
</foreach>
</select>
Results of the
Batch Edit
The first case is when the values to be updated are the same:
<!-- 根据创建人和内容id进行批量假删除-->
<update id="updateAllByCreatedByAndContentId">
UPDATE tar_course_content_info SET is_delete=1 WHERE (created_by,id) IN
<foreach collection="list" item="item" open="(" close=")" separator="," >
(#{item.createdBy},#{item.id})
</foreach>
</update>
The second case of the execution result
is that the value to be updated is different:
it should be noted here that you need to add &allowMultiQueries=true
in the connection data . Function: you can execute batch processing and issue multiple SQL statements at the same time. That is, you can carry a semicolon after the SQL statement to implement multi-statement execution.
<!-- 根据课程组件id批量修改创建人姓名-->
<update id="updateAllCreatedByByCourseAssemblyId" >
<foreach collection="list" item="item" separator=";" >
UPDATE tar_course_content_info
SET
created_by = #{item.createdBy}
WHERE
course_assembly_id = #{item.courseAssemblyId}
</foreach>
</update>
Results of the
batch deletion
<!-- 根据创建人和内容id进行批量删除-->
<delete id="deleteAllByCreatedByAndContentId">
DELETE FROM tar_course_content_info where (created_by,id) in
<foreach collection="list" item="item" open="(" close=")" separator="," nullable="false" index="index">
(#{item.createdBy},#{item.id})
</foreach>
</delete>
Results of the
Summarize
- When learning a new thing, what I need to think about is the minimum necessary pre-knowledge that I must master, otherwise the efficiency will be extremely slow. Learning new things after mastering the minimum necessary knowledge will get twice the result with half the effort.
- Combining theory and practice. What is learned on paper is always shallow, and if you want to know this, you must do it yourself.