option

探讨在MyBatis中使用注解方式添加记录后,如何正确获取自动生成的主键值。通过分析源码,揭示@Options注解配合@Insert或@InsertProvider的正确用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在使用mybatis作为ORM框架时,我通常更喜欢使用注解而非xml配置文件的方式。
业务场景:添加记录之后需要返回自己自增长的主键字段值。
通常,我们会将DAO层写成如下代码(以添加员工Staff为例):

public interface StaffDAO {
    @InsertProvider(type=StaffProvider.class, method="buildSinleStaff")
    @Options(useGeneratedKeys=true, keyProperty="staff_id", keyColumn="staff_id")
    public int addStaff(Staff staff);
}

显然,希望在执行addStaff()后返回新添加的员工记录的主键字段值,在这里为staff_id(staff_id为主键字段,且为自增类型)。
但是!!!经过多次验证,依然发现,返回值始终为:1!
跟踪mybatis源码发现,返回值其实是添加的记录数,而不是新加记录的主键字段值,所以永远为1。

mybatis添加记录时序图:
技术分享
查看org.apache.ibatis.executor.statement.PreparedStatementHandler源码实现:

@Override
public int update(Statement statement) throws SQLException {
    PreparedStatement ps = (PreparedStatement) statement;
    ps.execute();
    int rows = ps.getUpdateCount();
    Object parameterObject = boundSql.getParameterObject();
    KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
    keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
    return rows;
}

显然,返回值是受影响的记录数量,即:添加的记录数。

那么如何才能取得新添加记录的主键字段值呢?继续跟踪源码(org.apache.ibatis.executor.statement.PreparedStatementHandler):

@Override
public int update(Statement statement) throws SQLException {
    PreparedStatement ps = (PreparedStatement) statement;
    ps.execute();
    int rows = ps.getUpdateCount();
    Object parameterObject = boundSql.getParameterObject();
    KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
    keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
    return rows;
}

显然,在执行插入记录操作之后,还执行了如下操作:

Object parameterObject = boundSql.getParameterObject();
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);

在org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator中实现对主键字段的处理:

private void populateKeys(ResultSet rs, MetaObject metaParam, String[] keyProperties, TypeHandler<?>[] typeHandlers) throws SQLException {
    for (int i = 0; i < keyProperties.length; i++) {
        TypeHandler<?> th = typeHandlers[i];
        if (th != null) {
            Object value = th.getResult(rs, i + 1);
            metaParam.setValue(keyProperties[i], value);
        }
    }
}


恍然大悟!
在使用mybatis注解@Options(useGeneratedKeys=true)获取新添加记录的自增长主键字段值时,需要在执行添加操作之后,直接访问对象的主键字段属性即可取得对应值
回归到业务代码:

staffService.addStaff(staff);
long staffId = staff.getStaff_id(); // 执行添加操作之后获取对象主键字段值

最后需要说明:在mybatis中使用注解实现添加记录时,可以使用@Insert或者@InsertProvider 2个注解,都可以使用@Options注解获取新添加记录的自增长主键字段值。

【参考】
http://isilic.iteye.com/blog/1810782 Mybatis使用:Sql Annotation

<think>好的,用户想查询与“option 138”相关的IT内容。首先,我需要确定“option 138”具体指的是什么。根据常见的IT知识,option 138通常与DHCP配置相关,尤其是在PXE引导环境中。 DHCP(动态主机配置协议)中有很多选项代码,用于传递额外的配置信息给客户端。例如,option 66和67用于指定TFTP服务器地址和启动文件名。而option 138可能涉及特定的配置参数,比如网络引导或设备配置。 接下来,我需要验证这个信息是否正确。根据引用中的内容,虽然没有直接提到option 138,但引用[2]提到了SQL命令中的参数设置,这可能与网络配置中的参数传递有关联。不过,更可能的是,option 138属于DHCP的标准选项之一,用于指定某些服务器地址或路径。 在DHCP的上下文中,option 138通常用于设置冗余服务器或故障转移配置,比如在一些网络设备中指定备用的控制器或管理服务器的IP地址。例如,在工业自动化或高可用性网络中,设备可能需要通过DHCP获取主控和备用控制器的地址,以确保网络的可靠性。 此外,PXE(预启动执行环境)引导过程中,DHCP选项用于告诉客户端从哪里下载启动文件。虽然option 66和67更常用,但某些特定厂商或自定义配置可能会使用option 138来传递特殊参数。 为了确保准确性,我需要确认标准DHCP选项中138的定义。查阅相关资料,发现option 138确实被某些厂商用于特定的配置,比如Cisco的无线局域网控制器(WLC)使用option 138来指定控制器的IP地址,以便接入点(AP)能够发现并连接到正确的控制器。 总结来说,用户询问的“option 138”在IT上下文中,主要与DHCP配置相关,用于传递特定的网络参数,如冗余服务器地址或控制器信息。这在企业网络、工业自动化或无线网络部署中较为常见,确保设备能够正确连接到管理服务器或控制器,实现自动配置和高可用性。</think>### 关于DHCP Option 138的解析 在DHCP协议中,**Option 138**属于厂商自定义选项(Vendor-Specific Option),主要用于传递特定网络设备的配置参数。以下是其核心应用场景与技术细节: 1. **核心功能** - Option 138用于向客户端设备提供**冗余控制器或管理服务器的IP地址**,例如在工业自动化或企业网络中,设备需要通过DHCP获取主控和备用控制器的信息[^2]。 - 在无线网络部署中,Cisco无线接入点(AP)通过Option 138获取无线局域网控制器(WLC)的IP地址,以实现自动注册和集中管理[^4]。 2. **配置示例** ```plaintext # DHCP服务器配置(以Linux ISC DHCP为例) option space Cisco_LWAPP; option Cisco_LWAPP.controller-address code 138 = ip-address; subnet 192.168.1.0 netmask 255.255.255.0 { option routers 192.168.1.1; option Cisco_LWAPP.controller-address 10.0.0.10, 10.0.0.11; # 主备控制器IP } ``` 此配置会向客户端下发两个控制器地址,设备优先连接主控制器(10.0.0.10),故障时切换到备用地址(10.0.0.11)。 3. **技术依赖** - 需要DHCP服务器支持自定义选项扩展。 - 客户端设备需预装支持解析Option 138的固件或驱动(如Cisco AP的轻量接入点协议LWAPP)。 4. **与其他选项的对比** - **Option 66 (TFTP服务器地址)**:用于PXE引导或无盘工作站。 - **Option 150 (多TFTP服务器)**:扩展版Option 66,支持多个IP地址。 - **Option 138**:专用于控制器/服务器冗余场景,常见于企业级设备。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值