Resolve MyBatis @ param annotation parameter type error exception

  • 2021-08-16 23:59:49
  • OfStack

Problem phenomenon

Today, I encountered a very strange problem when using mybatis. I used a parameter @ param ("threshold"), and the type is double of java, but it was very strange. 1 told me that the parameter conversion was wrong, and int could not be converted to double, so I was surprised where int came from.

Solution

I feel that I may use the keyword of mybatis, so I changed the name of threshold, which is really good.

Causes of the problem

Some keywords, mybatis will be considered to be a certain type, listed below 1, later found to add.

size, threshold, modCount are int types

loadFactor is the float type

Added: mybatis uses @ Param's pit

The @ Param annotation in mybatis is used to specify a name for the parameter, which is used in the mapper file, instead of using arguments [0, 1...] of mybatis instead. But in the non-dynamic mapper--mybatis that creates implementation classes based on the mapper interface, the @ param annotation does not work.

Read the source code of mybatis and know how to check the annotation of @ param:


private boolean hasNamedParams(Method method) {
   boolean hasNamedParams = false;
   final Object[][] paramAnnos = method.getParameterAnnotations();
   for (Object[] paramAnno : paramAnnos) {
    for (Object aParamAnno : paramAnno) {
     if (aParamAnno instanceof Param) {
      hasNamedParams = true;
      break;
     }
    }
   }
   return hasNamedParams;
  }

This method is in the inner class MethodSignature of org. apache. ibatis. binding. MapperMethod.

According to the source code 1 step 1 step recursion:

The Construction Method of MethodSignature > The Construction Method of MapperMethod > cachedMapperMethod and invoke Methods of MapperProxy > newInstance method in MapperProxyFactory.


@SuppressWarnings("unchecked")
 protected T newInstance(MapperProxy<T> mapperProxy) {
//jdk Dynamic proxy generation based on mapper Object 
  return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
 }
 public T newInstance(SqlSession sqlSession) {
//MapperProxy Realized Invocation Interface 
  final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
  return newInstance(mapperProxy);
 }

When integrating spring with mybatis and using sqlSessionTemplate provided by spring for query, mapper is not taken from mapper cache set of MapperRegistry, but the configured sqlSessionTemplate is directly used.

Therefore, in this clear situation, @ param annotation is invalid.


Related articles: