ジャバを学ぶ。Java でクエリを使用して jdbc 呼び出しを行う場合、そのレコードを保存するにはどうすればよいですか。より高度なコーダーによってそれらがハッシュ コレクションに格納されているのを見てきましたが、Java コレクション フレームワークを使用してレコードを格納し、それらを反復処理する方法がわかりません。ハッシュマップのような結果セットのレコードを保存するために共有して説明できる簡単なコード例はありますか?
前もって感謝します。初心者の質問で申し訳ありません。
ジャバを学ぶ。Java でクエリを使用して jdbc 呼び出しを行う場合、そのレコードを保存するにはどうすればよいですか。より高度なコーダーによってそれらがハッシュ コレクションに格納されているのを見てきましたが、Java コレクション フレームワークを使用してレコードを格納し、それらを反復処理する方法がわかりません。ハッシュマップのような結果セットのレコードを保存するために共有して説明できる簡単なコード例はありますか?
前もって感謝します。初心者の質問で申し訳ありません。
あなたの質問は春の質問としてタグ付けされています。ということで、春らしい答えを出します。関係する部分は次のとおりです。
結果セットのデータをハッシュマップに保存し、そのデータを確実に取得するために関連するすべてのコードを格納すると、面倒になる可能性があります。Spring のデータ エクストラクタのパラダイムを使用して、Java オブジェクトをデータベースに一致させるという厄介な詳細を隠してから、アプリケーションがデータベースにまったく接続されていないかのように、通常どおりに Java を記述できます。
JdbcTemplateは、データベースでクエリを実行できるように構成する Spring によって提供されるクラスです。spring を使用すると、提供されている jdbctemplate を記述する必要はありませんが、他の部分を記述する必要があり、次のようになります。
私のJavaオブジェクト
public class Shoe {
int size;
String color;
String id;
}
靴ひき器
public class ShoeExtractor implements ResultSetExtractor {
public Object extractData(ResultSet rs) throws SQLException, DataAccessException {
Shoe s = new Shoe();
// setting object's values to result set's values
s.setSize(rs.getInt(1));
s.setColor(rs.getString(2));
s.setId(rs.getString(3));
return s;
}
RowMapper
public class ShoeRowMapper implements RowMapper {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
ShoeExtractor shoeExtractor = new ShoeExtractor ();
return shoeExtractor.extractData(rs);
}
}
あなたの「メイン」で
@Resource
private JdbcTemplate jdbcTemplate;
StringBuffer statement = new StringBuffer();
statement.append("select size, color, id from shoes");
List<Shoe> shoes = jdbcTemplate.query(statement.toString(), new ShoeRowMapper ()):
フレームワークを使用している場合は、ORM のそのフレームワークのルールに従う必要があります。独自のクラスを展開し、独自に JDBC 呼び出しを行う場合は、次のように独自の単純な「フレームワーク」を提供できます。
このパラダイムの簡単な例を次に示します。
データベース クライアントがあるので、データ モデルを表すクラスを作成します。このクラスは、要素を GUI で表現できるように、JavaFX プロパティを使用して記述されています。
public class Client extends DB {
private IntegerProperty id = new SimpleIntegerProperty();
private StringProperty lastName = new SimpleStringProperty();
private StringProperty firstName = new SimpleStringProperty();
public final int getID() {return this.id.get(); }
void setID(int id) { this.id.set(id); }
public final IntegerProperty idProperty() { return this.id; }
public final String getLastName() { return this.lastName.get(); }
public final void setLastName(String ln) { this.lastName.set(ln); }
public final StringProperty lastNameProperty() { return this.lastName; }
public final String getFirstName() { return this.firstName.get(); }
public final void setFirstName(String fn) { this.firstName.set(fn); }
public final StringProperty firstNameProperty() { return this.firstName; }
Client(ResultSet jrs) {
try {
this.id.set(jrs.getInt(DB.CLI_FIELD_ID));
this.lastName.set(jrs.getString(DB.CLI_FIELD_LAST));
this.firstName.set(jrs.getString(DB.CLI_FIELD_FIRST));
} catch (SQLException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
System.exit(1);
}
}
static class ClientFactory implements Callback<ResultSet,Client> {
@Override
public Client call(ResultSet jrs) {
return new Client(jrs);
}
}
このクラスには次の 3 つが含まれます。
JavaFX フレームワークによって提供される GUI コントロールで使用できるように、クラスのインスタンス フィールドの JavaFX Bean 定義。
コンストラクターにパラメーターとして渡される ResultSet の現在指定されている行に含まれるデータを使用して Client クラスのインスタンスを初期化するコンストラクター。
新しい Client オブジェクトの作成に使用されるファクトリを提供する、ネストされた静的クラス。とてもシンプルです。ファクトリが行うことは、ResultSet 行を Client に渡すことによって Client のコンストラクタを呼び出すことだけです。このクラスは Callback インターフェイスを実装して、このファクトリがタイプ Resultset の 1 つのパラメーターを受け取り、タイプ Client の 1 つの結果を返すことを期待していることに注意してください。この目的で Callback インターフェイスを使用することにしましたが、プログラマーはファクトリに独自の同様のインターフェイスを使用できます。
この自家製のフレームワークを機能させるには、次のような自家製のクエリ メソッドを使用できます。このメソッドを使用すると、プログラマは long 型の 1 つのパラメーターを使用してクエリを実行できますが、提供されたパラメーターのリストを使用してクエリを構築できるように簡単に抽象化できます。
static <E> ObservableList<E> doGenericQuery(long param,
String sql, Callback<ResultSet,E> factory) {
Connection con = null;
ObservableList<E> queryList = FXCollections.<E>observableArrayList();
try {
con = MyDataBase.getConnection(); // provide your own connection here
PreparedStatement ps = con.PreparedStatement(sql);
ps.setLong(1, param);
ResultSet jrs = ps.executeQuery();
while (jrs.next()) {
queryList.<E>add(factory.<ResultSet,E>call(jrs));
}
} catch (SQLException e) {
Logger.getLogger(DB.class.getName()).log(Level.SEVERE, null, e);
} finally {
if (jrs != null) try { jrs.close(); } catch (SQLException e) { }
}
return queryList;
}
このジェネリック メソッドは、データベースにクエリを実行し、ResultSet をデータ モデル テーブル クラスの 1 つに基づくオブジェクトのリストに変換します (ここでは、やはり JavaFX のため、ObservableList です)。重要な行は、ジェネリック メソッドの呼び出しです。
queryList.<E>add(factory.<ResultSet,E>call(jrs));
データ モデル クラスの 1 つ (クラス E) のファクトリを使用して、ResultSet で現在示されているデータの行を使用して、そのクラス E のオブジェクトを構築します。
この方法でデータベース アプリを構築することには、長所と短所があります。ORM フレームワークに依存するよりもパフォーマンスが向上する可能性がありますが、データベースからオブジェクトへのマッピングのフットワークをすべて実行する必要もあります。フレームワークへの依存から解放されますが、より多くのコード、特にボイラープレートを作成する必要があります。
アプリケーションが単純な場合、またはデータベースがそれほど複雑でない場合は、同様の方法で独自の「フレームワーク」を自作したいと思うかもしれません。
通常、結果セットのデータを独自のクラスにマップする必要があります。これは Object Relational Mapping (ORM、構造化されたデータベースを使用していると仮定します) と呼ばれます。前の回答に示されているように、または jpa/hibernate などの既存の API/製品によって、自分で行うことができます
Java では、各結果または各結果のサブセットに対してクラスを作成するのが慣用的です。例えば
patientResultSet => patientEntityObject
コレクションに保存するのは慣用的ではありません。理由は、それを調べて、必要なフィールドを取得する方法を理解するのが難しいからです。