从结果集中创建对象。我这样做对吗?

Bag*_*era 3 java jdbc resultset

我正在学习Java,现在正在学习JDBC。我认为我对如何使用结果集对象有一定的了解,但我想确保自己做得对。

请参见下面的代码。它在名为“ restaurant”的数据库中查询名为“ menu”的表。该表有四列:

  • id_menu 整数,表的主键。
  • name字符串,菜单项的名称(例如“ Double Cheeseburger”)
  • descr字符串,菜单项的描述(例如,“整个小麦面包上有两个全牛肉馅饼”。)
  • price Double,商品的价格(例如5.95)(请注意,我知道我可以使用Money类型,但是我想使其保持简单)

这是menuItem对象的Java代码。表中的每一行都应用于创建menuItem对象:

public class menuItem {

    public int id = 0;
    public String descr = "";
    public Double price = 0.0;
    public String name = "";
    public menuItem(int newid, String newdescr, Double newprice, String newname){
        id = newid;
        descr = newdescr;
        price = newprice;
        name = newname;
        }
    }
Run Code Online (Sandbox Code Playgroud)

一切都是公开的,只是为了简化此练习。

这是填充数据库的代码。目前,此代码是主类内部的方法。

public static ArrayList<menuItem> reQuery() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException{    

    ArrayList<menuItem> mi = new ArrayList<menuItem>();

    //Step 1. User Class.forname("").newInstance() to load the database driver.
    Class.forName("com.mysql.jdbc.Driver").newInstance();

    //Step 2. Create a connection object with DriverManager.getConnection("")
    //Syntax is jdbc:mysql://server/database? + user=username&password=password
    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/miguelel_deliveries?" + "user=root&password=");

    //Step 3. Create a statement object with connection.createStatement();
    Statement stmt = conn.createStatement();

    //Step 4. Create variables and issue commands with the Statement object.
    ResultSet rs = stmt.executeQuery("Select * from menu");

    //Step 5. Iterate through the ResultSet. Add a new menuItem object to mi for each item.
    while(rs.next()){
    menuItem item = new menuItem(rs.getInt("id_menu"),rs.getString("descr"),rs.getDouble("price"),rs.getString("name"));
    mi.add(item);
    }
    return mi;
}
Run Code Online (Sandbox Code Playgroud)

此代码有效。我最后得到一个menuItem的ArrayList,以便每个元素对应于表中的一行。但这是最好的方法吗?我可以将其概括为一种处理ResultSet的方法吗?

  1. 对于数据库中的每个表或视图,创建一个具有与该表的列等效的属性的Java类。

  2. 将表内容加载到ResultSet对象中。

  3. 使用while(ResultSet.next())遍历ResultSet,在步骤1中为ResultSet中的每个项目创建一个新对象(来自该类)。

  4. 创建每个新对象后,将其添加到该类的ArrayList中。

  5. 根据需要处理ArrayList。

这是一种有效的方法吗?有更好的方法吗?

JB *_*zet 5

代码逻辑很好,但是实现有几个问题:

  • 它不遵守命名约定。类以大写字母开头
  • 您不应该使用公共字段。如果将字段初始化为默认值,并且构造函数之后立即对其进行了初始化,则这些字段将无用
  • 您没有关闭连接,这意味着每次执行该方法时,它都会使一个连接保持打开状态,从而导致内存被无用的消耗,并且由于达到了打开连接的最大数量,您的程序最终会失败。应该在finally块中关闭连接,或者使用自Java 7起可用的try-with-resources构造关闭。结果集和语句也应该关闭,尽管不关闭它们与不关闭连接一样没有问题。
  • 最新的足够的驱动程序和JVM不需要Class.forName()。newInstance()
  • 选择的类型很奇怪。例如,价格存储在可为null的Double变量中。但是,您可以使用getDouble()(它永远不会返回null)来获取其值。同样,使用双精度价格也是一个不好的选择。请改用BigDecimal。
  • 使用select *是不好的做法。选择所需的列,而不是所有的列。

我不会概括每个表的类的创建。很多时候,您不会查询单个表中的所有列,而是查询多个联接表中的某些列。

我还考虑使用ORM(JPA)代替JDBC。这将使您的代码更加整洁,简短,易读且更安全。