Mybatis SQL映射语句中参数注释规则

请查看最新整理地址:http://leeyee.github.io/blog/2012/09/27/mybatis-param-mapping-rules/

 

最近在*Mybatis*的学习中对于映射语句中的参数注释设置有点犯迷糊,于是在*debug*下跟踪了下源代码,发现*Mybatis*在接口方法映射语句中会做如下处理:

1. 接口方法只有一个参数

1.1 不使用`@Param`注解

1.1.1 参数为基本类型或为基本包装类型(int,Integer,String...)

    参数注释为: #{任意字符}
   
1.1.2 参数为自定义对象

    参数注释为: #{对象属性}

示例:

Java代码   收藏代码
  1. <span style="font-size: medium;">    User getUserById(int id);  
  2.      
  3.         // 注:该中情况下'任意字符'不能为空,否则报错  
  4.         // select * from <TABEL> where id = #{任意字符}  
  5.         select * from <TABLE> where id = #{id}  
  6.   
  7.     User getUser(User user); // user.getName user.getAge  
  8.      
  9.         select * from <TABLE> where name = #{name} and age = #{age}</span>  


1.2 使用`@Param`注解

1.2.1 参数为基本类型或为基本包装类型(int,Integer,String...)

    参数注释为: #{注解名称} | #{param1}
   
1.2.2 参数为自定义对象

    参数注释为: #{注解名称.对象属性} | #{param1.对象属性}
   
示例:

