在MySql中给一个用户Id字段设置为Bigint类型,使用JDBC在完成ORM的时候,以为其可以自动转换为Integer,因为我的POJO类id使用的就是Integer。但事实是,我在测试的时候,发现报错,明明数据库中id是有值的,为什么取不到?原因在于MySql的Bigint类型映射为Java类型中的 java.lang.Long类型,并不是我简单认为的 Integer ,还会报一个错误:
java.lang.IllegalArgumentException: Can not set java.lang.Integer field com.jacob.pojo.User.id to java.lang.Long
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
at java.base/java.lang.reflect.Field.set(Field.java:780)
就是说Bigint的字段不能set进Integer类型的属性中.
如果使用原生的JDBC来封装数据,在这个id字段上,直接使用rs.getInt进我们的Integer字段是没有问题的:
public List<User> findList2() throws Exception {Connection connection=null;PreparedStatement ps=null;ResultSet rs=null;List<User> list=null;try {connection = super.getConnection();String sql="select eu_user_id from easybuy_user";ps = connection.prepareStatement(sql);rs = ps.executeQuery();list = new ArrayList<User>();while(rs.next()){User user=new User();user.setEu_user_id(rs.getInt("eu_user_id"));list.add(user);}} catch (Exception e) {e.printStackTrace();}finally{super.closeAll(connection, ps, rs);}return list;}
那么为什么我会出现这个错误呢?
我使用一个进行简单封装的BaseDao,它的查询使用的反射来做的,因为每个POJO类的属性类型不一致
// @Description: TODO 不同表的通用的查询操作,返回表中的一条记录,考虑上事务public static <T> T getInstance(Connection conn, Class<T> clazz, String sql, Object... args) {PreparedStatement ps = null;ResultSet rs = null;try {conn = dbUtils.getConnection();ps = conn.prepareStatement(sql);for (int i = 0; i < args.length; i++) {ps.setObject(i + 1, args[i]);}rs = ps.executeQuery();// 获取结果集的元数据ResultSetMetaData rsmd = rs.getMetaData();// 通过ResultSetMetaData获取结果集的列数int columnCount = rsmd.getColumnCount();if (rs.next()) {//通过反射,获取T的实例对象tT t = clazz.newInstance();// 处理结果集一行数据的每一个列for (int i = 0; i < columnCount; i++) {Object columvalue = rs.getObject(i + 1);// 获取每个列的列名String columnLambel = rsmd.getColumnLabel(i + 1); //这里要判断下columvalue是不是null,在你的数据库表中,很有可能某列是null。
//然后columvalue.toString()出现空指针 if(columvalue!=null){if("java.lang.Long".equals(columvalue.getClass().getName())){columvalue=Integer.parseInt(columvalue.toString());}}// 给t对象指定的某个属性(成员变量),赋值为columvalueField field = clazz.getDeclaredField(columnLambel);field.setAccessible(true);field.set(t, columvalue);}return t;}} catch (Exception e) {e.printStackTrace();} finally {//连接先不关,业务层再关dbUtils.closeResource(null, ps, rs);}return null;}