具有反射

时间:2016-03-14 16:55:38

标签: java sql-server generics reflection

我试图从结果集中获取一个值,然后通过特定类中setMethod的反射设置该值。当我的结果集在MSSQL中返回一个smallint列并且它试图将该smallint转换为Integer时,我遇到了一个问题(这就是我的set方法需要的那个pojo的int)。

            ResultSetMetaData md = rs.getMetaData();
            int columns = md.getColumnCount();
            ArrayList<T> results = new ArrayList<>(rs.getFetchSize());

            T obj = klass.newInstance();
            CaseInsensitiveMap map = getInsensitiveMethodMap(obj.getClass());
            while (rs.next()) {
                for (int i = 1; i <= columns; ++i) {
                    String columnName = SqlValue.SET_LOWER + md.getColumnName(i);
                    Method m = (Method) map.get(columnName);
//                    Object test = rs.getObject(i, m.getParameterTypes()[0]);
//                    System.out.println(columnName + " " + rs.getObject(i));
                    m.invoke(obj, rs.getObject(i, m.getParameterTypes()[0]));
                }
                results.add(obj);
                obj = klass.newInstance();
            }
            return results;

正如您所看到的,我正在尝试使用ResultSet.getObject(Integer,Class),我从方法参数类型获取类。目前我收到错误说&#34; java.sql.SQLFeatureNotSupportedException:不支持此操作。&#34;有没有办法做到这一点?能够从结果集中动态获取指定的类型值吗?

2 个答案:

答案 0 :(得分:1)

好的,以下是我为EasyORM库(github.com/IvanGH2/EasyORM/releases)编写的代码的一部分,它几乎完成了您尝试实现的目标。< / p>

   public <T> List<T> getRecordsForSingleTable( Class<? extends DBObject> target, int startRecord, int countRecord,String orderByColumn ) throws EasyORMException {
    T obj=null;
    ResultSet rs=null;
    PreparedStatement stmt=null;
    AnnotationUtil.checkTableAnnotation(target);
    List<T> objList = new ArrayList<T>();
    countRecord = (countRecord<=0)?recNum:countRecord;
    startRecord = (startRecord<0)?0:startRecord;
    String qualifiedName = dbSchema!=null?dbSchema+"."+target.getAnnotation(TableInfo.class).tableName():target.getAnnotation(TableInfo.class).tableName();
    String query=null;
    if(orderByColumn!=null&&!orderByColumn.isEmpty())
        query=modifyQuery(qualifiedName, startRecord, countRecord, orderByColumn);
    else
        query="SELECT * FROM "+qualifiedName;
    try{
        sqlQuery = query;
        stmt=conn.prepareStatement(query);
        rs = stmt.executeQuery();

        while(rs.next()){
            obj = (T) target.getConstructor(ResultSet.class).newInstance(rs);
            ((DBObject)obj).setConnection(conn);
            objList.add(obj);
        }
    }catch(Exception e){
        throw new EasyORMException(e);
    } finally{
        closeResources(rs,stmt);
    }
    return objList;
}

POJO类应该有一个接受ResultSet的构造函数(在我的实现中,每个POJO扩展DBObject)

//this constructor will be called for whenever creating objects via   reflection from a ResultSet    
 public DBObject(ResultSet rs) throws EasyORMException{
    try{
        for (int i=1;i<=rs.getMetaData().getColumnCount();i++) {
            Object obj=rs.getObject(i);
            if(obj instanceof Clob){
                cachedResults.put(rs.getMetaData().getColumnName(i), clobToString((Clob)obj));
            }else if(obj instanceof Blob){
                cachedResults.put(rs.getMetaData().getColumnName(i), (Blob)obj);
            }else if(obj instanceof String && stringEncoding != null ) {
                try{
                    cachedResults.put(rs.getMetaData().getColumnName(i), new String(((String)obj).getBytes(stringEncoding),stringEncoding));
                }catch(UnsupportedEncodingException e){
                    throw new EasyORMException(e);
                }
            }else{
                cachedResults.put(rs.getMetaData().getColumnName(i), obj);
            }

        }
    }catch (Exception e) {
        throw new EasyORMException(e);
    }
}

这基本上就是你所需要的。或者,使用no-args构造函数,但创建一个接受ResultSet的方法。

请注意,cachedResults是一个HashMap,因为我的getter / setter使用HashMap(这使得更新变得更容易,但您的实现可以使用访问私有成员字段的普通getter / setter)

答案 1 :(得分:-1)

来自MS的那些人不是很酷的JDBC驱动程序 这是sqljdbc42.jar的截图: com.microsoft.sqlserver.jdbc.SQLServerResultSet #getObject(int,java.lang.Class) https://screencloud.net/v/z271

使用SQL Server的方法是不可能的。 而且这不是他们唯一不支持的事情。