mybatis batch 批量操作 方法封装

本文介绍了如何在MyBatis中进行批量操作的方法封装,包括确保Spring扫描和调用示例。在处理批量操作时,由于泛型擦除导致无法直接从List获取类型,因此选择了特定的参数传递方式。

mybatis batch 批量操作 方法封装

确保spring可以扫描到


@Component
public class MybatisBatchMethod {
    @Autowired
    SqlSessionTemplate sqlSessionTemplate;

    /**
     * 
     * @param mapperClass 进行增、改、删操作的mapper类
     * @param list  List批量数据
     * @param listItem List中的对象类型
     * @param methodName 调用的方法名
     * @param <T1>  mapper类泛型
     * @param <T2>  操作对象的类泛型
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * 
     */
    public <T1,T2> void mybatisBatch(Class<T1> mapperClass, List<T2> list, Class<T2> listItem, String methodName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //关闭session的自动提交
        SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
        //利用反射生成mapper对象
        T1 mapper = session.getMapper(mapperClass);
        //获取mapper对象的类
//		Class<?> mapperClass = mapperClassName.getClass();


        //获取mapper对象的方法
        Method mapperClassDeclaredMethod = mapperClass.getDeclaredMethod(methodName, listItem);

        try {
            int i=0;
            for (T2 item  : list) {
                //对mapper对象操作
                mapperClassDeclaredMethod.invoke(mapper,item);

                if (i % 1000 == 0 || i == list.size()-1) {
                    //手动每1000个一提交,提交后无法回滚
                    session.commit();
                    session.clearCache();//注意,如果没有这个动作,可能会导致内存崩溃。
                }
                i++;
            }
        }catch (Exception e) {
            //没有提交的数据可以回滚
            
            session.rollback();
            System.out.println(e);
            throw e;
        } finally{
            //关闭连接
            session.close();
        }
    }
}

调用举例

	@Autowired
	private EqparameterMapper eqparametermapper;
	@Autowired
	private MybatisBatchMethod mybatisBatchMethod;

	public void importEqparameter() throws Exception {
		//业务代码删除
		
		List<EqparameterEntity> eqList  = new ArrayList<>();
		//向list中插入数据
		//批量插入
		mybatisBatchMethod.mybatisBatch(EqparameterMapper.class,eqList,EqparameterEntity.class,"insertEqparameter");
		//参数1 要操作的mapper.class
		//2 操作的list
		//3 List<T> 的泛型
		//4 操作mapper的方法名

	}

参数3想直接从List中取的,但是泛型被擦除了取不到,如果取List元素的第一个类型又得验空,所以直接传了

<think>嗯,用户想了解MyBatis批量操作中如何实现ID回填。让我先回忆一下相关的知识点。首先,MyBatis在插入数据时,如果数据库表的主键是自增的,通常可以通过配置来获取生成的主键值。对于单个插入,这个应该比较简单,使用useGeneratedKeys和keyProperty就可以了。但批量插入的话,可能涉及到不同的配置方式,特别是需要处理多个记录的主键回填。 根据用户提供的引用内容,引用[1]提到了在XML配置中使用useGeneratedKeys和keyProperty,并且结合foreach标签进行批量插入。同时提到参数不需要加@Param注解,否则可能会有问题。引用[3]也强调了@Param注解的使用问题,如果参数名不一致会导致异常。而引用[2]中的示例代码展示了如何通过调用Mapper方法后,遍历对象列表获取主键ID,这说明MyBatis会自动将生成的主键回填到实体对象的对应属性中。 那用户的问题是批量操作中的ID回填,我需要整理出具体的步骤。首先,XML配置部分需要正确设置useGeneratedKeys,keyProperty,keyColumn。然后,在插入语句中使用foreach循环处理多个值。同时,需要注意参数名称的问题,确保在接口方法中参数名与XML中的collection属性一致,比如使用list作为参数名,或者在接口方法中使用@Param注解指定正确的名称。 另外,可能需要注意数据库的支持情况,比如MySQL支持批量插入时返回自增ID,但某些数据库可能需要其他处理方式。此外,批量插入的语法是否正确,比如VALUES后面是否用逗号分隔多个元组。 还需要考虑事务的问题,确保插入操作在同一个事务中,并且主键回填是在插入之后立即生效。例如,在示例代码中,插入后直接遍历users列表,每个user对象的id已经被赋值,这可能是在插入操作执行时,MyBatis自动处理了回填。 总结起来,实现步骤应该是:配置XML中的insert语句,正确使用foreach和主键回填属性,确保接口方法的参数名正确,避免@Param注解导致的参数名不匹配,然后通过调用Mapper方法执行批量插入,之后直接从实体对象中获取ID。 另外,用户可能遇到的常见问题包括参数名不匹配导致异常,比如引用[3]中的错误信息,所以需要提醒用户注意参数名的统一。还有是否需要开启事务,或者在插入后是否需要提交事务才能获取ID,可能需要根据具体数据库和配置来确定。 可能还需要提到不同数据库的兼容性,比如MySQL和PostgreSQL在处理批量插入返回主键时的差异,但根据引用中的示例,应该是针对MySQL的情况,因为它的语法支持多个VALUES条目。其他数据库可能需要不同的处理方式,比如使用JDBC的getGeneratedKeys方法,但MyBatis已经封装了这些细节,只要配置正确即可。 最后,需要确保返回的主键确实被正确赋值到实体对象的id字段,这需要在实体类中有对应的id属性和setter方法,否则无法正确回填。</think>### MyBatis批量插入实现ID回填的步骤 #### 1. XML配置核心参数 在Mapper XML文件中,需配置`useGeneratedKeys`、`keyProperty`和`keyColumn`: ```xml <insert id="insertUserBatch" useGeneratedKeys="true" keyProperty="id" keyColumn="id"> INSERT INTO t_user (name) VALUES <foreach item="item" collection="list" separator=","> (#{item.name}) </foreach> </insert> ``` - **`useGeneratedKeys`**: 启用数据库生成的主键回填功能[^1] - **`keyProperty`**: 指定实体类中接收主键的字段名 - **`keyColumn`**: 数据库表中主键列名(可省略,默认与keyProperty同名) #### 2. Mapper接口定义 接口参数需注意命名规范: ```java // 正确示例(参数名与XML的collection值匹配) int insertUserBatch(List<User> list); // 错误示例(@Param注解导致参数名冲突) int insertUserBatch(@Param("userList") List<User> list); // 会导致XML中找不到'list'参数[^3] ``` #### 3. 主键回填验证 执行插入后,可直接从对象集合中获取主键: ```java List<User> users = Arrays.asList( new User("Alice"), new User("Bob") ); userMapper.insertUserBatch(users); // 自动回填主键 users.forEach(user -> System.out.println("生成的主键ID:" + user.getId()) ); ``` #### 4. 注意事项 | 要点 | 说明 | |-----------------------|--------------------------------------------------------------------| | 数据库支持 | MySQL、SQL Server等支持批量插入返回主键,Oracle需特殊处理 | | 参数命名统一 | 接口参数名需与XML中`collection="list"`严格一致 | | 批量插入数量限制 | 建议单批次不超过1000条,避免数据库性能下降 | | 事务控制 | 确保在SqlSession中执行commit(),部分数据库需要事务提交后才生成ID[^2] |
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值