Mybatis insert 过后返回生成的 uuid 主键(非自增主键)

项目场景:

mybatis insert 过后返回 sys_guid() 生成的主键


问题描述:

一开始 mapper 这样写的:

String addReturnId(Storehouse storehouse);

对应的 xml 是这样的:

<insert id="addReturnId" parameterType="com.erow.ddzy.bizc.domain.bizc.Storehouse">
        <selectKey keyProperty="storehouseId" order="BEFORE" resultType="String">
            select sys_guid() from dual
        </selectKey>
        insert into ddzy_storehouse(
        storehouse_id,
        <if test="storehouseName != null and storehouseName != ''">storehouse_name,</if>
        <if test="orgId != null and orgId != ''">org_id,</if>
        <if test="orgName != null and orgName != ''">org_name,</if>
        <if test="buildType != null and buildType != ''">build_type,</if>
        <if test="length != null ">length,</if>
        <if test="width != null ">width,</if>
        <if test="height != null ">height,</if>
        <if test="area != null ">area,</if>
        last_update_date
        )values(
        #{storehouseId},
        <if test="storehouseName != null and storehouseName != ''">#{storehouseName},</if>
        <if test="orgId != null and orgId != ''">#{orgId},</if>
        <if test="orgName != null and orgName != ''">#{orgName},</if>
        <if test="buildType != null and buildType != ''">#{buildType},</if>
        <if test="length != null ">#{length},</if>
        <if test="width != null ">#{width},</if>
        <if test="height != null ">#{height},</if>
        <if test="area != null ">#{area},</if>
        sysdate
        )
    </insert>

然后启动测试就报错:

has an unsupported return type: class java.lang.String


原因分析:

mybatis insert 后返回 uuid 的主键不是这样写的,查看源码 insert 对应的 mapper 方法返回值只能是 int、long、boolean ,没有字符串。

public Object execute(SqlSession sqlSession, Object[] args) {
        Object result;
        Object param;
        switch(this.command.getType()) {
        case INSERT:
            param = this.method.convertArgsToSqlCommandParam(args);
            result = this.rowCountResult(sqlSession.insert(this.command.getName(), param));
            break;
        case UPDATE:
            param = this.method.convertArgsToSqlCommandParam(args);
            result = this.rowCountResult(sqlSession.update(this.command.getName(), param));
            break;
        case DELETE:
            param = this.method.convertArgsToSqlCommandParam(args);
            result = this.rowCountResult(sqlSession.delete(this.command.getName(), param));
            break;
        case SELECT:
            if (this.method.returnsVoid() && this.method.hasResultHandler()) {
                this.executeWithResultHandler(sqlSession, args);
                result = null;
            } else if (this.method.returnsMany()) {
                result = this.executeForMany(sqlSession, args);
            } else if (this.method.returnsMap()) {
                result = this.executeForMap(sqlSession, args);
            } else if (this.method.returnsCursor()) {
                result = this.executeForCursor(sqlSession, args);
            } else {
                param = this.method.convertArgsToSqlCommandParam(args);
                result = sqlSession.selectOne(this.command.getName(), param);
                if (this.method.returnsOptional() && (result == null || !this.method.getReturnType().equals(result.getClass()))) {
                    result = Optional.ofNullable(result);
                }
            }
            break;
        case FLUSH:
            result = sqlSession.flushStatements();
            break;
        default:
            throw new BindingException("Unknown execution method for: " + this.command.getName());
        }

        if (result == null && this.method.getReturnType().isPrimitive() && !this.method.returnsVoid()) {
            throw new BindingException("Mapper method '" + this.command.getName() + " attempted to return null from a method with a primitive return type (" + this.method.getReturnType() + ").");
        } else {
            return result;
        }
    }
private Object rowCountResult(int rowCount) {
        Object result;
        if (this.method.returnsVoid()) {
            result = null;
        } else if (!Integer.class.equals(this.method.getReturnType()) && !Integer.TYPE.equals(this.method.getReturnType())) {
            if (!Long.class.equals(this.method.getReturnType()) && !Long.TYPE.equals(this.method.getReturnType())) {
                if (!Boolean.class.equals(this.method.getReturnType()) && !Boolean.TYPE.equals(this.method.getReturnType())) {
                    throw new BindingException("Mapper method '" + this.command.getName() + "' has an unsupported return type: " + this.method.getReturnType());
                }

                result = rowCount > 0;
            } else {
                result = (long)rowCount;
            }
        } else {
            result = rowCount;
        }

        return result;
    }

解决方案:

对应的 mapper 返回值还是改为 int:

int addReturnId(Storehouse storehouse);

返回的 String 类型的主键,直接从传入的对象 storehouse 里的 get 方法取:

int rows = storehouseService.insertReturnId(storehouse);
String storehouseId = storehouse.getStorehouseId();

猜你喜欢

转载自blog.csdn.net/zhang33565417/article/details/117547520
今日推荐