MyBatis参数名称解析器-ParamNameResolver解析

ParamNameResolver

ParamNameResolver是一个参数名解析器,负责把方法的参数按顺序解析出来并进行标注

主要用来处理接口形式的参数,最后会把参数处放在一个map中

map的key为参数的位置,value为参数的名字

 

package org.apache.ibatis.reflection;import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.binding.MapperMethod.ParamMap;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;public class ParamNameResolver {// 通用参数名称前缀private static final String GENERIC_NAME_PREFIX = "param";// key是索引,value是参数的名称。// 如果指定了名称,则从@Param中获得。如果未指定@Param,则使用参数索引。// 注意,当方法具有特殊参数(如RowBounds或ResultHandler)时,该索引可能与实际索引不同。// Method(@Param("M") int a, @Param("N") int b)转化为map为{{0, "M"}, {1, "N"}}// Method(int a, int b)转化为map为{{0, "0"}, {1, "1"}}// Method(int a, RowBounds rb, int b)转化为map为{{0, "0"}, {2, "1"}}// 有序映射 存储参数名称private final SortedMap<Integer, String> names;// 是否使用@Param注解标志private boolean hasParamAnnotation;// 构造方法public ParamNameResolver(Configuration config, Method method) {final Class<?>[] paramTypes = method.getParameterTypes();final Annotation[][] paramAnnotations = method.getParameterAnnotations();final SortedMap<Integer, String> map = new TreeMap<>();int paramCount = paramAnnotations.length;// get names from @Param annotationsfor (int paramIndex = 0; paramIndex < paramCount; paramIndex++) {if (isSpecialParameter(paramTypes[paramIndex])) {// 跳过特殊参数continue;}String name = null;for (Annotation annotation : paramAnnotations[paramIndex]) {if (annotation instanceof Param) {hasParamAnnotation = true;name = ((Param) annotation).value();break;}}if (name == null) {// 没有指定@Paramif (config.isUseActualParamName()) {name = getActualParamName(method, paramIndex);}if (name == null) {// 使用参数索引作为名称("0","1",…)name = String.valueOf(map.size());}}map.put(paramIndex, name);}names = Collections.unmodifiableSortedMap(map);}// 获取实际参数名称private String getActualParamName(Method method, int paramIndex) {return ParamNameUtil.getParamNames(method).get(paramIndex);}// 是不是特殊参数()private static boolean isSpecialParameter(Class<?> clazz) {return RowBounds.class.isAssignableFrom(clazz) || ResultHandler.class.isAssignableFrom(clazz);}/*** 返回SQL引用的参数名。*/public String[] getNames() {return names.values().toArray(new String[0]);}/*** 返回一个没有名称的非特殊参数。* 使用命名规则命名多个参数* 除了默认名称之外,该方法还添加通用名称(paraml、param2、...).*/public Object getNamedParams(Object[] args) {final int paramCount = names.size();if (args == null || paramCount == 0) {return null;} else if (!hasParamAnnotation && paramCount == 1) {return args[names.firstKey()];} else {final Map<String, Object> param = new ParamMap<>();int i = 0;for (Map.Entry<Integer, String> entry : names.entrySet()) {param.put(entry.getValue(), args[entry.getKey()]);// 添加通用参数名称(参数、参数 2...)final String genericParamName = GENERIC_NAME_PREFIX + String.valueOf(i + 1);// /确保没有覆盖以@Param命名的参数if (!names.containsValue(genericParamName)) {param.put(genericParamName, args[entry.getKey()]);}i++;}return param;}}
}

 

 

 

 

总结

指定@Param情况下

通过@Param("username")的value访问  比如#{username}

 

不指定@Param情况下

Java 8 编译,并且指定-parameters,并且mybatis版本3.4.1及之后版本

可以通过具体的参数变量名来访问,比如#{username}

@Insert("insert into account(username,phone,createTime) values(#{username},#{phone},#{createTime})")
void addAccountNoId22(String username, String phone, Date createTime);

 

不指定指定-parameters

可以通过第1个参数 #{arg0}  、第2个参数#{arg1},以此类推来访问

@Insert("insert into account(username,phone,createTime) values(#{arg0},#{arg1},#{arg2})")
void addAccountNoId1(String username,String phone,Date createTime);

 

 

只有1个参数情况下

未指定@Param,可以通过任何变量来访问

@Insert("insert into account(username) values(#{abc})")
void addAccountOne(String username);

 

 

指定了@Param,就不能访问了 

# 注意,本条语句会报错
@Insert("insert into account(username) values(#{abc})")
void addAccountOne1(@Param("username") String username);

 

 

通用

不管哪种模式下,在有多个参数情况下,都可以通过第1个参数#{param1}、第2个参数#{param2},以此类推来访问

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/269774.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

json 取值判断_【收藏级】.NETCore3.1中的Json互操作解读

本文将会全面介绍System.Text.Json 和 Newtonsoft.Json 的相同和异同之处&#xff0c;方便需要的同学做迁移使用&#xff0c;对未来&#xff0c;我们保持期待。文档比较几个重要的对象在 System.Text.Json 中&#xff0c;有几个重量级的对象&#xff0c;所有的JSON互操作&#…

学习Java的深拷贝和浅拷贝

关于Java的深拷贝和浅拷贝&#xff0c;简单来说就是创建一个和已知对象一模一样的对象。可能日常编码过程中用的不多&#xff0c;但是这是一个面试经常会问的问题&#xff0c;而且了解深拷贝和浅拷贝的原理&#xff0c;对于Java中的所谓值传递或者引用传递将会有更深的理解。 …

