get占位符传多个参数_mybatis多个参数(不使用@param注解情况下),sql参数占位符正确写法...
useActualParamName配置
useActualParamName
允許使用方法簽名中的名稱作為語句參數名稱。 為了使用該特性,你的工程必須采用Java 8編譯,并且加上-parameters選項。(從3.4.1開始)
true | false
true
mybatis的全局配置useActualParamName決定了mapper中參數的寫法,默認為true
代碼展示:
@Test
public void findUserById() {
SqlSession sqlSession = getSessionFactory().openSession();
UserDao userMapper = sqlSession.getMapper(UserDao.class);
User user = userMapper.findUserById(1,"lpf");
Assert.assertNotNull("沒找到數據", user);
}
public interface UserDao {
User findUserById (int id,String name);
}
1.如果useActualParamName設置為true時
傳遞參數需要使用
#{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設置為false時
傳遞參數需要使用
#{0}-#{n}或者#{param1}-#{paramn}
select * from m_user where id = #{0} and name =#{1}
或者
select * from m_user where id = #{param1} and name =#{param2}
下面是多個參數的錯誤寫法直接寫參數名(如果方法只有一個參數是可以用參數名代替的,其實如果只有一個參數,任何名稱都是可以的)
select * from m_user where id = #{id} and name =#{name}
源碼解讀(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;
}
}
總結:
1.如果接口方法有一個或多個參數,并且使用了@Param注解,sql語句中的參數用注解的value值,
2.如果接口方法的參數只有一個,并且沒有使用@Parma注解sql語句直接使用任何名稱均可。
3.如果接口的方法有多個參數,并且沒有使用@Parma注解,sql語句使用param1...paramn是不會錯的。
4.sql語句中的參數占位符名稱和接口方法的參數名稱沒有什么關系。
總結
以上是生活随笔為你收集整理的get占位符传多个参数_mybatis多个参数(不使用@param注解情况下),sql参数占位符正确写法...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 李翊君怎么读 李翊君是谁
- 下一篇: java 头像 微信群_java怎么生成