我应该使用什么类型的数据结构来保存表行?

发布于 2024-09-15 01:44:33 字数 134 浏览 3 评论 0原文

我是 Java 新手,刚刚开始查询数据库。到目前为止,我的结果都在 ResultSetMetaData 中。我认为对于数据集中的每一行,我应该将其添加到某种形式的集合中?谁能告诉我这方面的最佳实践?

谢谢,
琼西

I'm new to Java and just getting into querying databases. So far I have my results in a ResultSetMetaData. I'm think that for each row in the dataset I should add it to some form of collection? Can anyone tell me the best practice for this?

Thanks,
Jonesy

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

淡淡の花香 2024-09-22 01:44:33

创建一个对象来保存数据。循环遍历结果集,为每个结果集创建一个对象,并将它们存储在 ArrayList 或 HashMap 中,具体取决于您想要如何使用数据。这允许您关闭数据库,并且它为您提供了良好的对象,您可以在其上构建方法来操作数据。

它还允许您编写使用不需要依赖数据库的对象的代码。如果您想稍后取出数据库并切换到文本文件或其他任何文件,这很容易做到,并且您仍然可以使用相同的对象和方法。

Create an object to hold the data. Loop through the resultset, creating an object for each one, and store them in an ArrayList or HashMap, depending on how you want to use the data. This allows you to close the database, and it gives you good objects on which you can build methods to manipulate the data.

It also allows you to write code that uses the object that doesn't need to rely on the database. If you ever want to pull out the database later and switch to text files or whatever, it's easy to do and you can still use the same objects and methods.

空城缀染半城烟沙 2024-09-22 01:44:33

通常我们有一个类,其中的字段对应于一个表。然后,只要结果集中有(完整)行,我们就创建此类的一个实例。

示例:

考虑这样创建的表:

CREATE TABLE customer (First_Name char(50), Last_Name char(50),
   Address char(50), City char(50), Country char(25), Birth_Date date);

模型类将如下所示:

public class Customer {
  private String firstName;
  private String lastName;
  private String address;
  private String city;
  private String country;
  private Date date;


  public String getFirstName() {
    return firstName;
  }
  // getters for all fields

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }
  // setters for all fields

  public String toString() {
    return String.format("[%s, %s, %s, %s, %s, %s]", firstName,
             lastName, address, city, country, date);
  }
}

现在,如果您读取数据并有一个 ResultSet,您将创建一个新的客户对象并设置字段:

List<Customer> customers = new ArrayList<Customer>();
ResultSet rs = stmt.executeQuery("SELECT * from CUSTOMER;");
while (rs.next()) {
  Customer customer = new Customer();
  customer.setFirstName(rs.get("First_Name"));
  // ... and so on

  customers.add(customer);
}

Usually we have a class with fields that correspond to a table. Then, whenever we have a (full) row in a result set, we create an instance of this class.

Example:

Consider a table created like this:

CREATE TABLE customer (First_Name char(50), Last_Name char(50),
   Address char(50), City char(50), Country char(25), Birth_Date date);

A model class would be like this:

public class Customer {
  private String firstName;
  private String lastName;
  private String address;
  private String city;
  private String country;
  private Date date;


  public String getFirstName() {
    return firstName;
  }
  // getters for all fields

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }
  // setters for all fields

  public String toString() {
    return String.format("[%s, %s, %s, %s, %s, %s]", firstName,
             lastName, address, city, country, date);
  }
}

Now if you read data and have a ResultSet, you would create a new customer object and set the fields:

List<Customer> customers = new ArrayList<Customer>();
ResultSet rs = stmt.executeQuery("SELECT * from CUSTOMER;");
while (rs.next()) {
  Customer customer = new Customer();
  customer.setFirstName(rs.get("First_Name"));
  // ... and so on

  customers.add(customer);
}
靖瑶 2024-09-22 01:44:33

List 看起来很合乎逻辑。如果您不打算有重复项,并且您不关心结果的顺序,那么也许是一个Set

List 的相关实现:

  • ArrayList:它由数组支持,因此对特定索引的查找应该很快

Set 的相关实现:

  • < code>HashSet:由 HashMap 支持,因此 O(1) 插入时间
  • TreeSet:尊重数据的顺序(使用compareTo 方法) - 因此迭代数据将按顺序进行 - 权衡是 O(log n) 插入时间

A List seems quite logical. If you are not going to be having duplicates, and you are not bothered about the order of the results, then perhaps a Set.

A relevant implementation of List:

  • ArrayList: This is backed by an array, so lookups on particular indices should be quick

Relevant implementations of Set:

  • HashSet: Backed by a HashMap so O(1) insertion time
  • TreeSet: Respects the ordering of the data (using the compareTo method) - so iterating over the data will be in order - the trade off is O(log n) insertion time
神魇的王 2024-09-22 01:44:33

您可以创建代表现实世界实体的类。稍后如果你想选择像 hibernate 这样的 ORM 技术/工具,你可以使用相同的类。

You can create class which represents real world entities. Later if you wish to choose ORM technology/tool like hibernate you can use same classes.

冷…雨湿花 2024-09-22 01:44:33

首先, ResultSetMetaData 类保存“信息关于 ResultSet 对象中列的类型和属性。”因此,查询结果位于 ResultSet 中,而不是位于 ResultSetMetaData 对象中。

您可以参阅从结果集中检索值 Java 教程有关如何从结果集中提取数据的信息。您应该能够如图所示循环遍历 ResultSet,并将记录放入列表或映射中,具体取决于您稍后想要如何访问数据。

