将ResultSet映射到Pojo对象

5

非常尴尬,我已经创建了一个标准的POJO类和用于数据检索的DAO类。我现在遇到了一些困难,不知道如何处理自定义查询数据并将其转换为POJO类。

例如,我的用户类如下:

public class User{

private int userId;
private String username;
private int addressId;

}

public class Address{
private int addressId;
private String zip;
}
public class UserDAO{

public void getUserDetails(){

String getSql = select u.userId, u.username, a.zipcode from user u, address a where u.addressId =     a.addressId;

 //no pojo class is now specific to the resultset returned. so we can't map result to pojo object
}

}

现在我应该如何使用我的POJO类来建模,如果使用String来管理,则面向对象的概念将消失,未来的复杂性也会增加。请您指导!

进一步解释的更新

我们知道可以使用同一个POJO类映射相同的表对象,但是当查询被自定义并且返回的数据不映射到任何特定的类时,应该采取什么措施? 即,我们应该创建另一个类还是将该数据抛弃在字符串变量中? 请给出一些示例。


1
JPA 实现了对象/关系映射。可以尝试使用 NetBeans IDE,结合 eclipseLink for JPA,从数据库生成类。在 netbeans.org 上有一些很好的 NetBeans 教程。 - Joop Eggen
@JoopEggen 我已经更新了我的问题以便更好地解释。 - iCurious
除了目前的两个答案,用于连接表和进行计算,您可以创建一个带有虚拟字段的数据库视图。而且该视图也可以有一个POJO。这取决于查询的自然程度;视图越自然,就越好。特别是在过度规范化的数据库中,视图可以带来好处。 - Joop Eggen
请参考以下问题/答案,其中展示了如何使用JPA将自定义查询映射到非实体POJO。https://dev59.com/rGcs5IYBdhLWcg3wPxnN - Ian McLaird
4个回答

4

为此,您可以使用JPA的实现之一。但是,如果您想手动完成它,我将给出一个简单的示例。

更新:

public class User {
   private int userId;
   private String username;
   private Address address; // USE POJO not ID
}

public class Address{
   private int addressId;
   private String zip;
   List<User> users;
}
    public User getUserById(Connection con, long userId) {
        PreparedStatement stmt;
        String query = "select u.user_id, u.user_name, a.id, a.zip from user u, address a where a.address_id = u.id and u.id = ?";
        User user = new User();
        Address address = new Address;
        try {
            stmt = con.prepareStatement(query);
            stmt.setLong(1, userId);
            ResultSet rs = stmt.executeQuery();
            address.setId(rs.getInt("id"));
            address.setZip(rs.getString("zip");
            user.setId(rs.getInt("id"));
            user.setUsername(rs.getString("user_name"));
            user.setAddressId(rs.getInt("address_id"));
            user.setAddress(address); // look here
        } catch (SQLException e) {
            if (con != null) {
                try {
                    System.err.print("Transaction is being rolled back");
                    con.rollback();
                } catch (SQLException excep) {
                }
            }
        } finally {
            if (stmt != null) {
                stmt.close();
            }
        }
        return user;
    }

你不应该为该查询创建新的POJO,而是应编写普通的查询语句。记住:你的对象模型是主要的,在数据库中的表只是保存应用程序数据的一种方式。


1
非常感谢!@Divers。这正是我正在寻找的东西。未来,我一定会检查其他人提到的概念和框架。感谢阿拉。 - iCurious

2
我们知道可以使用同一POJO类映射相同表对象,但当查询被定制化且返回的数据不与任何特定的类相对应时,应该采取什么样的程序呢?也就是说,我们需要创建另一个类吗?
JPA动态实例化允许您使用仅指定要从数据库中获取的字段和类型的构造函数定义查询的POJO。
这将执行JPA选择,返回一个列表。如果您需要稍后更改查询并且列未更改,则POJO仍将起作用。如果更改了列,则相应地更改POJO。
注意: 必须指定完全限定的包和构造函数参数。 类型User必须是JPA映射或JPA注释实体类。 entityManager在JPA EntityManagerFactory中。
TypedQuery<User> q; 
String sql = "select new com.stuff.User(
int u.userId, String u.username, String a.zipcode) 
from User u, Address a where u.addressId = a.addressId";
List<User> list = entityManager.createQuery(sql).getResultList();

for(User u : list) {
  doStuff(u);
}

动态实例化在你想要选择指定列,但避免那些包含大量数据的列(如BLOB类型)时也非常方便。例如,您可能希望获得代表完全填充的事物的代理POJO列表,但它们本身并未完全填充。您可以显示代理列表,并在用户选择一个时执行另一个查询以获取完全填充的对象。
具体情况因人而异。

0

有很多ORM框架可以做到这一点,包括HibernatemyBatisJPAspring-JDBC

spring-jdbc和myBatis可以对SQL进行细粒度控制,而JPA和Hibernate通常将你从SQL中抽象出来。

我建议你先阅读一些资料,弄清楚哪个框架适合你,在自己解决方案之前。


1
我没有使用任何框架,我想在Eclipse中完成它。你能提供一些例子吗?先谢谢了。 - iCurious
所以,选择一个吧 ;). 在我看来,最不具侵入性的框架是spring-jdbc和它的RowMapper - lance-java

-4

您的问题:

We know that we can map same table objects with same pojo class,
but when the query is customized and there is a data returned 
which doesn't map to any specific class then what would be the procedure? 

如果你有100种返回不同列组合的SQL,是否需要创建100个不同的POJO?答案是“不需要,停止使用POJO”。
这个库qood旨在解决这个问题,你可以尝试一下。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接