将查询结果映射到Java中的POJO构造函数

时间:2015-04-03 21:17:13

标签: java database orm

我有一组SQL查询和一个带有构造函数的相应POJO对象。

实施例。

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

目前,我手动将结果集中的列映射到字段。我想使这个通用,所以我可以做一些像新学生(rs.getRow()),然后我可以通过某种配置文件映射它。选择查询中可能有N个字段,并且顺序不一定与构造函数中定义的顺序匹配。

我想控制SQL,因为它可能有很多连接,所以我不确定ORM是否可以在这里工作。我严格地想要一些可以将结果集列映射到字段的东西。

我想在我的Student类中添加注释以进行映射

8 个答案:

答案 0 :(得分: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中进行更改,就必须在此方法中进行相应的更改。

答案 1 :(得分:1)

这看起来像是使用JPA或类似ORM技术的地方的教科书示例。

但是,如果您只是使用注释进行此操作,则可以创建自己的注释 - http://www.mkyong.com/java/java-custom-annotations-example/是一个非常好的教程。

您可以创建自己的@DatabaseField注释,用它来注释对象的字段,指定相应的数据库字段。然后,在构造函数中,获取您的类(Class klass = this.getClass()),获取其上的声明字段(klass.getDeclaredFields()),并为其中的每一个,查看声明的注释(field.getDeclaredAnnotations())。对于其中的每一个,如果它们是您的自定义数据库字段注释,请记下映射。一旦你完成了所有领域,你就会有一个数据库列的字段映射,然后你可以继续使用反射进行设置(你有的Field对象有一个set方法,你就可以了)用&#34; this&#34;(正在构造的对象)和结果集得到的值来调用它。

可能是一项有趣的练习,但我仍然认为你最好使用JPA或者像SimpleORM这样重量较轻的ORM之一。

答案 2 :(得分: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;
} }

您可以使用以下代码在Student类中设置相应的值。

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();
    }
}}

如果您遇到任何问题,请告诉我。很高兴为您提供帮助。

答案 3 :(得分:0)

如果您的查询结果将成为像Student这样的域对象(永远不要在FROM语句中加入多少个连接),那么ORM可以正常工作,也许它是一个很好的解决方案。如果您要提取一些复杂的数据结构,那么您可以查看一些Spring功能,如RowMapper。

答案 4 :(得分:0)

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

refer

答案 5 :(得分: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));               
          }
        }       
    }
}

您还应该将字段映射到colum类型,例如我只使用了getString。

答案 6 :(得分:0)

使用HIbernate SQLQuery addScalar()示例http://www.journaldev.com/3422/hibernate-native-sql-example-addscalar-addentity-addjoin-parameter-example

这将完全将结果集设为POJO对象。您可以稍后遍历它以获取数据。

如果这有助于您,请告诉我。

答案 7 :(得分:0)

假设您的学生表如下。

__________________________
|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();
                }

            }
        }
    }
}