<selectid="getByLastName"resultType="com.clay.mybatis.bean.Employee"> select id, last_name as lastName, gender, email from t_employee where last_name like concat('%', #{lastName}, '%') </select>
<selectid="getEmpById"parameterType="Long"resultType="com.clay.mybatis.bean.Employee"> select id, last_name as lastName, gender, email from t_employee where id = #{id} </select>
<selectid="getEmpByIdAndEmail"resultType="com.clay.mybatis.bean.Employee"> select id, last_name as lastName, gender, email from t_employee where id = #{param1} and email = #{param2} </select>
<selectid="getEmpByIdAndEmailByAnnotation"resultType="com.clay.mybatis.bean.Employee"> select id, last_name as lastName, gender, email from t_employee where id = #{id} and email = #{email} </select>
<selectid="getEmpByIdAndEmailByMap"resultType="com.clay.mybatis.bean.Employee"> select id, last_name as lastName, gender, email from t_employee where id = #{id} and email = #{email} </select>
</mapper>
提示
如果有多个参数且都不是业务模型中的数据,但是会经常使用,此时不建议使用 Map 来封装参数,而是推荐编写 DTO(Data Transfer Object)数据传输对象来封装多个参数。
/** * Copyright 2009-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.ibatis.reflection;
/** * <p> * The key is the index and the value is the name of the parameter.<br /> * The name is obtained from {@link Param} if specified. When {@link Param} is not specified, * the parameter index is used. Note that this index could be different from the actual index * when the method has special parameters (i.e. {@link RowBounds} or {@link ResultHandler}). * </p> * <ul> * <li>aMethod(@Param("M") int a, @Param("N") int b) -> {{0, "M"}, {1, "N"}}</li> * <li>aMethod(int a, int b) -> {{0, "0"}, {1, "1"}}</li> * <li>aMethod(int a, RowBounds rb, int b) -> {{0, "0"}, {2, "1"}}</li> * </ul> */ privatefinal SortedMap<Integer, String> names;
privateboolean hasParamAnnotation;
publicParamNameResolver(Configuration config, Method method){ this.useActualParamName = config.isUseActualParamName(); 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 annotations for (int paramIndex = 0; paramIndex < paramCount; paramIndex++) { if (isSpecialParameter(paramTypes[paramIndex])) { // skip special parameters continue; } String name = null; for (Annotation annotation : paramAnnotations[paramIndex]) { if (annotation instanceof Param) { hasParamAnnotation = true; name = ((Param) annotation).value(); break; } } if (name == null) { // @Param was not specified. if (useActualParamName) { name = getActualParamName(method, paramIndex); } if (name == null) { // use the parameter index as the name ("0", "1", ...) // gcode issue #71 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); }
/** * Returns parameter names referenced by SQL providers. * * @return the names */ public String[] getNames() { return names.values().toArray(new String[0]); }
/** * <p> * A single non-special parameter is returned without a name. * Multiple parameters are named using the naming rule. * In addition to the default names, this method also adds the generic names (param1, param2, * ...). * </p> * * @param args * the args * @return the named params */ public Object getNamedParams(Object[] args){ finalint paramCount = names.size(); if (args == null || paramCount == 0) { returnnull; } elseif (!hasParamAnnotation && paramCount == 1) { Object value = args[names.firstKey()]; return wrapToMapIfCollection(value, useActualParamName ? names.get(0) : null); } 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()]); // add generic param names (param1, param2, ...) final String genericParamName = GENERIC_NAME_PREFIX + (i + 1); // ensure not to overwrite parameter named with @Param if (!names.containsValue(genericParamName)) { param.put(genericParamName, args[entry.getKey()]); } i++; } return param; } }
/** * Wrap to a {@link ParamMap} if object is {@link Collection} or array. * * @param object a parameter object * @param actualParamName an actual parameter name * (If specify a name, set an object to {@link ParamMap} with specified name) * @return a {@link ParamMap} * @since 3.5.5 */ publicstatic Object wrapToMapIfCollection(Object object, String actualParamName){ if (object instanceof Collection) { ParamMap<Object> map = new ParamMap<>(); map.put("collection", object); if (object instanceof List) { map.put("list", object); } Optional.ofNullable(actualParamName).ifPresent(name -> map.put(name, object)); return map; } elseif (object != null && object.getClass().isArray()) { ParamMap<Object> map = new ParamMap<>(); map.put("array", object); Optional.ofNullable(actualParamName).ifPresent(name -> map.put(name, object)); return map; } return object; }