2015-04-03 92 views
0

我有一組SQL查詢和一個帶有構造函數的相應POJO對象。將查詢結果映射到Java中的POJO構造函數

Ex。

Student student = new Student(rs.getString("FNAME"), rs.getString("LNAME"), rs.getString("GRADE")); 

當前我將結果集中的列手動映射到字段。我想使這個通用,所以我可以做一些像新的學生(rs.getRow()),然後我可以通過某種配置文件映射它。在選擇查詢中可能有N個字段,順序不一定與構造函數中定義的順序相匹配。

我想控制SQL,因爲它可能有很多連接,所以我不確定ORM是否可以在這裏工作。我嚴格希望能夠將結果集列映射到一個字段。

我想在我的學生類添加註解映射

回答

0

它並不完美,但看看這個:

public class Student { 
    private String name; 
    private Integer age; 
    //etc. 

    public Student() { 
     //default constructor 
    } 

    public Student(final ResultSet rs) throws Exception { 
     ResultSetMetaData rsmd = rs.getMetaData(); 
     int columnCount = rsmd.getColumnCount(); 

     for (int i = 1; i < columnCount + 1; i++) { 
      String name = rsmd.getColumnName(i); 

      if (Student.getField(name)) { 
       Student.getField(name).set(rs.getString(name));    
      } 
     }  
    } 
} 

你也應該映射領域科拉姆類型,例如,在這裏我只使用的getString。

0

如果查詢的結果將是一些領域的物體,像學生(請不要介意有多少FROM語句連接的),那麼ORM會工作得很好,也許這是好的解決方案如果你要提取一些複雜的數據結構,那麼你可以看看RowMapper等一些Spring特性。

2
public class StudentRowMapper implements RowMapper<YourStudentPojo> { 


@Override 
public YourStudentPojo mapRow(final ResultSet rs, final int arg1) throws SQLException { 

    final YourStudentPojo item = new YourStudentPojo(); 
    item.setFName(rs.getString("FNAME")); 

    return item; 

} 

與此FName類似,您可以在pojo中設置其他值。不需要構造函數。只要您在Pojo中進行更改,則必須在此方法中完成相應的更改。

0

您可以使用GSON序列化的對象映射。

refer

1

這似乎像使用JPA或類似的ORM技術的地方的一個典型例子。

但是,如果您只是對註釋做了這項工作,您可以創建自己的註釋 - http://www.mkyong.com/java/java-custom-annotations-example/是一個很好的教程。

你會創建自己的@DatabaseField註釋,你註釋與對象的字段,指定相應的數據庫字段。你會那麼,在構造函數中,把你的類(Klass類= this.getClass()),獲得聲明的字段就可以了(klass.getDeclaredFields()),併爲每個的,看看聲明註釋(場.getDeclaredAnnotations())。對於其中的每一個,如果它們是您的自定義數據庫字段註釋,請記下該映射。一旦你已經通過所有領域走了,你就會有一個地圖領域的數據庫列,然後你就可以繼續前進,使用反射設置的(你有Field對象上有一組方法,你會打電話與「這個「(正在構建的對象)以及結果集的值。

可能是一個有趣的練習,但我仍然認爲用JPA或更簡單的一個像SimpleORM這樣的ORM可能會更好。

1

你可以用Java反射做。 例如,我們將您的SQL查詢是這樣的。

SELECT FirstName 'FNAME', LastName 'LNAME', Grade 'GRADE' FROM Employee 

所以,你會得到的輸出爲以下

FNAME  LNAME   GRADE 

John   Dan    A+ 

然後在Java代碼中,你將需要反射來實現,其餘

假設你的學生類是這樣

public class Student { 

private String LNAME; 
private String FNAME; 
private String GRADE; 

public String getLNAME() { 
    return LNAME; 
} 
public void setLNAME(String lNAME) { 
    LNAME = lNAME; 
} 
public String getFNAME() { 
    return FNAME; 
} 
public void setFNAME(String fNAME) { 
    FNAME = fNAME; 
} 
public String getGRADE() { 
    return GRADE; 
} 
public void setGRADE(String gRADE) { 
    GRADE = gRADE; 
} } 

你可以使用下面的代碼設置在學生類的相應值。

import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
import java.util.HashMap; 


public class Main { 


    public static void main(String[] args) { 
     try { 
      //configuring the columns in the sql statement and class 
      String[] ColumnArray = new String[]{"LNAME","FNAME","GRADE"}; 

      // making a hashmap to emulate the result set of sql 
      HashMap<String, String> rs = new HashMap<String, String>(); 
      rs.put("FNAME", "John"); 
      rs.put("LNAME", "Dan"); 
      rs.put("GRADE", "A+"); 

      //reflection of the 
      Class cls = Class.forName("Student"); 
      Object c = cls.newInstance(); 
      Method[] mtd = cls.getMethods(); 
      for (String column : ColumnArray) { 
       Method method = cls.getMethod("set"+column, String.class); 
        method.invoke(c, new Object[]{rs.get(column)}); 
      } 
     //casting the class to employee 
     Student student = (Student) c; 

     //Printing the output 
     System.out.println(student.getFNAME()); 
     System.out.println(student.getLNAME()); 
     System.out.println(student.getGRADE()); 
    } catch (ClassNotFoundException e) { 
     e.printStackTrace(); 
    } catch (InstantiationException e) { 
     e.printStackTrace(); 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    }catch (NoSuchMethodException e) { 
     e.printStackTrace(); 
    } catch (SecurityException e) { 
     e.printStackTrace(); 
    } catch (IllegalArgumentException e) { 
     e.printStackTrace(); 
    } catch (InvocationTargetException e) { 
     e.printStackTrace(); 
    } 
}} 

請讓我知道你是否面臨任何問題。很高興幫助你。

0

假設您的STUDENT表如下。

__________________________ 
|STUDENT_ID | AGE | NAME | 
-------------------------- 
|   |  |  | 
|   |  |  | 
-------------------------- 

您必須擁有對SQL查詢的控制權。它的返回列必須根據POJO類的變量名稱重命名。所以SQL查詢將如下所示。

SELECT AGE AS age, NAME AS name from STUDENT; 

最後,POJO類的構造函數如下。它將遍歷類中的所有私有變量,並檢查這些列是否在ResultSet中可用。

import java.lang.reflect.Field; 
import java.lang.reflect.Method; 
import java.lang.reflect.Modifier; 
import java.sql.ResultSet; 

public class Student 
{ 
    private int age; 
    private String name; 

    public int getAge() 
    { 
     return age; 
    } 

    public void setAge(int age) 
    { 
     this.age = age; 
    } 

    public String getName() 
    { 
     return name; 
    } 

    public void setName(String name) 
    { 
     this.name = name; 
    } 

    public static void main(String[] args) 
    { 
     new Student(null); 
    } 

    public Student(ResultSet rs) 
    { 
     Field[] allFields = this.getClass().getDeclaredFields(); 
     for (Field field : allFields) 
     { 
      if (Modifier.isPrivate(field.getModifiers())) 
      { 
       String fieldName = field.getName(); 
       String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); 

       try 
       { 
        Method setterMethod = this.getClass().getMethod(methodName, field.getType()); 
        setterMethod.invoke(this, rs.getObject(fieldName)); 
       } 
       catch (Exception e) 
       { 
        e.printStackTrace(); 
       } 

      } 
     } 
    } 
}