3

私は次の機能を持っています:

public Map<Integer, Product> fetchAllProducts() {

  Map<Integer, Product> pArr = new HashMap();
  try {
     Statement st = conn.createStatement();
     ResultSet rs = st.executeQuery("SELECT id, intro, content, price FROM Product");
     while (rs.next()) {
       pArr.put(rs.getInt("id"), new Product(rs));
     }
     st.close();
  } catch (SQLException ex) {
   //...
  }
  return pArr;
}

mySQL テーブルからすべての行を取得し、行Productごとに新しいProductクラスを作成します。製品コンストラクター:

 public Product(ResultSet rs) {
    try {
       price = rs.getInt("price");
       content = rs.getString("content");
       intro = rs.getString("intro");
    } catch (SQLException ex) {
       //...
    }
   }

私の質問は: 結果列を の変数に割り当てるより良い方法はありますProductか? コードprice = rs.getInt("price");などは冗長に見えますね。クエリステートメントをSELECT intro, content, tax, delivery FROM ...コンストラクターに変更すると、コンストラクター内の適切な変数 (つまり、イントロ、コンテンツ、税金、配送) に自動的に割り当てられます。これはJavaで実行できますか、それとも私は夢を見ているだけですか?

4

5 に答える 5

3

リフレクションの助けを借りてこれを実現できます。ResultSetMapperは同じことを行います。

1 つのチュートリアル

Apache BeanUtils には似たようなものがありますが、DynaBeanが返されます。

より洗練された本格的なシステムに移行できる場合は、休止状態、JPA などの ORM の使用を検討する必要があります。

通常の JDBC の場合、独自のリフレクション ユーティリティを作成するか、ResultMapper を使用できます。

于 2012-04-27T08:00:13.560 に答える
3

最初: !ResultSetのコンストラクターに を渡すべきではありません。Productデータベース アクセス コードをビジネス ロジックから明確に分離する必要があります。

したがって、通常、コードでこれが表示されると予想されます。

private static final String TABLE_NAME = "product";
private static final String ID_COLUMN = "id";
private static final String INTRO_COLUMN = "intro";
private static final String CONTENT_COLUMN = "content";
private static final String PRICE_COLUMN = "price";

private static final String FETCHALLPRODUCTS_QUERY = String.format("SELECT %s, %s, %s, %s FROM %s", ID_COLUMN, INTRO_COLUMN, CONTENT_COLUMN, PRICE_COLUMN, TABLE_NAME);

public Map<Integer, Product> fetchAllProducts() {

  Map<Integer, Product> pArr = new HashMap();
  try {
     Statement st = conn.createStatement();
     ResultSet rs = st.executeQuery(FETCHALLPRODUCTS_QUERY);
     while (rs.next()) {
        Integer price = rs.getInt(PRICE_COLUMN);
        String content = rs.getString(CONTENT_COLUMN);
        String intro = rs.getString(INTRO_COLUMN);

        Product product = new Product(price, content, intro);
        Integer id = rs.getInt(ID_COLUMN);
        pArr.put(id, product);
     }
     st.close();
  } catch (SQLException ex) {
   //...
  }
  return pArr;
}

しかし、あなたの質問に答えると、プレーンな JDBC を扱う場合、これを行うのは非常に一般的な方法です。あなたが探しているのは、HibernateのようなORMフレームワークです。

JDBC 接続を使用するときに行っていることの 1 つは、列名とテーブル名の定数を宣言することです。そうすれば、私の意見では少しきれいになります。

于 2012-04-27T07:54:25.430 に答える
0

たとえば休止状態を使用すれば、これは可能だと思います。しかし、私の前書きのように、ProductのコンストラクターでResultSetを設定しないでください。これは、ResultSetの別のコピーで作業するため(ResultSetは重い)、データが多い場合はパフォーマンスが低下するためです。

だから、ただやってください:

..。

pArr.put(rs.getInt("id"), new Product(rs.getint("Price") ....));

..。

public Product(int price ....) {
于 2012-04-27T08:01:23.277 に答える
0

マッピング ライブラリ (Hibernate など) を使用すると、コードがより快適になると思います。私が聞いたように、それはあなたが望むものと共通のものになります。ただし、これを使用するには、プロジェクト内のすべてのデータベース対話コードを置き換える必要があります。あなたのコードはそれほど醜くないと思います。おそらくこれを行うと、もう少し快適になります。

 while (rs.next()) {
   pArr.put(rs.getInt("id"), new Product(rs));
   Integer id = rs.getInt("id");
   Integer price = rs.getInt("price");
   Integer content = rs.getString("content");
   Integer intro = rs.getString("intro");
   Product product = new Product(price, content, intro);
   pArr.put(id, product);
 }

回答を入力しているときに、同じ回答が 3 つ表示されたようです。ごめんなさい:)

于 2012-04-27T08:10:34.750 に答える
0

Commons DbUtilsは、JDBC の最上位の薄いレイヤーです (Hibernate のようなものほど関与していません) は、 ResultSet から Bean プロパティを設定できます。

于 2012-04-27T08:15:52.877 に答える