<mapper namespace="com.example.YourMapper"> <insert id="batchInsertOrUpdate" parameterType="java.util.List"> <foreach collection="list" item="item" separator=";"> <if test="item.id != null"> <!-- 判断ID是否存在 --> SELECT COUNT(*) FROM your_table WHERE id = #{item.id} </if> <choose> <when test="_parameter[0] > 0"> <!-- 更新操作 --> UPDATE your_table SET column1 = #{item.column1}, column2 = #{item.column2} WHERE id = #{item.id} </when> <otherwise> <!-- 插入操作 --> INSERT INTO your_table (id, column1, column2) VALUES (#{item.id}, #{item.column1}, #{item.column2}) </otherwise> </choose> </foreach> </insert> </mapper>和mybatis-plus的saveOrUpdateBatch性能比较及如何选用
时间: 2024-04-16 22:26:04 AIGC 浏览: 184
`<insert>`标签和`saveOrUpdateBatch`是两种不同的方式来实现大批量数据操作。下面是它们的性能比较和如何选择的建议:
1. `<insert>`标签方式:
- 性能比较:使用`<insert>`标签进行大批量数据操作时,会根据每个数据的ID是否存在执行对应的更新或插入操作。这种方式对于数据量较小的情况下性能较好,因为它会逐条执行SQL语句。但是对于大批量数据操作来说,可能会有较多的数据库交互,性能可能较低。
- 选择建议:如果您的数据量不是特别大,并且对性能要求不高,可以考虑使用`<insert>`标签方式。
2. `saveOrUpdateBatch`方法:
- 性能比较:`saveOrUpdateBatch`是MyBatis-Plus提供的方法,它能够根据实体对象的ID自动判断执行插入或更新操作。这种方式可以减少数据库交互次数,提高性能,尤其在处理大批量数据时效果更好。
- 选择建议:如果您的数据量较大,并且对性能要求较高,推荐使用`saveOrUpdateBatch`方法。
综上所述,如果您的数据量较小且对性能要求不高,可以选择使用`<insert>`标签方式。如果您的数据量较大且对性能有较高的要求,可以考虑使用`saveOrUpdateBatch`方法。根据具体情况选择适合您的方式。
相关问题
<mapper namespace="com.example.YourMapper"> <insert id="batchInsertOrUpdate" parameterType="java.util.List"> <foreach collection="list" item="item" separator=";"> <if test="item.id != null"> <!-- 判断ID是否存在 --> SELECT COUNT(*) FROM your_table WHERE id = #{item.id} </if> <choose> <when test="_parameter[0] > 0"> <!-- 更新操作 --> UPDATE your_table SET column1 = #{item.column1}, column2 = #{item.column2} WHERE id = #{item.id} </when> <otherwise> <!-- 插入操作 --> INSERT INTO your_table (id, column1, column2) VALUES (#{item.id}, #{item.column1}, #{item.column2}) </otherwise> </choose> </foreach> </insert> </mapper>和mybatis-plus的saveOrUpdateBatch性能比较及如何选用,注:实体对象ID属于type = IdType.INPUT非自增
`<insert>`标签方式和MyBatis-Plus的`saveOrUpdateBatch`方法是两种不同的方式来实现大批量数据操作。下面是它们的性能比较和如何选择的建议:
1. `<insert>`标签方式:
- 性能比较:使用`<insert>`标签进行大批量数据操作时,会根据每个数据的ID是否存在执行对应的更新或插入操作。这种方式对于数据量较小的情况下性能较好,因为它会逐条执行SQL语句。但是对于大批量数据操作来说,可能会有较多的数据库交互,性能可能较低。
- 选择建议:如果您的数据量不是特别大,并且对性能要求不高,可以考虑使用`<insert>`标签方式。
2. `saveOrUpdateBatch`方法:
- 性能比较:`saveOrUpdateBatch`是MyBatis-Plus提供的方法,它能够根据实体对象的ID自动判断执行插入或更新操作。这种方式可以减少数据库交互次数,提高性能,尤其在处理大批量数据时效果更好。
- 选择建议:如果您的数据量较大,并且对性能要求较高,推荐使用`saveOrUpdateBatch`方法。
根据您提供的注释信息,实体对象ID属于`IdType.INPUT`非自增类型。在这种情况下,使用`<insert>`标签方式可能更适合,因为您需要在插入操作中显式指定ID的值。
综上所述,如果您的数据量较小且对性能要求不高,可以选择使用`<insert>`标签方式。如果您的数据量较大且对性能有较高的要求,并且实体对象ID属于`IdType.INPUT`非自增类型,可以考虑使用MyBatis-Plus的`saveOrUpdateBatch`方法。根据具体情况选择适合您的方式。
<mapper namespace="com.example.EnterpriseMapper"> <insert id="insertEnterpriseB" parameterType="java.util.List"> INSERT INTO enterprise_table (column1, column2) VALUES <foreach collection="list" item="item" separator=","> (#{item.property1}, #{item.property2}) </foreach> </insert> </mapper>
### 代码理解
在 MyBatis XML 配置文件中,批量插入 Java 列表数据到数据库表通常会使用 `<insert>` 标签结合 `<foreach>` 标签来实现。以下是对给出代码的详细理解:
```xml
<insert id="insertEnterpriseB" parameterType="java.util.List">
insert into `CTDEVELOPENGINE_REPORT_DB`.`BIP_QYBB_QYCWKB`
(
id,entity
)
values
<foreach collection="list" separator="," item="item" open="" close="" index="index">
(
#{item.id},
#{item.entity}
)
</foreach>
</insert>
```
- `<insert>` 标签:用于定义一个插入操作的 SQL 语句,`id` 属性是该插入操作的唯一标识符,`parameterType` 指定传入的参数类型为 `java.util.List`,意味着要传入一个列表对象。
- `insert into` 部分:指定要插入数据的目标数据库表 `CTDEVELOPENGINE_REPORT_DB`.`BIP_QYBB_QYCWKB` 以及要插入数据的列 `id` 和 `entity`。
- `<foreach>` 标签:用于遍历传入的列表。`collection="list"` 表示要遍历的集合名称为 `list`;`separator=","` 表示每次遍历后用逗号分隔;`item="item"` 表示将集合中的每个元素命名为 `item`;`open` 和 `close` 这里为空,若有值则分别表示在遍历开始和结束时添加的内容;`index` 表示当前遍历的索引。
- `#{item.id}` 和 `#{item.entity}`:是 MyBatis 的占位符,用于获取列表中每个元素(`item`)的 `id` 和 `entity` 属性值,并将其插入到对应的列中。
### 代码优化
#### 1. 增加事务支持
在批量插入时,为了保证数据的一致性,建议使用事务。可以在 Java 代码中使用 Spring 的 `@Transactional` 注解来实现。
#### 2. 处理异常
在 Java 代码中捕获并处理可能出现的 SQL 异常,避免程序崩溃。
#### 3. 动态列插入
如果插入的列不是固定的,可以使用动态 SQL 来实现。例如,使用 `<choose>`、`<when>` 和 `<otherwise>` 标签。
#### 4. 性能优化
对于大量数据的批量插入,可以考虑使用 JDBC 的批量插入功能,通过设置 `ExecutorType.BATCH` 来提高性能。示例代码如下:
```java
SqlSessionFactory sqlSessionFactory = ...;
try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
EnterpriseMapper mapper = session.getMapper(EnterpriseMapper.class);
List<Enterprise> enterprises = ...;
for (Enterprise enterprise : enterprises) {
mapper.insertEnterpriseB(enterprise);
}
session.commit();
} catch (Exception e) {
e.printStackTrace();
}
```
#### 5. 日志记录
可以在 XML 配置文件中添加日志记录,方便调试和监控。例如,在 MyBatis 的配置文件中配置日志输出。
### 优化后的 XML 示例
```xml
<insert id="insertEnterpriseB" parameterType="java.util.List">
insert into `CTDEVELOPENGINE_REPORT_DB`.`BIP_QYBB_QYCWKB`
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="list.size() > 0">
id,entity
</if>
</trim>
values
<foreach collection="list" separator="," item="item" open="" close="" index="index">
(
#{item.id},
#{item.entity}
)
</foreach>
</insert>
```
这里使用 `<trim>` 标签来动态处理列名,增强了代码的灵活性。
阅读全文
相关推荐















<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>班级列表</title>
</head>
<body>
班级列表
添加班级
班级名称
操作
<c:forEach var="cls" items="${classist}">
${cls.cname} (ID: ${cls.cid})
查看成绩
查看学生
</c:forEach>
</body>
</html><%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>班级列表</title>
</head>
<body>
班级列表
年级
操作
<c:forEach var="gls" items="${gradeList}">
${gls.term} (ID: ${gls.gid})
查看第一学生成绩
查看第二学生成绩
查看第三学生成绩
查看第四学生成绩
s
</c:forEach>
</body>
</html>package com.buka.controller;
import com.buka.po.Grade;
import com.buka.po.Student;
import com.buka.service.GradeService;
import com.buka.service.StuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
@Controller
public class GradeController {
@Autowired
GradeService gradeService;
@Autowired
StuService stuService;
@RequestMapping("/addGrade")
public ModelAndView addGrade(Grade grade,ModelAndView mv ){
gradeService.addGrade(grade);
Integer sid = grade.getSid();
List<Student>studentList = gradeService.getallS();
if (studentList == null) {
mv.setViewName("error.jsp");
mv.addObject("message", "找不到对应的学生");
return mv;
}
mv.addObject("stuList", studentList);
mv.setViewName("Student.jsp");
return mv;
}
@RequestMapping("/ShowGrade")
public ModelAndView showGrade(String term,ModelAndView mv ){
List<Grade> gradeList = gradeService.showGradeByTerm(term);
mv.addObject("gradeList", gradeList);
mv.setViewName("ShowGrade.jsp");
return mv;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.buka.dao.GradeDao">
<insert id="addGrade" parameterType="com.buka.po.Grade">
INSERT INTO grade (gid, term, sid, math, chinese, English)
VALUES (#{gid}, #{term}, #{sid}, #{math}, #{chinese}, #{English})
</insert>
<select id="selectGradeByTerm" parameterType="String" resultType="java.util.Map">
SELECT
s.name ,
g.math ,
g.chinese ,
g.English ,
g.term
FROM
grade g
INNER JOIN
student s ON g.sid = s.sid
WHERE
g.term = #{term}
ORDER BY
s.name
</select>
</mapper><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.buka.dao.GradeDao">
<insert id="addGrade" parameterType="com.buka.po.Grade">
INSERT INTO grade (gid, term, sid, math, chinese, English)
VALUES (#{gid}, #{term}, #{sid}, #{math}, #{chinese}, #{English})
</insert>
<select id="selectGradeByTerm" parameterType="String" resultType="java.util.Map">
SELECT
s.name ,
g.math ,
g.chinese ,
g.English ,
g.term
FROM
grade g
INNER JOIN
student s ON g.sid = s.sid
WHERE
g.term = #{term}
ORDER BY
s.name
</select>
</mapper>package com.buka.service;
import com.buka.dao.GradeDao;
import com.buka.dao.Studao;
import com.buka.po.Grade;
import com.buka.po.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class GradeService {
@Autowired
GradeDao gradeDao;
@Autowired
Studao studao;
public int addGrade(Grade grade){
return gradeDao.addGrade(grade);
}
public List<Student> getallS() {
return studao.getallS();
}
public List<Grade>showGradeByTerm(String term){
return gradeDao.showGradeByTerm(term);
}
}



<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>班级列表</title>
</head>
<body>
班级列表
添加班级
班级名称
操作
<c:forEach var="cls" items="${classist}">
${cls.cname} (ID: ${cls.cid})
<button>查看成绩</button>
查看学生
</c:forEach>
</body>
</html><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: asus
Date: 2025/9/14
Time: 21:19
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
学生列表
学生id
姓名
学号
班级id
<c:forEach var="sls" items="${stuList}">
${sls.sid} (ID: ${sls.sid})
${sls.name} (name: ${sls.name})
${sls.xuehao} (xuehao: ${sls.xuehao})
${sls.cid} (cid: ${sls.cid})
添加学生
修改学生
</c:forEach>
</body>
</html>
package com.buka.controller;
import com.buka.po.Student;
import com.buka.service.StuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
@Controller
public class StuController {
@Autowired
StuService stuService;
@RequestMapping("/addStu")
public ModelAndView addStu(Student student, ModelAndView mv) {
stuService.addStu(student);
mv.addObject("stu", student);
mv.setViewName("Student.jsp");
return mv;
}
@RequestMapping("/Student")
public ModelAndView selStu(Student student, ModelAndView mv) {
List<Student> studentList=stuService.selStu(new Student());
mv.addObject("stuList", studentList);
mv.setViewName("Student.jsp");
return mv;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.buka.dao.Studao">
<insert id="addStu" parameterType="com.buka.po.Student">
INSERT INTO student (sid, name, xuehao, cid)
VALUES (#{sid}, #{name}, #{xuehao}, #{cid})
</insert>
<update id="updateStu" parameterType="com.buka.po.Student">
</update>
<select id="selStu" resultType="com.buka.po.Student">
SELECT s.sid, s.name, s.xuehao, s.cid
FROM student s
INNER JOIN class c ON s.cid = c.cid
WHERE s.cid = #{cid}
</select>
</mapper>前面的班级部分已经完成,我想实现通过获取班级id查找班级里的人并呈现在Student.jsp
