myBatis批量添加,修改和删除

1、批量添加元素session.insert(String string,Object o)

public void batchInsertStudent(){
	List<Student> ls = new ArrayList<Student>();
	for(int i = 5;i < 8;i++){
		Student student = new Student();
		student.setId(i);
		student.setName("maoyuanjun" + i);
		student.setSex("man" + i);
		student.setTel("tel" + i);
		student.setAddress("浙江省" + i);
		ls.add(student);
	}
	SqlSession session = SessionFactoryUtil.getSqlSessionFactory().openSession();
	session.insert("mybatisdemo.domain.Student.batchInsertStudent", ls);
	session.commit();
	session.close();
}

<insert id="batchInsertStudent" parameterType="java.util.List">
	INSERT INTO STUDENT (id,name,sex,tel,address)
	VALUES 
	<foreach collection="list" item="item" index="index" separator="," >
		(#{item.id},#{item.name},#{item.sex},#{item.tel},#{item.address})
	</foreach>
</insert>

2、批量修改session. insert (String string,Object o)
实例1:
public void batchUpdateStudent(){
	List<Integer> ls = new ArrayList<Integer>();
	for(int i = 2;i < 8;i++){
		ls.add(i);
	}
	SqlSession session = SessionFactoryUtil.getSqlSessionFactory().openSession();
	session.insert("mybatisdemo.domain.Student.batchUpdateStudent",ls);
	session.commit();
	session.close();
}
<update id="batchUpdateStudent" parameterType="java.util.List">
	UPDATE STUDENT SET name = "5566" WHERE id IN
	<foreach collection="list" item="item" index="index" open="(" separator="," close=")" >
		#{item}
	</foreach>
</update>

实例2:
public void batchUpdateStudentWithMap(){
	List<Integer> ls = new ArrayList<Integer>();
	for(int i = 2;i < 8;i++){
		ls.add(i);
	}
	Map<String,Object> map = new HashMap<String,Object>();
	map.put("idList", ls);
	map.put("name", "mmao789");
	SqlSession session = SessionFactoryUtil.getSqlSessionFactory().openSession();
	session.insert("mybatisdemo.domain.Student.batchUpdateStudentWithMap",map);
	session.commit();
	session.close();
}
<update id="batchUpdateStudentWithMap" parameterType="java.util.Map" >
	UPDATE STUDENT SET name = #{name} WHERE id IN 
	<foreach collection="idList" index="index" item="item" open="(" separator="," close=")"> 
		#{item} 
	</foreach>
</update>

3、批量删除session.delete(String string,Object o)
public void batchDeleteStudent(){
	List<Integer> ls = new ArrayList<Integer>();
	for(int i = 4;i < 8;i++){
		ls.add(i);
	}
	SqlSession session = SessionFactoryUtil.getSqlSessionFactory().openSession();
	session.delete("mybatisdemo.domain.Student.batchDeleteStudent",ls);
	session.commit();
	session.close();
}
<delete id="batchDeleteStudent" parameterType="java.util.List">
	DELETE FROM STUDENT WHERE id IN
	<foreach collection="list" index="index" item="item" open="(" separator="," close=")"> 
		#{item} 
	</foreach>
</delete>
<think> 我们在处理“批量删除分区”时,通常有两种理解: 1. 在数据库层面,分区(Partition)是一种数据管理方式,批量删除分区是指删除多个表分区(例如在MySQL中删除多个分区)。 2. 在业务层面,可能是指删除多条记录,而这些记录存储在不同的分区(比如按时间分区的表)中,或者是指按某个字段(如分区键)批量删除数据。 根据引用内容,特别是引用[1]提到“假装删除”(逻辑删除引用[3]中批量更新的例子,以及用户的问题“批量删除分区”,我们更倾向于第二种理解,即批量删除数据(可能是逻辑删除,也可能是物理删除),并且这些数据可能属于不同的分区。 但是,用户明确提到了“分区”,因此我们也要考虑数据库表分区的情况。在MyBatis中,对于分区的操作(如删除分区)通常是通过执行DDL语句(ALTER TABLE ... DROP PARTITION)来完成的。然而,批量删除分区是指一次删除多个分区,这需要动态生成SQL语句。 考虑到MyBatis主要用于DML(数据操作语言,如增删改查),而分区的创建删除属于DDL(数据定义语言),在MyBatis中执行DDL并不常见,但也是可行的。 因此,我们分两种情况讨论: 情况一:批量删除数据库表的分区(DDL操作) 例如,在MySQL中,我们可以这样删除分区: ALTER TABLE table_name DROP PARTITION partition_name1, partition_name2, ...; 在MyBatis中,我们可以这样写: <update id="dropPartitions"> ALTER TABLE ${tableName} DROP PARTITION <foreach item="partition" collection="partitions" separator=","> #{partition} </foreach> </update> 注意:这里使用`${tableName}`直接替换表名,因为表名分区名不能使用预编译的方式(#{}会加上引号,而分区名不需要引号)。但要注意SQL注入风险,确保参数来源可靠。 情况二:批量删除分区表中的数据(DML操作),可能是逻辑删除或物理删除 逻辑删除(使用@TableLogic注解,引用[1]): 批量更新状态为已删除。 物理删除: 使用DELETE语句,根据分区键或其他条件删除多个分区的数据。 例如,按分区键(如月份)批量删除数据(物理删除): <delete id="deleteByPartitions"> DELETE FROM table_name WHERE partition_key IN <foreach item="partition" collection="partitions" open="(" separator="," close=")"> #{partition} </foreach> </delete> 或者,逻辑删除(更新状态): <update id="logicDeleteByPartitions"> UPDATE table_name SET status = 'deleted' WHERE partition_key IN <foreach item="partition" collection="partitions" open="(" separator="," close=")"> #{partition} </foreach> </update> 引用[3]中给出了一个批量更新的例子,我们可以借鉴其动态生成IN条件的方法。 另外,引用[4]提到了批量插入时获取自增主键,但删除操作不需要。 引用[5]提到了事务,批量删除操作应该在事务中进行,确保操作的原子性。 综上所述,具体实现取决于用户的需求是删除分区(DDL)还是删除分区中的数据(DML)。下面我们分别给出两种情况的代码示例。 注意:在执行DDL删除分区时,要谨慎,因为删除分区会导致该分区所有数据被删除(且不可回滚,除非在事务中且数据库支持DDL事务,但MySQL的DDL会隐式提交事务)。 由于问题没有明确,我们提供两种可能的解决方案: 方案A:批量删除分区(DDL) Mapper接口: int dropPartitions(@Param("tableName") String tableName, @Param("partitions") List<String> partitions); XML映射文件: <update id="dropPartitions"> ALTER TABLE ${tableName} DROP PARTITION <foreach collection="partitions" item="partition" separator=","> #{partition} </foreach> </update> 方案B:批量删除分区数据(DML,物理删除) Mapper接口: int deleteByPartitionKeys(@Param("partitions") List<String> partitions); XML映射文件: <delete id="deleteByPartitionKeys"> DELETE FROM your_table WHERE partition_key IN <foreach collection="partitions" item="partition" open="(" separator="," close=")"> #{partition} </foreach> </delete> 方案C:批量删除分区数据(逻辑删除) Mapper接口: int logicDeleteByPartitionKeys(@Param("partitions") List<String> partitions); XML映射文件: <update id="logicDeleteByPartitionKeys"> UPDATE your_table SET status = 'deleted' WHERE partition_key IN <foreach collection="partitions" item="partition" open="(" separator="," close=")"> #{partition} </foreach> </update> 注意事项: 1. 在方案A中,由于是DDL操作,需要确保数据库用户有执行DDL的权限,并且要小心使用,避免误删。 2. 在方案BC中,如果数据量很大,需要考虑分批删除,避免一次删除过多数据导致事务过大或锁表。 3. 使用方案C(逻辑删除)时,查询语句需要排除已删除的数据(如加上`status != 'deleted'`),否则需要修改查询逻辑。 根据引用[2]中提到批量操作的最佳批次大小,如果数据量很大,即使是删除数据(DML)也应该分批次进行(比如每批删除500条)。但这里我们是按分区删除,分区数量一般不会特别大(比如一次删除12个分区),所以可以不用分批。但是,如果每个分区的数据量很大,那么删除整个分区的数据量就会很大,此时应该考虑使用分批删除(按分区键内的数据分批)而不是按分区批处理。 因此,如果用户的实际需求是删除分区内的数据(不是删除分区结构),并且每个分区的数据量很大,我们可能需要改为按主键或其他条件分批次删除。但这已经超出分区键的范畴,需要根据具体情况设计。 综上,请用户明确需求是删除分区结构(DDL)还是删除分区中的数据(DML),以及是物理删除还是逻辑删除。 最后,我们生成相关问题: </think> ### MyBatis实现批量删除分区的方法 在MyBatis中实现批量删除分区操作(包括物理删除逻辑删除)主要有以下三种方法,根据引用内容结合最佳实践进行说明: #### 1. **动态SQL实现分区批量物理删除** ```xml <delete id="batchDeletePartitions"> DELETE FROM partitioned_table WHERE partition_key IN <foreach item="partitionId" collection="partitionIds" open="(" separator="," close=")"> #{partitionId} </foreach> </delete> ``` - **原理**:使用`<foreach>`标签动态生成`IN`语句,适用于按分区键批量删除 - **注意事项**: - 分区键字段需预先定义(如时间分区`partition_date`或ID分区`partition_id`) - 建议每批次处理100-500个分区(参考引用[2]的批量操作优化建议) - 需开启事务保证原子性(引用[5]) #### 2. **逻辑删除实现分区数据隐藏** ```java // 实体类添加逻辑删除注解 public class PartitionData { @TableLogic(value = "0", delval = "1") // 引用[1] private Integer status; } ``` ```xml <update id="logicDeletePartitions"> UPDATE partitioned_table SET status = 1 WHERE partition_key IN <foreach ...></foreach> </update> ``` - **适用场景**: - 需要保留历史数据(如审计要求) - 支持数据恢复(引用[1]的"假装删除"说明) - **优势**:避免直接删除数据,可通过`status`字段过滤已删除分区 #### 3. **DDL模式直接删除物理分区** ```xml <update id="dropPartitions"> ALTER TABLE ${tableName} DROP PARTITION <foreach item="part" collection="partitions" separator=","> #{part} </foreach> </update> ``` - **适用数据库**:MySQL/Oracle等支持分区管理的DBMS - **示例参数**: ```java Map<String, Object> params = new HashMap<>(); params.put("tableName", "sales_data"); params.put("partitions", Arrays.asList("p2020", "p2021")); ``` ### 关键注意事项 1. **事务控制**(引用[5]) - 在Service层添加`@Transactional`注解 - 批量操作失败时自动回滚 2. **性能优化** - 监控JDBC内存使用(引用[2]) - 避免单次操作超过1000个分区 3. **安全防范** - 分区参数需白名单校验 - 禁止直接拼接`${partitionName}`(防SQL注入) > **分区选择建议**: > 业务数据清理使用**逻辑删除**(方案2),存储空间回收使用**物理删除**(方案1或3)。历史归档场景可结合Oracle分区交换(引用[2]扩展阅读)实现高效迁移。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值