- 使用setObject方法填充占位符时,setObject会判断实际传入的参数类型,进行参数转换,例如,如果是String类型,则会在参数开始和结尾追加 ',setString的源码
parameterAsBytes = null;
buf = new StringBuilder(x.length() + 2);
buf.append('\'');
buf.append(x);
buf.append('\'');
- 如果是传入的参数是java.sql.Date类型,还会将时间戳自动转为字符串
这里创建了timestamp对象
else if (this.connection.getTreatUtilDateAsTimestamp() && parameterObj instanceof Date) {
this.setTimestamp(parameterIndex, new Timestamp(((Date)parameterObj).getTime()));
}
同时转换成了字符串格式。
this.tsdf = TimeUtil.getSimpleDateFormat(this.tsdf, "''yyyy-MM-dd HH:mm:ss", (Calendar)null, (TimeZone)null);
Calendar adjCal = TimeUtil.setProlepticIfNeeded(this.tsdf.getCalendar(), targetCalendar);
if (this.tsdf.getCalendar() != adjCal) {
this.tsdf.setCalendar(adjCal);
}
StringBuffer buf = new StringBuffer();
buf.append(this.tsdf.format(x));
if (fractionalLength > 0) {
int nanos = x.getNanos();
if (nanos != 0) {
buf.append('.');
buf.append(TimeUtil.formatNanos(nanos, this.serverSupportsFracSecs, fractionalLength));
}
}
buf.append('\'');
this.setInternal(parameterIndex, buf.toString());
PreparedStatement ps = connection.prepareStatement("select * from sys_role where create_time > ? and id = ?");
ps.setObject(1,new Date(4454546464l));
ps.setObject(2,10);
- getObject方法返回的是当前列在数据库的存储类型对应的Java类型
通过 ResultSetMetaData metaData = resultSet.getMetaData();可以获取到结果集的元数据信息
-
getColumnCount 获取一共返回了多少列(可根据这个属性动态遍历)
-
getColumnLable 获取sql执行结果的别名,如果没有别名,则获取的是原始的列名。
-
getColumnTypeName 获取当前列在数据库对应的类型,ResultSet可根据数据库类型与Java类型的一一对应关系创建Java类型的值,getObject方法的核心。
-
getColumnClassName 获取该列对应的在Java中的数据类型。
所以在如下通过反射为某个对象的属性赋值时,对象的该属性类型还是要和这一列的getColumnClassName 对应上,否则还是会抛出异常。
Object object = resultSet.getObject(i + 1);
Field declaredField = Role.class.getDeclaredField(columnName);
declaredField.setAccessible(true);
declaredField.set(role,object);
Exception in thread "main" java.lang.IllegalArgumentException: Can not set java.lang.String field com.example.demo.entity.Role.id to java.lang.Long
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
at java.lang.reflect.Field.set(Field.java:764)
at com.example.demo.jdbc.JdbcTest.main(JdbcTest.java:38)
数据库的datetime对应Java的TimeStamp,但是在类中声明的属性类型为java.util.Date,发现也能赋值成功。
原来是打开Date类一看,发现sql包下的TimeStamp和Date继承了java.util.Date,这样就可以顺理成章的赋值了。