3

私は Java を勉強しており、現在 JDBC を学んでいます。結果セット オブジェクトの使用方法については把握していると思いますが、それが正しく行われていることを確認したいと思います。

以下のコードを参照してください。「restaurant」という名前のデータベース内の「menu」という名前のテーブルを照会します。テーブルには次の 4 つの列があります。

  • id_menu 整数、テーブルの主キー。
  • name文字列、メニュー項目の名前 (例: 「ダブル チーズバーガー」)
  • descr文字列、メニュー項目の説明 (例: 「全粒小麦パンに 2 つのオールビーフ パテ」)
  • 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;
        }
    }

この演習を簡単にするために、すべてが公開されています。

データベースにデータを入力するコードは次のとおりです。現時点では、このコードはメイン クラス内のメソッドです。

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;
}

このコードは機能します。各要素がテーブル内の 1 つの行に対応するように、menuItem の ArrayList になります。しかし、これが最善の方法ですか?これを ResultSet の処理方法に一般化できますか?

  1. データベース内のテーブルまたはビューごとに、テーブルの列と同等のプロパティを持つ Java クラスを作成します。

  2. テーブルの内容を ResultSet オブジェクトにロードします。

  3. while(ResultSet.next())を使用して ResultSet を反復処理し、手順 1 で ResultSet の各項目に対して (クラスから) 新しいオブジェクトを作成します。

  4. 新しいオブジェクトが作成されるたびに、それをクラスの ArrayList に追加します。

  5. 必要に応じて ArrayList を操作します。

これは効率的な方法ですか?それを行うより良い方法はありますか?

4

1 に答える 1

5

コード ロジックは問題ありませんが、実装にはいくつかの問題があります。

  • 命名規則を尊重しません。クラスは大文字で始まります
  • public フィールドは使用しないでください。また、フィールドがコンストラクターによって直後に再初期化された場合、フィールドをデフォルト値に初期化しても意味がありません
  • 接続を閉じません。つまり、メソッドが実行されるたびに、1 つの接続が開いたままになり、メモリが無駄に消費され、開いている接続の最大数に達したためにプログラムが最終的に失敗します。接続は、finally ブロックで閉じるか、Java 7 以降で利用可能な try-with-resources コンストラクトを使用して閉じる必要があります。ResultSet とステートメントも閉じる必要がありますが、それらを閉じないことは、接続を閉じないことほど問題ではありません。
  • Class.forName().newInstance() は、最近の十分なドライバーと JVM では必要ありません。
  • 選択されたタイプは奇妙です。たとえば、価格は null 許容の Double 変数に格納されます。ただし、null を返さない getDouble() を使用して値を取得します。また、価格に double を使用するのは適切ではありません。代わりに BigDecimal を使用してください。
  • を使用するselect *のは悪い習慣です。すべての列ではなく、必要な列を選択します。

テーブルごとのクラスの作成を一般化するつもりはありません。多くの場合、1 つのテーブルのすべての列に対してクエリを実行するのではなく、いくつかの結合されたテーブルの一部の列に対してクエリを実行します。

JDBC を使用する代わりに、ORM (JPA) を使用することも検討します。これにより、コードがよりクリーンで短く、読みやすく、安全になります。

于 2013-06-30T17:23:35.583 に答える