Java代码   收藏代码
  1. <span style="font-size: medium;">    User getUserById(@Param(value="keyId"int id);  
  2.      
  3.         select * from <TABEL> where id = #{keyId}  
  4.         // or  
  5.         select * from <TABLE> where id = #{param1}  
  6.          
  7.     User getUser(@Param(value="usr") User user); // user.getName user.getAge  
  8.         select * from <TABLE> where name = #{user.name} and age = #{user.age}  
  9.         // or  
  10.         select * from <TABLE> where name = #{param1.name} and age = #{param1.age}</span>  

 
2. 接口方法有两个及两个以上参数

2.1 不使用`@Param`注解

2.1.1 参数为基本类型或为基本包装类型(int,Integer,String...)

    参数注释为: #{参数位置[0..n-1]} | #{param[1..n]}
   
2.1.2 参数为自定义对象

    参数注释为: #{参数位置[0..n-1].对象属性} | #{param[1..n].对象属性}

示例:

Java代码   收藏代码
  1. <span style="font-size: medium;">    User getUser(String name, int age);  
  2.         select * from <TABLE> where name = #{0} and age = #{1}  
  3.         // or  
  4.         select * from <TABLE> where name = #{param1} and age = #{param2}  
  5.      
  6.     User getUser(User usr, int flag);  
  7.         select * from <TABLE> where name = #{0.name} and age = {0.age} and flag = #{1}  
  8.         // or  
  9.         select * from <TABLE> where name = #{param1.name} and age = {param1.age} and flag = #{param2}</span>  

 

2.2 使用`@Param`注解

2.2.1 参数为基本类型或为基本包装类型(int,Integer,String...)

    参数注释为: #{注解名称} | #{param[1..n]}
   
2.2.2 参数为自定义对象

    参数注释为: #{注解名称.对象属性} | #{param[1..n].对象属性}

示例:

Java代码   收藏代码
  1. <span style="font-size: medium;">    User getUser(@Param(value="xm") String name, @Param(value="nl"int age);  
  2.         select * from <TABLE> where name = #{xm} and age = #{nl}  
  3.         // or  
  4.         select * from <TABLE> where name = #{param1} and age = #{param2}  
  5.         // or  
  6.         select * from <TABLE> where name = #{xm} and age = #{param2}  
  7.   
  8.     User getUser(@Param(value="usr") User user, @Param(value="tag"int flag);  
  9.         select * from <TABLE> where name = #{usr.name} and age = #{usr.age} and flag = #{tag}  
  10.         // or  
  11.         select * from <TABLE> where name = #{param1.name} and age = #{param1.age} and flag = #{param2}  
  12.         // or  
  13.         select * from <TABLE> where name = #{usr.name} and age = #{param1.age} and flag = #{param2}</span>  

 
2.2.3 部分参数使用`@Param`注解

当采用部分参数使用`@Param`注解时,参数注释为将以上两种情况结合起来即可。

示例:

 

Java代码   收藏代码
  1. <span style="font-size: medium;">User getUser(String name, @Param(value="nl") age, int gendar);  
  2.   
  3. // 对于age的访问不能是 #{1} 只能是 #{param2} | #{nl}  
  4. select * from <TABLE> where name = #{0} and age = #{nl} and gendar = #{param3)</span>  

 

 

总结下

  • `@Param`的作用是设置参数别名。设置后的参数只能通过`#{param[1..n]`或者`#{注解别名}`来访问
  • 多个参数情况下,均可使用  `#{参数位置[0..n-1]}` |   `#{param[1..n]}`来访问参数

最后给出几个源代码中关于参数设置的源代码供大家参考:

 

参数获取操作:org.apache.ibatis.binding.MapperMethod.getParam(Object[] args)

Java代码   收藏代码
  1. <span style="font-size: medium;">    private Object getParam(Object[] args) {  
  2.         final int paramCount = paramPositions.size();  
  3.         // 无参数  
  4.         if (args == null || paramCount == 0) {  
  5.             return null;  
  6.         // 无注解并参数个数为1  
  7.         } else if (!hasNamedParameters && paramCount == 1) {  
  8.             return args[paramPositions.get(0)];  
  9.         } else {  
  10.             Map<String, Object> param = new MapperParamMap<Object>();  
  11.             for (int i = 0; i < paramCount; i++) {  
  12.                 param.put(paramNames.get(i), args[paramPositions.get(i)]);  
  13.         }  
  14.         // issue #71, add param names as param1, param2...but ensure backward compatibility  
  15.         // 这就是 #{param[1..n]} 的来源  
  16.         for (int i = 0; i < paramCount; i++) {  
  17.             String genericParamName = "param" + String.valueOf(i + 1);  
  18.             if (!param.containsKey(genericParamName)) {  
  19.                 param.put(genericParamName, args[paramPositions.get(i)]);  
  20.             }  
  21.         }  
  22.         return param;  
  23.         }  
  24.     }</span>  

SQL预编译参数设置:org.apache.ibatis.executor.parameter.DefaultParameterHandler.setParameters(PreparedStatement ps) throws SQLException  

Java代码   收藏代码
  1. <span style="font-size: medium;">org.apache.ibatis.executor.parameter.DefaultParameterHandler.setParameters(PreparedStatement ps) throws SQLException  
  2.   
  3.     public void setParameters(PreparedStatement ps)  
  4.       throws SQLException {  
  5.         ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());  
  6.         List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();  
  7.         if (parameterMappings != null) {  
  8.             MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject);  
  9.             for (int i = 0; i < parameterMappings.size(); i++) {  
  10.                 ParameterMapping parameterMapping = parameterMappings.get(i);  
  11.                 if (parameterMapping.getMode() != ParameterMode.OUT) {  
  12.                     Object value;  
  13.                     String propertyName = parameterMapping.getProperty();  
  14.                     PropertyTokenizer prop = new PropertyTokenizer(propertyName);  
  15.                     if (parameterObject == null) {  
  16.                         value = null;  
  17.                     } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {  
  18.                         value = parameterObject;  
  19.                     } else if (boundSql.hasAdditionalParameter(propertyName)) {  
  20.                         value = boundSql.getAdditionalParameter(propertyName);  
  21.                     } else if (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX)  
  22.               && boundSql.hasAdditionalParameter(prop.getName())) {  
  23.                         value = boundSql.getAdditionalParameter(prop.getName());  
  24.                         if (value != null) {  
  25.                             value = configuration.newMetaObject(value).getValue(propertyName.substring(prop.getName().length()));  
  26.                         }  
  27.                 } else {  
  28.                     value = metaObject == null ? null : metaObject.getValue(propertyName);  
  29.                 }  
  30.                 TypeHandler typeHandler = parameterMapping.getTypeHandler();  
  31.                 if (typeHandler == null) {  
  32.                     throw new ExecutorException("There was no TypeHandler found for parameter " + propertyName + " of statement " + mappedStatement.getId());  
  33.                 }  
  34.                 JdbcType jdbcType = parameterMapping.getJdbcType();  
  35.                 if (value == null && jdbcType == null) jdbcType = configuration.getJdbcTypeForNull();  
  36.                     typeHandler.setParameter(ps, i + 1, value, jdbcType);  
  37.                 }  
  38.             }  
  39.         }  
  40.     }</span> 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值