java反射可通过getparametertypes()获取方法参数类型,映射到preparedstatement对应setxxx方法实现强类型绑定,需统一处理基本类型与包装类、null值、时间类型及泛型等细节。

Java 反射可以获取方法的参数类型,再根据类型选择对应的 JDBC PreparedStatement#setXxx() 方法完成强类型绑定。核心是:通过 Method#getParameterTypes() 获取参数类,映射到 JDBC 的 set 方法(如 String → setString、int → setInt),再用 Method.invoke() 调用。
获取目标方法的参数类型
使用反射拿到待调用的方法对象后,调用 getParameterTypes() 得到参数类型的 Class 数组:
- 例如
public void setId(int id)返回[int.class] -
public void setName(String name)返回[String.class] - 注意基本类型(
int、boolean)和包装类(Integer、Boolean)需统一处理,推荐转为包装类再匹配
建立 Java 类型到 JDBC setXxx 方法的映射
不是所有 Java 类型都有直接对应的 setXxx,需按语义归类。常见映射如下:
String.class → setString(int, String)Integer.class / int.class → setInt(int, int)Long.class / long.class → setLong(int, long)Boolean.class / boolean.class → setBoolean(int, boolean)-
java.time.LocalDate.class → setObject(int, LocalDate, JDBCType.DATE)(需 JDBC 4.2+) -
java.sql.Date.class / Timestamp.class → setDate(int, Date)或setTimestamp(int, Timestamp) -
null值统一用setNull(int, Types.VARCHAR)等,配合具体 SQL 类型
动态调用 setXxx 方法并传参
不硬编码 switch,可用 Map 存储 Class → setMethod 映射,或用工具方法判断后反射调用:
- 预先缓存常用
PreparedStatement的 set 方法(如setString),避免每次反射查找开销 - 对每个参数索引
i,取值args[i],根据其运行时类型(obj.getClass())查映射,再调用对应invoke(preparedStatement, i + 1, obj) - 若值为
null,跳过类型匹配,直接调用setNull(i + 1, sqlType),其中sqlType可从字段元数据或约定默认值(如Types.VARCHAR)获取
处理泛型与复杂类型(如 List、自定义对象)
反射无法直接获取泛型实际类型,普通参数类型匹配不覆盖集合或嵌套对象:
- 遇到
List<string></string>,不能直接 set,应拆解为多个setString或转为 JSON 字符串存储(需数据库支持) - 自定义 POJO 类型建议不直接绑定,而是提取其字段值(递归反射)再逐个绑定,或交由 ORM 框架(如 MyBatis)处理
- 为简化,可约定仅支持基础类型、时间类型、数组(如
String[]→setArray)、以及byte[](→setBytes)
不复杂但容易忽略细节:参数索引从 1 开始、null 值需显式 setNull、时间类型注意时区和 JDBC 版本兼容性。做好类型映射表和异常兜底(如未知类型 fallback 到 setObject),就能安全实现强类型绑定。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











