08MyBatis注解方式之@Insert

本文详细解析了MyBatis中@Insert注解的使用,包括无需返回主键和通过@Options指定返回自增主键的方法,同时介绍了@Update和@Delete操作。重点讲解了如何在RoleMapper接口中实现这些操作,并提供了相关工具和小结。

LD is tigger forever,CG are not brothers forever, throw the pot and shine forever.
Modesty is not false, solid is not naive, treacherous but not deceitful, stay with good people, and stay away from poor people.
talk is cheap, show others the code,Keep progress,make a better result.
Survive during the day and develop at night。

目录

概 述

MyBatis-08MyBatis注解方式之@Insert

@Insert注解本身很简单,需要注意的是如果需要返回主键的值,情况会稍微复杂一点,这种XML方式配置本质是一样的

不需要返回主键
1.RoleMapper接口增加接口方法

/**
     * 
     * 
     * @Title: insertSysRole
     * 
     * @Description: insertSysRole 不需要返回主键的情况
     * 
     * @param sysRole
     * @return
     * 
     * @return: int
     */
    @Insert({ "insert into sys_role(id, role_name, enabled, create_by, create_time) values(#{id}, #{roleName}, #{enabled}, #{createBy}, #{createTime, jdbcType=TIMESTAMP})" })
    int insertSysRole(SysRole sysRole);

返回自增主键

/**
     * 
     * 
     * @Title: insertSysRole2
     * 
     * @Description: insertSysRole2 返回自增主键的情况
     * 
     * @param sysRole
     * @return
     * 
     * @return: int
     */
    @Insert({ "insert into sys_role(role_name, enabled, create_by, create_time) values(#{roleName}, #{enabled}, #{createBy}, #{createTime, jdbcType=TIMESTAMP})" })
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insertSysRole2(SysRole sysRole);

返回自增主键

/**
     * 
     * 
     * @Title: insertSysRole2
     * 
     * @Description: insertSysRole2 返回自增主键的情况
     * 
     * @param sysRole
     * @return
     * 
     * @return: int
     */
    @Insert({ "insert into sys_role(role_name, enabled, create_by, create_time) values(#{roleName}, #{enabled}, #{createBy}, #{createTime, jdbcType=TIMESTAMP})" })
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insertSysRole2(SysRole sysRole);

MyBatis-09MyBatis注解方式之@Update/@Delete

  1. RoleMapper接口增加接口方法
    2.在这里插入代码片
    /**
     * 
     * 
     * @Title: updateSysRoleById
     * 
     * @Description: updateSysRoleById
     * 
     * @param sysRole
     * @return
     * 
     * @return: int
     */
    @Update({ "update sys_role set role_name = #{roleName},enabled = #{enabled},create_by = #{createBy},create_time = #{createTime, jdbcType=TIMESTAMP} where id = #{id}" })
    int updateSysRoleById(SysRole sysRole);

@Delete 方法:

/**
     * 
     * 
     * @Title: deleteSysRoleById
     * 
     * @Description: deleteSysRoleById
     * 
     * @param id
     * @return
     * 
     * @return: int
     */
    @Delete("delete from sys_role where id = #{id}")
    int deleteSysRoleById(Long id);

总结:

相关工具如下:

分析:

小结:

主要讲述了接下来@Insert详解,请大家指正~

参考资料和推荐阅读

1.链接: 参考资料.

