Сбор данных из результирующего набора в карту или список

#java #resultset

#java #результирующий набор

Вопрос:

У меня есть код для сбора некоторых данных из базы данных в результирующий набор (данные продуктов). Моя модель продукта выглядит следующим образом:

 public class Product {
    private Integer avail;
    private  Long id;
    private BigDecimal price;
    private String url;
    private Integer stock;
    private String category;
    private String title;
    private String description;
    private List<String> attribute;
    private Map<String, String> attributes;

//getters-setters-toString
  

Другой класс — собирать продукты в список:

 public class Products {
    private List<Product> products = null;

    public List<Product> getProducts() {
        return products;
    }

    public void setProducts(List<Product> products) {
        this.products = products;
    }
}
  

Результат моего запроса к базе данных выглядит следующим образом:

 =============================================================
products_id||attribute key||attribute valu||some other data ...
=============================================================
      1        a1:k1            a1:v      some other data ...       
      1        a1:k2            a1:v      some other data ... 
      1        a1:k3            a1:v      some other data ... 
      1        a1:k4            a1:v      some other data ...
      1        a1:k5            a1:v      some other data ...
      2        a2:k1            a2:v      some other data ...
      2        a2:k2            a2:v      some other data ...
      2        a2:k3            a2:v      some other data ...
      2        a2:k4            a2:v      some other data ...
      3        a3:k1            a3:v      some other data ...
      4        a4:k1            a4:v      some other data ...
      5        a5:k1            a5:v      some other data ...
      5        a5:k2            a5:v      some other data ...
      5        a5:k3            a5:v      some other data ...
=============================================================
  

Мне нужно создать List<Product> вот так:

 =================================================
products_id | attributes           | some other data ...
=================================================
      1       k1:v, k2:v...          some other data ...
      2       k1:v, k2:v...          some other data ...
      3       k1:v                   some other data ...
      4       k1:v                   some other data ...
      5       k1:v, k2:v...          some other data ...
=================================================   
  

Выберите запрос:

 String query = "SELECTn"  
            "p.products_id, n"  
            "p.products_price_tax, n"  
            "p.products_availability_id, n"  
            "p.products_quantity, n"  
            "p.products_image, n"  
            "cd.categories_name, n"  
            "pd.products_name, n"  
            "pd.products_description, n"  
            "pef.products_extra_fields_name,n"  
            "ptpef.products_extra_fields_valuen"  
            "FROM n"  
            "products p  n"  
            "LEFT JOIN n"  
            "products_to_categories ptc n"  
            "ON n"  
            "ptc.products_id = p.products_id n"  
            "LEFT JOIN n"  
            "categories_description cd n"  
            "ON n"  
            "cd.categories_id = ptc.categories_id n"  
            "LEFT JOIN n"  
            "categories c n"  
            "ON n"  
            "c.categories_id = cd.categories_id n"  
            "LEFT JOIN n"  
            "products_description pd n"  
            "ON n"  
            "pd.products_id = p.products_id n"  
            "LEFT JOINn"  
            "products_to_products_extra_fields ptpefn"  
            "ONn"  
            "ptpef.products_id = p.products_idn"  
            "LEFT JOINn"  
            "products_extra_fields pefn"  
            "ONn"  
            "pef.products_extra_fields_id = ptpef.products_extra_fields_idn"  
            "WHERE n"  
            "p.products_status = 1n"  
            "ANDn"  
            "c.categories_id IN (83, 104, 102, 106, 92)";
  

Я пытался создать что-то вроде этого:

             conn = DriverManager.getConnection("connection data");
            selectProducts = conn.prepareCall(query);
            rs = selectProducts.executeQuery();

            while (rs.next()) {
                String tmpId = rs.getString("products_id");
                attr = new ArrayList<>();
                Product product = new Product();
                product.setId(rs.getLong("products_id"));
                product.setPrice(rs.getBigDecimal("products_price_tax"));
                product.setAvail(rs.getInt("products_availability_id"));
                product.setStock(rs.getInt("products_quantity"));
                product.setCategory(rs.getString("categories_name"));
                product.setTitle(rs.getString("products_name"));
                product.setDescription("products_description");
                attr.add(rs.getString("products_extra_fields_name"));
                attr.add( rs.getString("products_extra_fields_value"));
                product.setAttribute(attr);
                mainList.add(product);
            }

//            mainList.forEach(product -> System.out.println(product));

            Product tmpProduct = null;
            List<Product> tmpProductList = new ArrayList<>();
            Map<String, String> tmpAttr = new HashMap<>();

            for (int i = 0; i < mainList.size() - 1; i  ) {
                if (mainList.get(i).getId().equals(mainList.get(i   1).getId())) {
                  tmpAttr.put(mainList.get(i).getAttribute().get(1),mainList.get(i).getAttribute().get(2)); //here I am getting NullPointerException
                } else {
                    tmpAttr.put(mainList.get(i).getAttribute().get(0),mainList.get(i).getAttribute().get(1));
                    tmpProduct = mainList.get(i);
                    tmpProduct.setAttributes(tmpAttr);
                    tmpProductList.add(tmpProduct);
                    tmpAttr = null;
                    tmpProduct = null;
                }
            }
  

Поэтому я пытался создать что-то новое List<Product> и работать с этим. Есть ли какой-нибудь более простой способ решить эту задачу?

Комментарии:

1. Вы думали об ORM API?

2. Пропущенный «код подключения» очень важен, потому что, основываясь на том, как вы извлекаете свои данные, вы можете, например, передавать их непосредственно в List<Product> то, что вам нужно. Детали зависят от размера набора данных, но общая идея заключалась бы в том, чтобы передавать его в список Product напрямую.

3. @TreffnonX Я думаю, что через некоторое время я перепишу код в режиме гибернации, но сейчас я хочу найти решение для этой задачи

4. @Dropout Я добавлю удаленные данные через секунду

Ответ №1:

Вы можете использовать библиотеку jOOQ для создания потока, который просто отображается в список

 Connection conn = DriverManager.getConnection("connection data");
PreparedStatement pSt = connection.prepareStatement(query); //your SQL query
ResultSet rs = pSt.executeQuery();

List<Product> productList;
try(Stream<Record> productStream = DSL.using(conn).fetchStream(rs)){ //jOOQ DSL
    productList = productStream
        .map(p -> {
            Product product = new Product();
            
            //casting after get might be necessary
            product.setAvail(p.get("products_availability_id")); 
            //do the same for other fields you'd like to map to Product

            return product;
        })
        .collect(Collectors.toList());
}
  

Документация jOOQ DSL

Документация по записи jOOQ

Комментарии:

1. Пожалуйста, обратите внимание, что это не решение для копирования и вставки, а скорее общая идея подхода. Я пишу код из головы, не тестируя на данный момент.