First, the ResultSetMetaData class holds "information about the types and properties of the columns in a ResultSet object." So the results from your query are in the ResultSet, not in the ResultSetMetaData object.

You can see the Retrieving Values from Result Sets Java tutorial for information on how to extract your data from a ResultSet. You should be able to just loop through the ResultSet as shown and put your records in a List or Map, depending on how you want to access the data later.

相守太难 2024-09-22 01:44:33

我通常遵循 Andreas_D 描述的相同模式。

用于包含每行数据的对象(在本例中为 Customer 类)称为数据传输对象 (TO)。

获取数据库连接、查询数据库、填充 TO 并返回它们(通常在列表中)的代码称为数据访问对象 (DAO)。

您可以在此处阅读有关此设计模式的更多信息

I usually follow the same pattern as Andreas_D describes.

The object used to contain each row of data (in this case, the Customer class) is referred to as Data Transfer Object (TO).

The code that gets the database connection, queries the db, populates the TOs and returns them (typically in a List), is referred to as a Data Access Object (DAO).

You can read more about this design pattern here

南街九尾狐 2024-09-22 01:44:33

上面的许多答案都建议创建一个类来保存行的列并创建类对象的数组列表。我们是否也应该担心,如果结果集很大,但只处理较少的行,它是否不会过度消耗内存,除非垃圾收集器以与创建对象相同的速度进行回收。

Many of the answers above advice creating a class to hold the columns of a row and create Array list of the Class Objects. Shouldn't we also worry if the result set is huge though only fewer rows are being processed, would it not over consume memory unless the garbage collector reclaims at the same pace at which the objects are being created.

dawn曙光 2024-09-22 01:44:33

我遇到了一个有几十列的 ResultSet 问题,编写一个包含如此多成员的类对于懒惰的我来说工作量太大了。因此,我将 ResultSet 的每个字段迭代到 HashMap 中,列标签作为键,字段作为值。然后,每个人将每行的所有哈希图放入一个单独的列表中,并将所有列表放入一个主列表中。

工作起来就像一个魅力。

private ArrayList<ArrayList<HashMap<String, Object>>> allRecords = new ArrayList<>();

public MyTable getRecords()throws IOException, SQLException{
    try{
        String query = new Utils().readResourceFile("MyQuery.sql");
        ResultSet rs = DBUtils.dbConnect().createStatement().executeQuery(query);
        ResultSetMetaData rsmd = rs.getMetaData();
        int columnCount = rsmd.getColumnCount();
        while (rs.next()){
            ArrayList<HashMap<String, Object>> row = new ArrayList<>();
            for (int i = 1; i < columnCount + 1; i++) {
                HashMap<String, Object> data = new HashMap<>();
                Object field = rs.getObject(i);
                data.put(rsmd.getColumnLabel(i), rs.wasNull()? "": field);
                row.add(data);
            }
            allRecords.add(row);
        }
    }catch (IOException | ClassNotFoundException | SQLException e){
        if(e instanceof SQLException){
            DBUtils.printSQLException((SQLException) e);}
        e.printStackTrace();
        throw e;
    }
    return this;
}

这是我过滤数据的方法:

 public MyTable makeChanges(){
    for(int i = 0; i < allRecords.size(); i++){
        Date startDate = (Date) allRecords.get(i).stream().filter((HashMap<String, Object> field) -> field.containsKey("StartDate")).findFirst().get().get("StartDate");
        int product = (int) allRecords.get(i).stream().filter((HashMap<String, Object> field) -> field.containsKey("pk_Product")).findFirst().get().get("pk_Product");
        // now do something....
    }
    return this;
}

I had this issue with a ResultSet that had a few dozen columns, writing a class with so many members was way too much work for lazy me. So I iterated the ResultSet each field into a HashMap, the column label way the key and the field being the value. Then each put all the hashmaps from each row into a seperate list and all the lists into a master list.

Worked like a charm.

private ArrayList<ArrayList<HashMap<String, Object>>> allRecords = new ArrayList<>();

public MyTable getRecords()throws IOException, SQLException{
    try{
        String query = new Utils().readResourceFile("MyQuery.sql");
        ResultSet rs = DBUtils.dbConnect().createStatement().executeQuery(query);
        ResultSetMetaData rsmd = rs.getMetaData();
        int columnCount = rsmd.getColumnCount();
        while (rs.next()){
            ArrayList<HashMap<String, Object>> row = new ArrayList<>();
            for (int i = 1; i < columnCount + 1; i++) {
                HashMap<String, Object> data = new HashMap<>();
                Object field = rs.getObject(i);
                data.put(rsmd.getColumnLabel(i), rs.wasNull()? "": field);
                row.add(data);
            }
            allRecords.add(row);
        }
    }catch (IOException | ClassNotFoundException | SQLException e){
        if(e instanceof SQLException){
            DBUtils.printSQLException((SQLException) e);}
        e.printStackTrace();
        throw e;
    }
    return this;
}

And here is how I filtered the data:

 public MyTable makeChanges(){
    for(int i = 0; i < allRecords.size(); i++){
        Date startDate = (Date) allRecords.get(i).stream().filter((HashMap<String, Object> field) -> field.containsKey("StartDate")).findFirst().get().get("StartDate");
        int product = (int) allRecords.get(i).stream().filter((HashMap<String, Object> field) -> field.containsKey("pk_Product")).findFirst().get().get("pk_Product");
        // now do something....
    }
    return this;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文