Java + Spring Boot + Mybatis 插入数据后,获取自增 id 的示例代码

示例代码1:

特点:

1、单个参数

2、使用 useGeneratedKeys="true" keyProperty="id"

3、通过实体类的 id 接收自增 id 的值(Integer)

BranchWarehouseApplyServiceImpl.java
    // 生成分仓物资申领单(试剂耗材)
    @Override
    public void generateForReagent(List<ReagentOptionVO> reagentOptionList) {
        // 获取当前日期
        LocalDate today = LocalDate.now();

        // 提取年、月、日
        int year = today.getYear();          // 年(2025)
        int month = today.getMonthValue();   // 月(1-12)
        int day = today.getDayOfMonth();     // 日(1-31)

        // 获取分仓物资申领编号
        HashMap<String, Object> map = new HashMap<>();
        map.put("year", year);
        map.put("month", month);
        map.put("day", day);
        // 执行存储过程
        branchWarehouseApplyMapper.generateNo(map);
        // 获取输出参数 orderNo 的值
        String orderNo = map.get("orderNo").toString();
        log.info("生成分仓物资申领编号 = {}", orderNo);

        if (!orderNo.isEmpty()) {
            // 获取用户名(账号)
            String userName = PublicUtils.getUserName();
            // 通过用户名(账号),获取其所属部门
            Department department = departmentMapper.selectByUserName(userName);

            // 插入分仓物资申领主项数据
            BranchWarehouseApplyMaster applyMaster = new BranchWarehouseApplyMaster();
            applyMaster.setWarehouseId(1);
            applyMaster.setOrderNo(orderNo);
            applyMaster.setApplyTime(LocalDateTime.now());
            applyMaster.setApplyDept(department.getDeptId());
            applyMaster.setApplyOperator(userName);
            applyMaster.setStage(0);
            branchWarehouseApplyMapper.insertMaster(applyMaster);
            // 返回自增 id 的值
            Integer masterId = applyMaster.getId();

            // 插入分仓物资申领明细数据
            List<BranchWarehouseApplyDetail> applyDetailList = new ArrayList<>();
            reagentOptionList.forEach(item -> {
                BranchWarehouseApplyDetail applyDetail = new BranchWarehouseApplyDetail();
                applyDetail.setWarehouseId(1);
                applyDetail.setMasterId(masterId);
                applyDetail.setMaterialId(item.getId());
                applyDetail.setAmount(item.getApplyAmount());
                applyDetail.setStage(0);
                applyDetailList.add(applyDetail);
            });
            // 集合不为空
            if (!applyDetailList.isEmpty()) {
                // 批处理,拆分数据,满50条,执行批量插入
                List<List<BranchWarehouseApplyDetail>> lists = (List<List<BranchWarehouseApplyDetail>>)PublicUtils.splitList(applyDetailList, 50);
                for (List<BranchWarehouseApplyDetail> list: lists) {
                    branchWarehouseApplyMapper.insertDetail(list);
                }
            }
        }
    }
BranchWarehouseApplyMapper.java
    // 增加分仓物资申领主项
    void insertMaster(BranchWarehouseApplyMaster applyMaster);
BranchWarehouseApplyMapper.xml
    <!-- 增加分仓物资申领主项 -->
    <insert id="insertMaster" useGeneratedKeys="true" keyProperty="id">
        insert into BranchWarehouseApplyMaster (
        warehouse_id, order_no, apply_time, apply_dept, apply_operator, purpose, stage, remark
        ) values (
        #{warehouseId}, #{orderNo}, #{applyTime}, #{applyDept}, #{applyOperator}, #{purpose}, #{stage}, #{remark}
        )
    </insert>

示例代码2:

特点:

1、单个参数

2、使用 useGeneratedKeys="false"、selectKey

3、通过实体类的 id 接收自增 id 的值(Integer),定义 resultType="java.lang.Integer"

4、useGeneratedKeys="false"、<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">、select @@IDENTITY as id

ApplySampleServiceImpl.java
    // 增加受理样品,增加NULL值的样品信息,只有outerApplyId、applyId、sampleNo,并返回自增的 id,若样品已经存在,返回 0
    @Override
    public Integer addNullValue(ApplySample applySample) {
        // 通过applyId、sampleNo查询样品
        ApplySample sample = applySampleMapper.selectByApplyIdAndSampleNo(applySample.getApplyId(), applySample.getSampleNo());
        // 样品不存在
        if (sample == null) {
            // 增加样品,并返回自增的 id
            applySampleMapper.insertNullValue(applySample);
            // 返回自增的 id
            return applySample.getId();
        } else {
            // 样品已经存在,返回 0
            return 0;
        }
    }
ApplySampleMapper.java
    // 增加受理样品,增加NULL值的样品信息,只有outerApplyId和applyId,并返回自增的 id
    void insertNullValue(ApplySample applySample);
