【问题标题】:How to map resultset into composite object in mapper class如何将结果集映射到映射器类中的复合对象
【发布时间】:2021-12-17 20:50:44
【问题描述】:

我有一个查询,它将返回 8 列用于下订单 POC,前 4 列对于几行(人员详细信息)相同,其余 4 列将不同(订单详细信息)。它是一个非规范化表。

COL1   COL2   COL3   COL4   COL5  COL6  COL7  COL8
-----------------------------------------------------
a      aaa    bbb    ccc    ddd   eee   fff   ggg
a      aaa    bbb    ccc    hhh   iii   jjj   kkk

我的对象看起来像

class OrderBook{
   int id;
   int name;
   String age;
   String mailId;
   List<Order> orderList;
}

class Order{
   String productName;
   int price;
   int quantity;
   String address;
}

如何遍历结果集并将行映射到 Orderbook 对象。响应应如下所示

{
   "id": 1,
   "name": "dude",
   "age" : 22,
   "mailId": "dude@abc.com",
   "orderList": [
        {
            "productName": "Milk",
            "price":23,
            "quantity":2,
            "address": "dude, 1st street"
        },
        {
            "productName": "Egg",
            "price":5,
            "quantity":10,
            "address": "dude, 1st street"
        }
    ]
}

这里不知道怎么循环

while(rs.next()){
    ???
}

【问题讨论】:

  • 你的问题解决了吗?

标签: java spring spring-mvc spring-data


【解决方案1】:

如果您直接使用 ResultSet,则必须直接从 RS 到 Object 实例实现转换器。并从您的 DAO 层使用它 类似:

@Override
public User getByID(int id) {
    OrderBook book = new OrderBook();
    try {
        PreparedStatement select = OrderBookTransformer.getInstance().getSelectStatementById(id);
        ResultSet rs = select.executeQuery();
        while (rs.next()) {
            book = OrderBookTransformer.getInstance().fromRsToObject(rs);
        }
    } catch (SQLException e) {
        log.error(e);
    }
    return book;
}

OrderBookTransformer 可能是这样的:

@Override
public OrderBook fromRsToObject(ResultSet rs) {
    OrderBook book = new OrderBook();
    try {
        user.setId(rs.getInt("id"));
        user.setName(rs.getInt("name"));
        user.setAge(rs.getString("age"));
        // set other fields
    } catch (SQLException e) {
        log.error(e);
    }
    return user;
}

对于初始化转换器,我使用了 Singleton 模式:

public class OrderBookTransformer implements BaseTranformer<OrderBook> {

    private static final Logger log = Logger.getLogger(OrderBookTransformer.class);
    private static OrderBookTransformer instance = null;

    protected OrderBookTransformer() {
    }

    public static OrderBookTransformer getInstance() {
        if (instance == null) {
            instance = new OrderBookTransformer();
        }
        return instance;
    }

然后选择语句类似于:

@Override
public PreparedStatement getSelectStatementById(int id) {
    PreparedStatement select = null;
    try (Connection connection = ConnectionManager.getConnection()) {
        select = connection
                .prepareStatement("SELECT FROM order_books WHERE id = ?");
        select.setInt(1, id);
    } catch (SQLException e) {
        log.error(e);
    }
    return select;
}

我的建议是使用Spring Data,而不是直接处理结果集。

您只需要再执行几个步骤:

  • spring data 依赖添加到您的构建工具中
  • 将 JPA 注释添加到您的模型及其关系中:
    @Entity
    class OrderBook {
       @Id
       @GeneratedValue(strategy = GenerationType.IDENTITY)
       private Integer id;
       private Integer name;
       private String age;
       private String mailId;
    
       @ElementCollection(targetClass = Order.class, fetch = FetchType.EAGER)
        @CollectionTable(name = "orders", joinColumns = @JoinColumn(name = "book_id"))
       private List<Order> orderList;
       // no args constructor + getters/setters
    }
    
    @Entity
    class Order {
       @Id
       @GeneratedValue(strategy = GenerationType.IDENTITY)
       private String productName;
       private Integer price; // consider use Double here
       private Integer quantity;
       private String address;
    }
  • 为这个类创建一个存储库:

公共 OrderBookRepository 实现 JpaRepository {}

并使用它从数据库中检索数据。

【讨论】:

    【解决方案2】:

    您应该首先将结果集转换为DataObject(OrderBook)。

    List<OrderBook> list = new ArrayList<>();
    while(rs.next()){
       OrderBook orderBook = mapToOrderBook(rs);
       list.add(orderBook);
    }
    

    你应该编写的几个基本函数。

    private List<OrderBook> getOrderBooks();
    private OrderBook mapToOrderBook(ResultSet rs);
    

    如果你不知道如何从结果集中获取数据:

    https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html

    然后就可以使用jackson将List转成json数据了。 Spring mvc 已经为你处理好了。

    @RequestMapping("/orderbooks")
    public List<OrderBook> getOrderBooks() {
      return orderbookService.getOrderBooks();
    }
    

    【讨论】:

    • 对不起。我猜我的问题不清楚。如何填充 orderList?
    猜你喜欢
    • 2018-12-21
    • 1970-01-01
    • 2019-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-27
    • 1970-01-01
    相关资源
    最近更新 更多