get占位符传多个参数_mybatis多个参数(不使用@param注解情况下),sql参数占位符正确写法...
useActualParamName配置
useActualParamName
允許使用方法簽名中的名稱作為語(yǔ)句參數(shù)名稱。 為了使用該特性,你的工程必須采用Java 8編譯,并且加上-parameters選項(xiàng)。(從3.4.1開始)
true | false
true
mybatis的全局配置useActualParamName決定了mapper中參數(shù)的寫法,默認(rèn)為true
代碼展示:
@Test
public void findUserById() {
SqlSession sqlSession = getSessionFactory().openSession();
UserDao userMapper = sqlSession.getMapper(UserDao.class);
User user = userMapper.findUserById(1,"lpf");
Assert.assertNotNull("沒找到數(shù)據(jù)", user);
}
public interface UserDao {
User findUserById (int id,String name);
}
1.如果useActualParamName設(shè)置為true時(shí)
傳遞參數(shù)需要使用
#{arg0}-#{argn}或者#{param1}-#{paramn}
比如:
select * from m_user where id = #{arg0} and name =#{arg1}
或者
select * from m_user where id = #{param1} and name =#{param2}
2.如果useActualParamName設(shè)置為false時(shí)
傳遞參數(shù)需要使用
#{0}-#{n}或者#{param1}-#{paramn}
select * from m_user where id = #{0} and name =#{1}
或者
select * from m_user where id = #{param1} and name =#{param2}
下面是多個(gè)參數(shù)的錯(cuò)誤寫法直接寫參數(shù)名(如果方法只有一個(gè)參數(shù)是可以用參數(shù)名代替的,其實(shí)如果只有一個(gè)參數(shù),任何名稱都是可以的)
select * from m_user where id = #{id} and name =#{name}
源碼解讀(3.4.6):
在mapper的代理對(duì)象調(diào)用方法時(shí),最終會(huì)是MapperMethod對(duì)象的execute方法。如下:
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
// 如果目標(biāo)方法是Object類繼承來(lái)的,直接調(diào)用目標(biāo)方法
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 對(duì)象,如果沒有就創(chuàng)建新的并添加
final MapperMethod mapperMethod = cachedMapperMethod(method);
// 執(zhí)行sql 語(yǔ)句
return mapperMethod.execute(sqlSession, args);
}
MapperMethod的一個(gè)內(nèi)部類MethodSignature封裝了Mapper接口中定義的方法的相關(guān)信息。而MethodSignature的一個(gè)屬性ParamNameResolver對(duì)象處理接口中定義的方法的參數(shù)列表。
ParamNameResolver 的屬性
// 記錄參數(shù)在參數(shù)列表中的位置索引與參數(shù)名稱之間的對(duì)應(yīng)關(guān)系
private final SortedMap names;
// 記錄對(duì)應(yīng)的方法參數(shù)是否使用了@Param注解
private boolean hasParamAnnotation;
ParamNameResolver的構(gòu)造函數(shù)
/**
* 通過反射讀取方法中的信息,并初始化上面兩個(gè)字段
* @param config
* @param method
*/
public ParamNameResolver(Configuration config, Method method) {
// 獲取參數(shù)列表中每個(gè)參數(shù)的類型
final Class>[] paramTypes = method.getParameterTypes();
// 獲取參數(shù)列表上的注解 @Param
final Annotation[][] paramAnnotations = method.getParameterAnnotations();
// 該集合用于記錄參數(shù)索引與參數(shù)名稱的對(duì)應(yīng)關(guān)系
final SortedMap map = new TreeMap();
int paramCount = paramAnnotations.length;
// 遍歷所有參數(shù)
for (int paramIndex = 0; paramIndex < paramCount; paramIndex++) {
if (isSpecialParameter(paramTypes[paramIndex])) {
// 如果參數(shù)是RowBounds類型或者ResultHandler類型,則跳過該參數(shù)
continue;
}
String name = null;
// 遍歷該參數(shù)上的注解集合
for (Annotation annotation : paramAnnotations[paramIndex]) {
if (annotation instanceof Param) {
// 獲取@Param注解指定的參數(shù)名稱
hasParamAnnotation = true;
name = ((Param) annotation).value();
break;
}
}
// 沒有@Param注解的話 執(zhí)行下面邏輯
if (name == null) {
// useActualParamName==true時(shí) 即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", ...)
// 使用參數(shù)的索引作為其名稱
name = String.valueOf(map.size());
}
}
map.put(paramIndex, name);
}
names = Collections.unmodifiableSortedMap(map);
}
names集合主要是在ParamNameResolver.getNamedParams方法中使用
/**
*
* @param args 用戶傳入的參數(shù)值列表
* @return
*/
public Object getNamedParams(Object[] args) {
final int paramCount = names.size();
if (args == null || paramCount == 0) {
return null;
} else if (!hasParamAnnotation && paramCount == 1) {// 未使用@Param注解且參數(shù)列表只有一個(gè)
return args[names.firstKey()];//即args[0] 參數(shù)的值
} else {
// 下面是為參數(shù)創(chuàng)建param+索引的格式作為默認(rèn)參數(shù)名稱 如:param1 下標(biāo)從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;
}
}
總結(jié):
1.如果接口方法有一個(gè)或多個(gè)參數(shù),并且使用了@Param注解,sql語(yǔ)句中的參數(shù)用注解的value值,
2.如果接口方法的參數(shù)只有一個(gè),并且沒有使用@Parma注解sql語(yǔ)句直接使用任何名稱均可。
3.如果接口的方法有多個(gè)參數(shù),并且沒有使用@Parma注解,sql語(yǔ)句使用param1...paramn是不會(huì)錯(cuò)的。
4.sql語(yǔ)句中的參數(shù)占位符名稱和接口方法的參數(shù)名稱沒有什么關(guān)系。
總結(jié)
以上是生活随笔為你收集整理的get占位符传多个参数_mybatis多个参数(不使用@param注解情况下),sql参数占位符正确写法...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 李翊君怎么读 李翊君是谁
- 下一篇: java 头像 微信群_java怎么生成