Mybatis可以使用对象传参,也可以使用Map作为入参,我们也可以将对象转换成Map,作为一个通用的入参。以下为示例案例
import cn.hutool.core.util.ReflectUtil;
import com.test.ft.common.exception.CommonException;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class QueryParam extends HashMap<Object, Object> {
private static final long serialVersionUID = 1101074895437012210L;
/**
* 构建查询参数对象。
* 该方法通过反射,从传入的value对象中获取所有字段值,并根据一定条件过滤后,添加到QueryParam对象中。
*
* @param value 要构建查询参数的对象。该对象的字段会被反射读取并添加到查询参数中。
* @param filterNull 是否过滤掉值为null或者空字符串的字段。
* @param numberIsBiggerThanZero 是否过滤掉数值类型字段且值不大于0的字段。
* @param filterMap 是否过滤掉字段类型为Map的字段。
* @return QueryParam 查询参数对象,包含了从value对象中反射获取并经过过滤的字段及其值。
*/
public static QueryParam build(Object value, boolean filterNull, boolean numberIsBiggerThanZero, boolean filterMap) {
QueryParam param = new QueryParam();
Field[] fields = ReflectUtil.getFields(value.getClass());
try {
for (Field field : fields) {
field.setAccessible(true);
Object o = field.get(value);
// 过滤掉null值
if (filterNull && (Objects.isNull(o) || StringUtils.isBlank(o.toString()))) {
continue;
}
// 过滤掉静态字段
if (Modifier.isStatic(field.getModifiers())) {
continue;
}
if (numberIsBiggerThanZero && o instanceof Number && !isNotNullAndBigZero((Number) o)) {
continue;
}
if (Map.class.isAssignableFrom(field.getType())) {
if (filterMap) {
continue;
}
param.putAll((Map<?, ?>) o);
continue;
}
param.put(field.getName(), o);
}
} catch (IllegalAccessException e) {
throw new CommonException("Accessing field values failed", e);
}
return param;
}
/**
* 构建一个QueryParam对象,专门处理值为null的情况。
*
* @param value 拟作为QueryParam对象属性的值,此方法中该值将被忽略,因为专门处理null值。
* @return 返回一个QueryParam实例,其内部状态根据此方法的特定逻辑配置。
*/
public static QueryParam buildWithNull(Object value) {
return build(value, false, false, false);
}
public static QueryParam buildNonNull(Object value) {
return build(value, true, false, false);
}
/**
* 构建一个非空且大于零的查询参数。
*
* @param value 参数的值,该值将被用于构建查询参数,必须是非空且大于零的数值。
* @return 返回一个配置好的查询参数对象,确保了参数的非空性和数值大于零的条件。
*/
public static QueryParam buildNonNullAndBiggerThanZero(Object value) {
return build(value, true, true, false);
}
public static QueryParam buildNonNullAndFilterMap(Object value) {
return build(value, true, true, true);
}
public static boolean isNotNullAndBigZero(Number number) {
return (number != null && isBigThanZero(number));
}
private static boolean isBigThanZero(Number number) {
if (number instanceof Integer) {
return (Integer) number > 0;
} else if (number instanceof Long) {
return (Long) number > 0L;
} else if (number instanceof Short) {
return (Short) number > 0;
} else if (number instanceof Byte) {
return (Byte) number > 0;
} else if (number instanceof BigInteger) {
return ((BigInteger) number).compareTo(BigInteger.ZERO) > 0;
} else if (number instanceof Double) {
double value = (Double) number;
return value >= 1e-6 && Math.abs(value) >= 1e-6; // 考虑到小数点后位数可能有限制,使用近似值进行比较
} else if (number instanceof Float) {
float value = (Float) number;
return value >= 1e-5f && Math.abs(value) >= 1e-5f; // 浮点数也需要考虑小数点后位数的影响
} else if (number instanceof BigDecimal) {
return ((BigDecimal) number).compareTo(BigDecimal.ZERO) > 0;
} else {
throw new IllegalArgumentException("Unsupported type of number");
}
}
}
在Mapper中的使用:
public interface BOrderMapper {
List<TestVo> getBOrderList(@Param("param") QueryParam param);
}
在xml里面的使用示例:
<select id="getBOrderList" resultType="com.test.ft.common.vo.TestVo">
select distinct
(case
when bo.resume_type = 1 then '在线'
when bo.resume_type = 2 then '线下'
else '未知'
end
) as resumeTypeName
from
b_order bo
where
bo.id >= #{param.id} <!-- 查询id时使用传入的参数 -->
</select>
以上为使用对象构造Mybatis通用入参的简单使用