复习下mybatis 中 useGeneratedKeys 和 keyProperty 含义

今天突然碰到这个错误,让我复习下mybatis 中 useGeneratedKeys 和 keyProperty 含义

nested exception is org.apache.ibatis.executor.ExecutorException: Error getting generated key or setting result to parameter object. Cause: org.apache.ibatis.executor.ExecutorException: Could not determine which parameter to assign generated keys to. Note that when there are multiple parameters, 'keyProperty' must include the parameter name (e.g. 'param.id'). Specified key properties are [id] and available parameters are [2]

MyBatis如何获取插入记录的自增长字段值:

第一步:

在Mybatis Mapper文件中添加属性useGeneratedKeyskeyProperty,其中keyProperty是Java对象的属性名!

<insert id="insert" parameterType="Spares" 
        useGeneratedKeys="true" keyProperty="id">
        insert into spares(spares_id,spares_name,
            spares_type_id,spares_spec)
        values(#{id},#{name},#{typeId},#{spec})
  </insert>

第二步:

Mybatis执行完插入语句后,自动将自增长值赋值给对象Spares的属性id。因此,可通过Spares对应的getter方法获取!
    /**
     * 新增备件
     * @author hellostory
     * @param spares
     * @return
     */
    @RequestMapping(value = "/insert")
    @ResponseBody
    public JsonResponse insert(Spares spares) {
        int count = sparesService.insert(spares);      //count>0 表示成功
        System.out.println( "刚刚插入记录的主键自增长值为:" + spares.getId());

如果没有useGeneratedKeys="true"keyProperty="id",下面 insert 之后的 user.getId() 是无法获取 id 值

public void insert(User user) {    
  int count = userMapper.insert(user);     
  System.out.println("共插入" + count + "条记录!"  + "\n刚刚插入记录的主键自增长值为:" + user.getId());
 }

总结

useGeneratedKeys 的意思是向传入的Model赋值自增长id 。而keyProperty表示将自增长id赋值给哪个字段。所以当传入两个参数时,会报如上错误;
可参照getAssignerForParamMap源码:

 private Entry<String, KeyAssigner> getAssignerForParamMap(Configuration config, ResultSetMetaData rsmd,
      int columnPosition, Map<String, ?> paramMap, String keyProperty, String[] keyProperties, boolean omitParamName) {
    //判断paramMap是否只有一个唯一key
    boolean singleParam = paramMap.values().stream().distinct().count() == 1;
    //获取keyProperty的.的位置
    int firstDot = keyProperty.indexOf('.');
    //如果是多个参数,但是keyProperty又不包含.,会抛出错误
    if (firstDot == -1) {
      if (singleParam) {
        return getAssignerForSingleParam(config, rsmd, columnPosition, paramMap, keyProperty, omitParamName);
      }
      throw new ExecutorException("Could not determine which parameter to assign generated keys to. "
          + "Note that when there are multiple parameters, 'keyProperty' must include the parameter name (e.g. 'param.id'). "
          + "Specified key properties are " + ArrayUtil.toString(keyProperties) + " and available parameters are "
          + paramMap.keySet());
    }
    //多参数,需要截取keyProperty的.之前部分,去paramMap拿对应值
    String paramName = keyProperty.substring(0, firstDot);
    if (paramMap.containsKey(paramName)) {
      String argParamName = omitParamName ? null : paramName;
      String argKeyProperty = keyProperty.substring(firstDot + 1);
      return entry(paramName, new KeyAssigner(config, rsmd, columnPosition, argParamName, argKeyProperty));
    } else if (singleParam) {
      return getAssignerForSingleParam(config, rsmd, columnPosition, paramMap, keyProperty, omitParamName);
    } else {
      throw new ExecutorException("Could not find parameter '" + paramName + "'. "
          + "Note that when there are multiple parameters, 'keyProperty' must include the parameter name (e.g. 'param.id'). "
          + "Specified key properties are " + ArrayUtil.toString(keyProperties) + " and available parameters are "
          + paramMap.keySet());
    }
  }

猜你喜欢

转载自blog.csdn.net/agonie201218/article/details/105866670