MyBatis-@param注解详解

MyBatis-@param注解详解param 参数注解一 Param 注解单一属性 dao 层示例 PublicUserse param userName Stringname param userpassword Stringpasswo xml 映射对应示例 amp amp amp amp amp lt selectid amp amp amp amp quot selectUser amp amp amp a

一、源码解析

一、useActualParamName配置

#{arg0}-#{argn}或者#{param1}-#{paramn}

#{0}-#{n}或者#{param1}-#{paramn}

二、源码解读(3.4.6)

在mapper的代理对象调用方法时,最终会是MapperMethod对象的execute方法。如下:

@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { // 如果目标方法是Object类继承来的,直接调用目标方法 if (Object.class.equals(method.getDeclaringClass())) { return method.invoke(this, args); } else if (isDefaultMethod(method)) { return invokeDefaultMethod(proxy, method, args); } } catch (Throwable t) { throw ExceptionUtil.unwrapThrowable(t); } // 从缓存中获取MapperMethod 对象,如果没有就创建新的并添加 final MapperMethod mapperMethod = cachedMapperMethod(method); // 执行sql 语句 return mapperMethod.execute(sqlSession, args); } 

MapperMethod的一个内部类MethodSignature封装了Mapper接口中定义的方法的相关信息。而MethodSignature的一个属性ParamNameResolver对象处理接口中定义的方法的参数列表。

ParamNameResolver 的属性

// 记录参数在参数列表中的位置索引与参数名称之间的对应关系 private final SortedMap 
  
    names; // 记录对应的方法参数是否使用了@Param注解 private boolean hasParamAnnotation; 
  

ParamNameResolver的构造函数

/ * 通过反射读取方法中的信息,并初始化上面两个字段 * @param config * @param method */ public ParamNameResolver(Configuration config, Method method) { // 获取参数列表中每个参数的类型 final Class 
  [] paramTypes = method.getParameterTypes(); // 获取参数列表上的注解 @Param final Annotation[][] paramAnnotations = method.getParameterAnnotations(); // 该集合用于记录参数索引与参数名称的对应关系 final SortedMap 
  
    map = new TreeMap 
   
     (); int paramCount = paramAnnotations.length; // 遍历所有参数 for (int paramIndex = 0; paramIndex < paramCount; paramIndex++) { if (isSpecialParameter(paramTypes[paramIndex])) { // 如果参数是RowBounds类型或者ResultHandler类型,则跳过该参数 continue; } String name = null; // 遍历该参数上的注解集合 for (Annotation annotation : paramAnnotations[paramIndex]) { if (annotation instanceof Param) { // 获取@Param注解指定的参数名称 hasParamAnnotation = true; name = ((Param) annotation).value(); break; } } // 没有@Param注解的话 执行下面逻辑 if (name == null) { // useActualParamName==true时 即name = arg0 ... if (config.isUseActualParamName()) { name = getActualParamName(method, paramIndex); } if (name == null) {//useActualParamName == false是 即 name="0" ... // use the parameter index as the name ("0", "1", ...) // 使用参数的索引作为其名称 name = String.valueOf(map.size()); } } map.put(paramIndex, name); } names = Collections.unmodifiableSortedMap(map); } 
    
  

names集合主要是在ParamNameResolver.getNamedParams方法中使用

/ * * @param args 用户传入的参数值列表 * @return */ public Object getNamedParams(Object[] args) { final int paramCount = names.size(); if (args == null || paramCount == 0) { return null; } else if (!hasParamAnnotation && paramCount == 1) {// 未使用@Param注解且参数列表只有一个 return args[names.firstKey()];//即args[0] 参数的值 } else { // 下面是为参数创建param+索引的格式作为默认参数名称 如:param1 下标从1开始 final Map 
  
    param = new ParamMap 
    (); int i = 0; for (Map.Entry 
    
      entry : names.entrySet()) { param.put(entry.getValue(), args[entry.getKey()]); // add generic param names (param1, param2, ...) final String genericParamName = GENERIC_NAME_PREFIX + String.valueOf(i + 1); // ensure not to overwrite parameter named with @Param if (!names.containsValue(genericParamName)) { param.put(genericParamName, args[entry.getKey()]); } i++; } return param; } } 
      
  

二.使用@param参数注解

一、单一属性

service层示例

todoItemsMapper.selectItembyparam1(1,"medium") 

dao层示例

List 
  
    selectItembyparam1(@Param("id") int userId,@Param("pty") String Priority); 
  

xml映射对应示例

  
[{ "todoItemId": 2, "userId": 1, "todoItemTitle": "bbbb", "todoItemContent": "待办事项2", "priority": "medium", "creationDate": 00, "lastUpdateDate": 00, "comments": "bb" }, { "todoItemId": 4, "userId": 1, "todoItemTitle": "dddd", "todoItemContent": "待办事项4", "priority": "medium", "creationDate": 00, "lastUpdateDate": 00, "comments": "ddd" }] 

二、JavaBean对象

一、单个javabean对象

service 层示例

 CuxTodoItems items = new CuxTodoItems(); items.setUserId(1); items.setPriority("low"); List 
  
    itemsList = todoItemsMapper.selectItembyparam2(items); return itemsList; 
  

dao层示例

 List 
  
    selectItembyparam2(@Param("item") CuxTodoItems cuxTodoItems); 
  

xml映射对应示例

 
 [{ "todoItemId": 5, "userId": 1, "todoItemTitle": "eee", "todoItemContent": "待办事项5", "priority": "low", "creationDate": 00, "lastUpdateDate": 00, "comments": "ee" }, { "todoItemId": 6, "userId": 1, "todoItemTitle": "fffffffff", "todoItemContent": "ffffffffff", "priority": "low", "creationDate": 00, "lastUpdateDate": 00, "comments": "ffffffffffffffffffff" }] 

二、多个javabean对象

service层

 CuxTodoItems items = new CuxTodoItems(); items.setPriority("high"); CuxUsers users = new CuxUsers(); users.setUserId(2); List 
  
    itemsList = todoItemsMapper.selectItembyparam3(items,users); 
  

dao层

 List 
  
    selectItembyparam3(@Param("it") CuxTodoItems cuxTodoItems, @Param("us")CuxUsers user); 
  

xml对应示例

 
 [{ "todoItemId": 7, "userId": 2, "todoItemTitle": "ggg", "todoItemContent": "代办事项g", "priority": "high", "creationDate": 00, "lastUpdateDate": 00, "comments": "备注g" }] 

三.不使用@param参数注解

一、单一属性

一、一个单一属性

service

todoItemsMapper.selectItembyparam4(2); 

dao 层

List 
  
    selectItembyparam4( int userId); 
  

xml对应示例

 
[{ "todoItemId": 7, "userId": 2, "todoItemTitle": "ggg", "todoItemContent": "代办事项g", "priority": "high", "creationDate": 00, "lastUpdateDate": 00, "comments": "备注g" }] 

注意:当查询参数为一个单一属性且没有使用注解时xml中查询字段#{}内可以为任意值

二、多个单一属性

service层

todoItemsMapper.selectItembyparam5(1,"high"); 

dao层

List 
  
    selectItembyparam5( int userId,String Priority); 
  

xml对应示例

 
[{ "todoItemId": 3, "userId": 1, "todoItemTitle": "ccc", "todoItemContent": "待办事项3", "priority": "high", "creationDate": 00, "lastUpdateDate": 00, "comments": "cc" }] 

二、JavaBean对象

一、单个javabean对象

service层

CuxTodoItems items = new CuxTodoItems(); items.setUserId(2); items.setPriority("high"); List 
  
    itemsList = todoItemsMapper.selectItembyparam6(items); 
  

dao层

List 
  
    selectItembyparam6( CuxTodoItems cuxTodoItems); 
  

xml对应查询字段

 
[{ "todoItemId": 7, "userId": 2, "todoItemTitle": "ggg", "todoItemContent": "代办事项g", "priority": "high", "creationDate": 00, "lastUpdateDate": 00, "comments": "备注g" }] 

注意:xml查询字段需要与javabean属性一致

二、多个javabean对象

service层

CuxTodoItems items = new CuxTodoItems(); items.setPriority("medium"); CuxUsers users = new CuxUsers(); users.setUserId(1); List 
  
    itemsList = todoItemsMapper.selectItembyparam7(items,users); 
  

dao层

List 
  
    selectItembyparam7( CuxTodoItems cuxTodoItems, CuxUsers user); 
  

xml对应查询

 
[{ "todoItemId": 2, "userId": 1, "todoItemTitle": "bbbb", "todoItemContent": "待办事项2", "priority": "medium", "creationDate": 00, "lastUpdateDate": 00, "comments": "bb" }, { "todoItemId": 4, "userId": 1, "todoItemTitle": "dddd", "todoItemContent": "待办事项4", "priority": "medium", "creationDate": 00, "lastUpdateDate": 00, "comments": "ddd" }] 

在这里插入图片描述

四、总结:

1.如果接口方法有一个或多个参数,并且使用了@Param注解,若注解的为单一属性则sql语句中的参数用注解的value值,若为bean则sql语句中使用的参数注解的value.bean属性值

2.如果接口方法的参数只有一个,并且没有使用@Parma注解,若为单一属性,则sql语句直接使用任何名称均可,若为bean,则sql 语句中的参数直接为bean的属性值就行。

3.如果接口的方法有多个参数,并且没有使用@Parma注解,单一属性 时sql语句使用param1…paramn,bean时sql语句使用param1.属性值…paramn.属性值是不会错的。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/222049.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午4:40
下一篇 2026年3月17日 下午4:41


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号