<think> 我们参考站内引用信息,特别是引用[1]和引用[3],它们都提到了使用@Insert注解进行批量插入的方法。 引用[1]中展示了一个自定义批量插入的SQL,使用<foreach>标签来遍历集合,并在values后面构造多个插入值。 引用[3]则提到了一个常见的错误,即在@Insert注解中使用集合时参数绑定问题。 因此,我们可以总结出使用@Insert注解实现批量插入的步骤: 1. 在Mapper接口中定义一个方法,参数为List集合,并使用@Param注解指定参数名(在XML或注解SQL中引用)。 2. 在@Insert注解中编写SQL语句,使用<script>标签包裹,以便使用动态SQL(如foreach)。 3. 在values后面使用foreach标签遍历集合,生成多个插入值。 注意点: - 在注解中使用动态SQL,需要将SQL用<script>包裹,这样MyBatis才会解析其中的动态标签。 - foreach标签的collection属性需要和@Param注解指定的参数名一致。 - foreach标签中的item属性指定集合中每个元素的别名,然后在#{}中使用这个别名来访问属性。 下面是一个示例代码,假设我们有一个实体类MaterialData,对应的表是rpt_material_hour,并且我们想要批量插入一个List<MaterialData>。 但是,根据引用[1]和引用[2],我们需要注意主键生成策略。如果我们的主键是使用MyBatis-Plus的雪花算法自动生成,那么在批量插入时,我们需要确保在插入前为每个实体的主键赋值。在引用[1]中,作者提到因为自定义批处理SQL导致雪花算法失效,无法自动生成id。因此,我们需要在Java代码中手动为每个实体生成主键。 解决方法: 1. 在实体类的主键字段上使用@TableId(type = IdType.ASSIGN_ID),这样MyBatis-Plus在插入前会自动生成主键(但这是在MyBatis-Plus的Service方法中才会生效)。而如果我们使用自定义的@Insert注解,则不会触发主键生成。 2. 因此,我们需要在调用Mapper的批量插入方法之前,遍历列表,为每个实体设置主键。可以使用MyBatis-Plus的IdWorker(3.3.0之前)或者IdentifierGenerator(3.3.0之后)来生成主键。 例如,在3.3.0之后,我们可以注入IdentifierGenerator,然后使用其nextId方法生成主键。或者,我们也可以使用IdWorker.getId()(但3.4.0之后IdWorker被弃用)。 考虑到引用[2]中提到的错误,我们还要确保数据库表的主键是自增的(如果使用数据库自增策略)或者我们使用程序生成主键(如雪花算法)并设置到实体上。 因此,我们分两步: 第一步:为每个实体生成主键(如果使用雪花算法) 第二步:使用@Insert注解编写批量插入SQL 具体实现: Mapper接口方法: ```java @Insert("<script>" + "INSERT INTO rpt_material_hour (id, sample_time, rounding_time, cur_month, machine_no, data_code, data_value, create_user, create_time, update_user, update_time) VALUES " + "<foreach collection='materialDataList' item='item' separator=','>" + " (#{item.id}, #{item.sampleTime}, #{item.roundingTime}, #{item.curMonth}, #{item.machineNo}, #{item.dataCode}, #{item.dataValue}, " + " #{item.createUser}, #{item.createTime}, #{item.updateUser}, #{item.updateTime})" + "</foreach>" + "</script>") void insertBatch(@Param("materialDataList") List<MaterialData> materialDataList); ``` 在调用insertBatch方法之前,我们需要为materialDataList中的每个MaterialData对象设置id(如果主键由程序生成)。例如: ```java // 假设我们使用MyBatis-Plus的IdentifierGenerator(需要注入) // 或者我们可以使用IdWorker(但已弃用)或者使用配置的KeyGenerator // 这里我们使用IdentifierGenerator(需要Spring容器) // 在Service中 @Autowired private IdentifierGenerator identifierGenerator; public void batchInsert(List<MaterialData> materialDataList) { for (MaterialData materialData : materialDataList) { // 如果materialData的id为null,则生成id if (materialData.getId() == null) { // 使用IdentifierGenerator生成Long类型的ID(雪花算法) materialData.setId(identifierGenerator.nextId(materialData)); } // 设置其他公共字段,如createTime等 } materialDataMapper.insertBatch(materialDataList); } ``` 注意:如果数据库表主键是自增的(AUTO_INCREMENT),那么我们应该在实体类主键字段上使用@TableId(type = IdType.AUTO),并且在插入时不需要设置主键值。但是,在批量插入的SQL中,我们通常需要将主键列排除(如果数据库自增)。然而,在MyBatis-Plus中,如果使用自定义SQL,那么自增主键的生成完全由数据库完成,我们不需要插入主键值。所以,在SQL中应该去掉id列,同时values中也不插入id值。 因此,如果主键是自增的,我们的SQL可以改为: ```java @Insert("<script>" + "INSERT INTO rpt_material_hour (sample_time, rounding_time, cur_month, machine_no, data_code, data_value, create_user, create_time, update_user, update_time) VALUES " + "<foreach collection='materialDataList' item='item' separator=','>" + " (#{item.sampleTime}, #{item.roundingTime}, #{item.curMonth}, #{item.machineNo}, #{item.dataCode}, #{item.dataValue}, " + " #{item.createUser}, #{item.createTime}, #{item.updateUser}, #{item.updateTime})" + "</foreach>" + "</script>") void insertBatch(@Param("materialDataList") List<MaterialData> materialDataList); ``` 但是,在自增主键的情况下,我们可能希望获取到生成的主键值,但批量插入时MyBatis不支持返回多个主键。所以,如果不需要立即获取主键,可以这样使用。 另外,引用[3]中提到了一个错误:Parameter 'item' not found。这个错误通常是因为在foreach标签中使用了错误的参数名。在@Param("materialDataList")中我们指定了参数名为"materialDataList",然后在foreach的collection属性中使用'materialDataList'。在foreach内部,我们使用item属性指定了每个元素的别名为'item',然后在#{}中应该使用'item.属性名'。 所以,请确保在SQL中正确引用了参数。 总结: 使用@Insert注解进行批量插入,关键在于使用<script>和<foreach>动态标签构造插入多个值的SQL语句。同时,需要注意主键生成策略,在自定义SQL中,MyBatis-Plus的自动主键生成不会生效,需要手动设置主键值(如果使用程序生成主键)或者在SQL中排除主键列(如果使用数据库自增)。 下面我们给出两种情况的完整示例: 情况1:使用程序生成主键(雪花算法) 实体类: ```java public class MaterialData { @TableId(type = IdType.ASSIGN_ID) // 由程序分配ID(雪花算法) private Long id; // 其他字段... } ``` Mapper接口: ```java public interface MaterialDataMapper extends BaseMapper<MaterialData> { @Insert("<script>" + "INSERT INTO rpt_material_hour (id, sample_time, rounding_time, cur_month, machine_no, data_code, data_value, create_user, create_time, update_user, update_time) VALUES " + "<foreach collection='materialDataList' item='item' separator=','>" + " (#{item.id}, #{item.sampleTime}, #{item.roundingTime}, #{item.curMonth}, #{item.machineNo}, #{item.dataCode}, #{item.dataValue}, " + " #{item.createUser}, #{item.createTime}, #{item.updateUser}, #{item.updateTime})" + "</foreach>" + "</script>") void insertBatch(@Param("materialDataList") List<MaterialData> materialDataList); } ``` Service层调用: ```java @Service public class MaterialDataServiceImpl implements MaterialDataService { @Autowired private MaterialDataMapper materialDataMapper; @Autowired private IdentifierGenerator identifierGenerator; @Override public void insertBatchMaterialData(List<MaterialData> materialDataList) { // 为每个实体设置主键 for (MaterialData materialData : materialDataList) { if (materialData.getId() == null) { materialData.setId(identifierGenerator.nextId(materialData)); } // 设置其他公共字段,如创建时间等 materialData.setCreateTime(LocalDateTime.now()); materialData.setUpdateTime(LocalDateTime.now()); } materialDataMapper.insertBatch(materialDataList); } } ``` 情况2:使用数据库自增主键 实体类: ```java public class MaterialData { @TableId(type = IdType.AUTO) // 自增主键 private Long id; // 其他字段... } ``` Mapper接口: ```java public interface MaterialDataMapper extends BaseMapper<MaterialData> { @Insert("<script>" + "INSERT INTO rpt_material_hour (sample_time, rounding_time, cur_month, machine_no, data_code, data_value, create_user, create_time, update_user, update_time) VALUES " + "<foreach collection='materialDataList' item='item' separator=','>" + " (#{item.sampleTime}, #{item.roundingTime}, #{item.curMonth}, #{item.machineNo}, #{item.dataCode}, #{item.dataValue}, " + " #{item.createUser}, #{item.createTime}, #{item.updateUser}, #{item.updateTime})" + "</foreach>" + "</script>") void insertBatch(@Param("materialDataList") List<MaterialData> materialDataList); } ``` 在自增主键的情况下,我们不需要在插入前设置id,插入后MyBatis也不会回填多个主键值(批量插入不支持回填)。如果需要回填,可能需要使用其他方式(如单条插入并回填,但性能较差)。 最后,注意SQL注入问题:这里使用的是#{},是预编译的,所以是安全的。 希望以上内容能帮助您实现MyBatis-Plus使用@Insert注解的批量插入。 </think> 以下是MyBatis-Plus使用`@Insert`注解实现批量插入的完整方法和注意事项: ### 方法实现 在Mapper接口中使用`@Insert`注解结合动态SQL实现批量插入: ```java @Insert("<script>" + "INSERT INTO your_table (id, field1, field2) VALUES " + "<foreach collection='list' item='item' separator=','>" + " (#{item.id}, #{item.field1}, #{item.field2})" + "</foreach>" + "</script>") void insertBatch(@Param("list") List<YourEntity> list); ``` ### 关键说明 1. **动态SQL标签** - `<script>`:包裹整个SQL语句,启用动态SQL解析 - `<foreach>`:遍历集合,`collection`指定参数名,`item`定义元素别名 - `separator=","`:生成逗号分隔的VALUES列表 2. **主键处理(雪花ID问题)** 自定义SQL时**不会触发**MyBatis-Plus的自动ID生成,需手动赋值: ```java // 在Service层为每个实体生成ID list.forEach(item -> { if(item.getId() == null) { item.setId(IdWorker.getId()); // 雪花ID生成 } }); mapper.insertBatch(list); ``` 3. **参数绑定** 必须使用`@Param("list")`明确参数名,避免报错: > 错误示例:`Parameter 'item' not found`[^3] 4. **字段匹配** 确保`#{}`中的属性名与实体类字段**严格匹配**(驼峰命名自动转换) ### 完整示例 ```java // Entity @Data public class User { @TableId(type = IdType.ASSIGN_ID) // 雪花ID策略 private Long id; private String name; private Integer age; } // Mapper public interface UserMapper extends BaseMapper<User> { @Insert("<script>" + "INSERT INTO user (id, name, age) VALUES " + "<foreach collection='users' item='u' separator=','>" + " (#{u.id}, #{u.name}, #{u.age})" + "</foreach>" + "</script>") void batchInsert(@Param("users") List<User> users); } // Service @Service public class UserService { @Autowired private UserMapper userMapper; public void saveBatch(List<User> users) { users.forEach(u -> { if(u.getId() == null) { u.setId(IdWorker.getId()); // 手动生成ID } }); userMapper.batchInsert(users); } } ``` ### 注意事项 1. **性能优化** 批量数据建议分批次插入(每批500-1000条),避免SQL过长 2. **主键冲突** 确保手动生成的ID在分布式系统中全局唯一 3. **事务管理** 在Service层添加`@Transactional`保证原子性 4. **字段过滤** 若数据库有默认值字段,可省略对应`#{}`表达式 > **提示**:MyBatis-Plus原生`saveBatch()`方法已优化批量插入,优先考虑使用内置方法[^1][^2]。仅当需要特殊SQL逻辑时才用此方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迅捷的软件产品制作专家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值