ApplySampleMapper.xml
    <!--增加受理样品,增加NULL值的样品信息,只有outerApplyId、applyId、sampleNo,并返回自增 id 的值-->
    <!--useGeneratedKeys 和 keyProperty 是 MyBatis 中用于处理自增主键的两个重要属性-->
    <!--useGeneratedKeys 属性表示是否使用自动生成的主键。如果该属性为 true,则表示使用数据库自动生成的主键-->
    <!--如果该属性为 false,则表示不使用自动生成的主键。默认值为 false。-->
    <!--keyProperty 属性表示实体类的属性名,用于接收自动生成的主键值。在执行插入操作时,如果使用了自动生成的主键,-->
    <!--那么数据库会为新插入的记录自动生成一个主键值,这个值会被保存到 keyProperty 属性指定的实体类属性中。-->

    <!--selectKey 标签中指定自动生成主键的方式和接收主键值的实体类属性,resultType的数据类型需要与实体类中的keyProperty对应的属性一致-->
    <!--useGeneratedKeys 属性被设置为 false,表示不使用自动生成主键的方式。-->
    <!--而是在 selectkey 标签中使用 @@IDENTITY 函数获取自动生成的主键值,并将其设置到实体类的 id 属性中。-->
    <!--需要注意的是,在 SQL Server中,@@IDENTITY 函数用于获取最近插入的标识列的值,因此只能在插入后(order="AFTER")使用。-->

    <!--这里 keyProperty="id",id 的数据类型是 Integer,所以 resultType 就需要设置为 java.lang.Integer-->
    <insert id="insertNullValue" parameterType="com.weiyu.pojo.ApplySample" useGeneratedKeys="false">
        insert into ApplySampleInfoC(as_OuterApplyId, as_ApplyID, as_SampleNo)
        values(#{outerApplyId}, #{applyId}, #{sampleNo})
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            select @@IDENTITY as id
        </selectKey>
    </insert>

示例代码3:

特点:

1、多个参数,Mapper中使用@Param

2、使用 useGeneratedKeys="true" keyProperty="idHolder.generatedId",多个参数的情况下,generatedId前面需要@Param的参数名做为前缀

3、通过 Map 接收自增 id 的值(Integer),Map结构类型为<String, Object>,再通过安全转换为Integer

4、useGeneratedKeys="true" keyProperty="idHolder.generatedId"


ReagentServiceImpl.java

    // 生成试剂
    @Override
    public List<Reagent> generate(List<Integer> idList) {
        if (!idList.isEmpty()) {
            List<Integer> reagentIdList = new ArrayList<>();
            idList.forEach(ckDetailId -> {
                // id 接收器,用于接收插入数据时生成的自增 id 值
                Map<String, Object> idHolder = new HashMap<>();
                // 插入数据
                reagentMapper.insertByCkDetailId(ckDetailId, idHolder);
                // 获取插入数据后的自增 id 值(键名 generatedId 与 XML 配置一致  idHolder.get("generatedId")  keyProperty="idHolder.generatedId")
                Object idObj = idHolder.get("generatedId");
                // 类型安全转换 Object -> Long
                Long reagentId = TypeUtils.safeToLong(idObj);
                reagentIdList.add(reagentId.intValue());
            });
            // 返回生成的试剂
            return reagentMapper.selectByIds(reagentIdList);
        } else {
            // 返回空集合
            return new ArrayList<>();
        }
    }
ReagentMapper.java
    // 通过出库明细 id,增加试剂
    void insertByCkDetailId(@Param("ckDetailId") Integer id, @Param("idHolder") Map<String, Object> holder);
ReagentMapper.xml
    <!-- 通过出库明细 id,增加试剂,并返回自增 id 的值 -->
    <insert id="insertByCkDetailId" useGeneratedKeys="true" keyProperty="idHolder.generatedId">
        insert into Reagent(
        rea_TypeName, rea_Name,
        rea_Spec, rea_unit, rea_BatchNo,
        rea_ManufacturerName, rea_ProviderName, rea_Amount,
        rea_SubTotal, rea_ProduceDate,
        rea_OverdueDate, rea_DeptID, rea_Location,
        rea_Memo, rea_MaterialID, rea_br, rea_source, rea_State,
        rea_BookerName, rea_PrepareDate)
        select
        null, ckd_MaterialName,
        ckd_Spec, ckd_Unit, ckd_BatchNo,
        null, null, ckd_Amount,
        ckd_SubTotal, null,
        getdate(), ckm_PDDID, null,
        null, ckd_MaterialID, null, ckd_ID, 0,
        '', getdate()
        from CKDetail
        inner join CKMaster on ckm_ID = ckd_MasterID
        where ckd_ID = #{ckDetailId}
    </insert>
 TypeUtils.java
package com.weiyu.utils;

/**
 * 类型转换工具
 */
public class TypeUtils {
    /**
     * 安全转换为 Long
     * @param obj 转换对象
     * @return Long
     */
    public static Long safeToLong(Object obj) {
        if (obj == null) return null;
        if (obj instanceof Long) return (Long) obj;
        if (obj instanceof Number) return ((Number) obj).longValue();
        try {
            return Long.parseLong(obj.toString());
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("无法转换为Long: " + obj);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值