前言
在 MyBatis 中,ParameterHandler 是四大核心组件之一,负责将 Java 方法的参数解析成 SQL 语句中的参数。在本文中,我们将详细介绍 ParameterHandler 的源码,并解释复杂对象作为参数时一个和多个的区别和原因。
ParameterHandler 接口
ParameterHandler 接口定义了参数解析器的基本方法,包括:
setParameters(PreparedStatement ps):将 Java 方法的参数设置到 PreparedStatement 中。
getParameterObject():获取 Java 方法的参数对象。
getParameterType():获取 Java 方法的参数类型。
DefaultParameterHandler 类
DefaultParameterHandler 类是 ParameterHandler 接口的默认实现,它提供了参数解析的默认实现。
DefaultParameterHandler 类中包含了两个重要的成员变量:
parameterObject:Java 方法的参数对象。
mappedStatement:当前正在执行的 SQL 语句的映射语句。
setParameters 方法
setParameters 方法是 ParameterHandler 接口的核心方法,它负责将 Java 方法的参数设置到 PreparedStatement 中。setParameters 方法的实现如下:
@Override public void setParameters(PreparedStatement ps) throws SQLException { // 获取 Java 方法的参数对象 Object parameterObject = getParameterObject(); // 获取当前正在执行的 SQL 语句的映射语句 MappedStatement mappedStatement = getMappedStatement(); // 获取 SQL 语句中的参数映射 List<ParameterMapping> parameterMappings = mappedStatement.getParameterMappings(); // 遍历参数映射 for (int i = 0; i < parameterMappings.size(); i++) { // 获取参数映射 ParameterMapping parameterMapping = parameterMappings.get(i); // 获取参数值 Object value = getParameterValue(parameterMapping, parameterObject); // 设置参数值 ps.setObject(i + 1, value); } }
getParameterValue 方法
getParameterValue 方法负责获取参数值。getParameterValue
方法的实现如下:
private Object getParameterValue(ParameterMapping parameterMapping, Object parameterObject) { // 获取参数类型 Class<?> parameterType = parameterMapping.getJavaType(); // 获取参数名称 String parameterName = parameterMapping.getProperty(); // 获取参数值 Object value = null; if (parameterType == String.class) { value = (String) parameterObject; } else if (parameterType == Integer.class) { value = (Integer) parameterObject; } else if (parameterType == Long.class) { value = (Long) parameterObject; } else if (parameterType == Float.class) { value = (Float) parameterObject; } else if (parameterType == Double.class) { value = (Double) parameterObject; } else if (parameterType == Date.class) { value = (Date) parameterObject; } else if (parameterType == byte[].class) { value = (byte[]) parameterObject; } else { // 如果参数类型是复杂类型,则需要使用反射获取参数值 try { Field field = parameterObject.getClass().getDeclaredField(parameterName); field.setAccessible(true); value = field.get(parameterObject); } catch (NoSuchFieldException e) { throw new RuntimeException("Error getting parameter value: " + e.getMessage()); } catch (IllegalAccessException e) { throw new RuntimeException("Error getting parameter value: " + e.getMessage()); } } // 返回参数值 return value; }
这两个方法结合起来完成了将 Java 方法的参数解析并设置到 PreparedStatement 的过程。
结语
通过深入理解 MyBatis 中 ParameterHandler 的源码,我们能够更好地把握参数解析的机制,提高 SQL 语句的执行效率。同时,了解复杂对象作为参数时的处理方式,能够更灵活地应对各种场景。在实际应用中,合理地使用参数映射规范,能够使 SQL 语句更加清晰易读,提高开发效率。
开源项目
- SpringCloud + Vue3 微服务商城
Github | Gitee | |
后端 | youlai-mall🍃 | youlai-mall🍃 |
前端 | mall-admin🌺 | mall-admin🌺 |
移动端 | mall-app🍌 | mall-app🍌 |
SpringBoot 3+ Vue3 单体权限管理系统
Github | Gitee | |
后端 | youlai-boot🍃 | youlai-boot🍃 |
前端 | vue3-element-admin🌺 | vue3-element-admin🌺 |