转list_你知道Java数组转List的三种方式及对比吗?

前言&#xff1a;本文介绍Java中数组转为List三种情况的优劣对比&#xff0c;以及应用场景的对比&#xff0c;以及程序员常犯的类型转换错误原因解析。一.最常见方式(未必最佳)通过 Arrays.asList(strArray) 方式,将数组转换List后&#xff0c;不能对List增删&#xff0c;只能查…

Mybatis中的#号与$符号的区别

1、#{变量名}可以进行预编译、类型匹配等操作&#xff0c; 2、#{变量名}会转化为jdbc的类型。 3、${变量名}不进行数据类型匹配&#xff0c;直接替换。 4、#方式能够很大程度防止sql注入。 5、$方式无法方式sql注入。 6、$方式一般用于传入数据库对象&#xff0c;例如传入…

创建存储问题总结

创建存储过程时 1 drop procedure if exists pro_1; 2 delimiter // 3 create procedure pro_1( 4 5 ) 6 begin 7 8 end // 9 delimiter ; 发现这个问题时时因为看到输出的最后delimiter中有两个分号&#xff0c;所以怀疑这个地方语法存在问题 结尾的delimiter &#xff1b; …

Windows如何安装MSMQ消息队列

1 打开控制面板&#xff0c;找到下图所示的服务器核心&#xff0c;然点击确定 2 等待安装完成 转载于:https://www.cnblogs.com/acetaohai123/p/6610302.html

讲字节数组转化为base64_Base64编码简介及简单实现

Base64编码是一种将字节数据编码为字符串的编码&#xff0c;字节数据会被编码成由64个可打印ASCII字符组成的字符串,这64个字符包括大写字母A-Z, 小写字母a-z, 以及数字 0 -9再加上 和 / &#xff0c;刚好64个字符。对应的字符表如下图&#xff1a;base64编码的一个用途就是对…

Mybatis返回Map

返回一条记录的map resultType“map“ key就是列名&#xff0c;值就是对应的值 多条记录封装成一个map Select返回类型中是返回Map时&#xff0c;是对方法中是否存在注解MapKey&#xff0c;这个注解我也是第一次看到&#xff0c;当时我也以为是纯粹的返回单个数据对象的Map…

Mybatis中注解@MapKey的使用详解

MyBatis查询一些记录&#xff0c;数据涉及到两个表里的数据&#xff0c;需要连表查询&#xff0c;但我MyBatis的返回结果不想创建新的DO对象&#xff0c;因此使用MapKey注解返回一个Map集合。 含义&#xff1a;MapKey注解用于mapper.xml文件中&#xff0c;一般用于查询多条记录…

更新 绑定数据_Blazor 修仙之旅 组件与数据绑定

一.前言在第一篇文章初尝 Blazor WebAssembly中&#xff0c;有提到过组件(Component)这个概念。组件在 Blazor 中是必不可少的&#xff0c;UI 全靠它组装起来&#xff0c;和前端的 JS 组件是一个意思&#xff0c;比如&#xff1a;vue component、react component 等等。借用官方…

关于使用idea工具debug时,断点颜色由红色变成灰色解决方法

在使用断点调试的时候&#xff0c;发现断点由原来的红色变成灰色的&#xff0c;后来发现是由于错误操作将Debug断点调试禁用了 &#xff0c;只需要点击禁用按钮取消就可以了

改变图标颜色_LOL设计师宣布修改装备图标:提高清晰度、颜色差异化

在11月12日&#xff0c;英雄联盟更新到了最新的季前赛版本。这次官方除了对部分英雄进行改动&#xff0c;主要是对于装备的图标和属性进行了更新。而在图标更新后&#xff0c;很多装备的样子都发生了很大的变化。这也导致很多老玩家在进游戏后&#xff0c;看着装备栏发呆&#…

虚拟机中centos安装gcc

yum install gcc-c 一、首先是&#xff1a;使得虚拟机联网 使用NAT模式 虚拟机网络连接使用NAT模式&#xff0c;物理机网络连接使用Vmnet8。 虚拟机设置里面——网络适配器&#xff0c;网络连接选择NAT模式。 虚拟机菜单栏—编辑—虚拟网络编辑器&#xff0c;选择Vmnet8 NAT模式…

gcd(欧几里得算法)

基础 1 int gcd(int a,int b) 2 { 3 int r; 4 while(b>0) 5 { 6 ra%b; 7 ab; 8 br; 9 } 10 return a; 11 } View Code递归 1 int gcd(int a,int b) 2 { 3 return (b>0)?gcd(b,a%b):a; 4 } Vi…

网络摄像头sdk_SenseDLC嵌入式人像识别SDK 安防边缘的“小巨人”

随着这些年将人工智能技术赋能行业的不断深入&#xff0c;商汤科技对智慧城市建设有着更深的理解。通过不断实践发现&#xff0c;很多区域由于摄像头数量和布置等问题较难有效做到清晰的人脸抓拍&#xff0c;且单一的人脸识别会遇到诸多干扰&#xff0c;比如发型、胖瘦、年纪、…

使用最大似然法来求解线性模型(1)

在Coursera机器学习课程中&#xff0c;第一篇练习就是如何使用最小均方差(Least Square)来求解线性模型中的参数。本文从概率论的角度---最大化似然函数&#xff0c;来求解模型参数&#xff0c;得到线性模型。本文内容来源于&#xff1a;《A First Course of Machine Learning》…