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互操作&#…

使用wireshark抓包工具 检测不到本地网卡

wireshark 抓包工具无法检测到自身的网卡 下载wireshark 地址&#xff1a;https://www.wireshark.org/download.html安装&#xff0c;打开后发现没有windows 本身的网卡&#xff0c;查了一下&#xff0c;是Windows 本身抓包服务没有开启。打开Wireshark Legacy 在Start 下面没有…

学习Java的深拷贝和浅拷贝

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

2017.3.22-morning

RIP是一种基于距离矢量的路由协议&#xff0c;以路由跳数作为计数单位的路由协议。适合用于比较小型的网络环境。 中文名路由信息协议 外文名 Routing Information Protocol 类 型 路由协议 计数单位 路由跳数[1] 英文原义&#xff1a;Routing Information Protocol 中文释…

转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; …

js实现modbus_nodejs中使用modbus-serial库创建Modbus TCP读取设备的数据

nodejs中使用modbus-serial库创建Modbus TCP读取设备的数据在nodejs中安装modbus-serial库本人使用的开发环境是Windows10下的VSCode&#xff0c;安装并配置好了npm、node、cnpm等工具&#xff0c;使用cnpm安装了modbus-serial库&#xff0c;可以在npm中搜到modbus-serial包以及…

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…

C# TreeView 连续点击 不触发AfterCheck事件

创建一个类 TreeView2 namespace System.Windows.Forms {public class TreeView2 : TreeView{protected override void WndProc(ref Message m){if (m.Msg ! 0x203){base.WndProc(ref m);}}} }然后前台放置一个TreeView控件。名叫&#xff1a;treeView1 后台代码&#xff1a; p…

最长等差数列_最长等差数列分析

原题给定未排序的数组&#xff0c;请给出方法找到最长的等差数列。分析题目描述比较简单&#xff0c;但是有一个问题我们需要首先搞清楚&#xff1a;等差数列中的数字&#xff0c;是否要和原始数组中的顺序一致。题目中&#xff0c;并没有说明&#xff0c;这个就需要大家在面试…

Mybatis中注解@MapKey的使用详解

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

JMeter测试组件

JMeter的主要测试组件 1、测试计划是使用JMeter进行测试的起点&#xff0c;它是其它JMeter测试元件的容器。 2、线程组代表一定数量的并发用户&#xff0c;它可以用来模拟并发用户发送请求。实际的请求内容在Sampler中定义&#xff0c;它被线程组包含。 3、监听器负责收集测试结…

aes js 加盐值 解密_Java已有AES加解密,现需要前端Javascript加密调接口,返回的数据需要解密,目前互..._慕课猿问...

目前Javascript使用crypto-js包。前后台可以自己跑通加解密&#xff0c;但是&#xff0c;无法互通。针对对象{}加密……网上的方案&#xff0c;已经尝试了4天左右了&#xff0c;还没成功&#xff0c;请指导。无思路&#xff0c;无报错。Javapackage com.pactera.sms.foundbase.…

springboot 1.5.2 集成kafka 简单例子

添加依赖 compile("org.springframework.kafka:spring-kafka:1.1.2.RELEASE") 添加application.properties #kafka # 指定kafka 代理地址&#xff0c;可以多个 spring.kafka.bootstrap-servers192.168.59.130:9092,192.168.59.131:9092,192.168.59.132:9092 # 指定默…

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

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