現在、アプリケーションを作成しており、データベースに接続するためのクラスを正しく設計する方法の決定に苦労しています。私はこのようなものを思いつきました:
public class DatabaseConnector {
private Connection databaseConnection = null;
public DatabaseConnector(String url, String user, String password) {
databaseConnection = DriverManager.getConnection(url, user, password);
}
public void close() throws SQLException {
databaseConnection.close();
}
}
さらに、このクラスには、データベースから何かをプルしたり挿入したりするメソッドがあり、メソッドごとにPrepareStatement
とResultSet
およびその他のオブジェクトを作成します。
私の質問は、このアプローチが正しいか、どういうわけか間違っているか、ひどく間違っているかです。良いコミュニケーションクラスを設計するためのあらゆるヒントと、データベースを正しく操作する方法を喜んで教えます。
MySQLデータベースとJDBCを通信に使用しています。
データベースへの接続には2つのクラスの設計を好みます。このアプローチは、単一のアプリケーション内で複数のデータベースと通信する場合に特に効率的です。
具体的には、たとえば、CommDBのselectメソッドは次のようになります。
public class CommDB
{/** This class contains a generic code for data manipulation */
public TreeMap<String,HashMap<String,String>>
select(Connection conn, String selectQuery)
{ /** This is a generic method for the select operation */
TreeMap<String,HashMap<String,String>> selectResult =
new TreeMap<String,HashMap<String,String>>();
String[] keys = selectQuery.replace(" ","").replace("SELECT", "").split("FROM")[0].split(",");
try {
PreparedStatement stmt = conn.prepareStatement(selectQuery);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
HashMap<String,String> eachResult = new HashMap<String,String>();
for (int i=1; i<keys.length; i++) {
eachResult.put(keys[i],rs.getString(i+1));
} // for
selectResult.put(rs.getString(1),eachResult);
} // while
} catch(SQLException sqlExc) {
System.out.println(sqlExc.getMessage());
} // try-catch
return selectResult;
} // select()
} // class CommDB
myDBからユーザー情報を取得するための特定のコードは次のようになります。
public class MyDB
{ /** This is MyDB Proxy Class */
String myDbUrl = "jdbc:mysql://MyDB/mySchema";
String myDbDriver = "com.mysql.jdbc.Driver";
String myDbUser = "myName";
String myDbPwd = "myPassword";
CommDB db = new CommDB();
public TreeMap<String,HashMap<String,String>>
getUsers(String namePattern)
{ /** This method is specific for USERS data */
TreeMap<String,HashMap<String,String>> users =
new TreeMap<String,HashMap<String,String>>();
String selectUsers =
"SELECT userID, firstName, lastName, address, phone FROM USERS " +
"WHERE lastName like '%" + namePattern + "%'";
Connection conn = null;
try {
conn = db.connect(myDbUrl,myDbDriver,myDbUser,myDbPwd);
users = db.select(conn, selectUsers);
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
try {
if (conn != null) { conn.close(); }
} catch (SQLException sqlExc) {
System.out.println(sqlExc.getMessage());
} // try-catch
} // try-catch-finally
return users;
} // getUsers()
} // class MyDB
リレーショナルデータベースに接続して情報を保存および取得するには、さまざまな方法があります。ニーズに応じて、低レベルの実装またはより高いレベルの実装を使用できます。
JDBCを直接使用する を使用できます。特定のデータベースと通信する方法を知っている driver が必要です。接続を開き、SQLクエリを使用してステートメントを準備し、ステートメントに必要なパラメーターを設定し(ある場合)、ステートメントを実行します、結果セットを取得し、結果セットを反復して結果からオブジェクトを作成してから、使用したリソース(結果セット、ステートメント、接続)を閉じます。
それが最も低レベルの方法です。ただし、いくつかの欠点があります。
開く接続を制限するには、次のようにします 接続プールを使用 Apache DBCP、C3P0、HikariCPなど。同じボイラープレートコードが残っていますが、接続を作成して閉じるのではなく、借ります1つをプールに戻します。もっと効率的。
さて、ボイラープレートは毎回同じなので、SQLの作成に専念できるフレームワークやライブラリーに移動してください。これは、たとえば MyBatis のようなデータマッパーが行うことです。一度設定して、必要なSQLを記述してメソッドにマッピングし、MyBatisに行の結果をオブジェクトにマッピングする方法を伝えます。すべてのボイラープレートはMyBatisによって処理されます。メソッドを実行して、必要なオブジェクトを取得します。
MyBatisを使用すると、SQLを作成するだけで済みます。しかし、それを気にしたくない人もいます。ボイラープレートコードと、いくつかのライブラリ/フレームワークによって処理される接続がありますが、SQLも削除してみませんか?
これが、Hibernateのように ORMs が行うことです。クラスをテーブルにマップすると、Hibernateがすべてを処理します。データベースからデータを保存または取得するときに必要なSQLを生成します。 Hibernateを構成したら、データベースが存在しない(少なくともしばらくの間)ふりをすることができます。
これらの方法にはそれぞれ長所と短所があります。
これらはオプションです。アプリケーションを見て、どのソリューションがより適切であるかを確認します。あなたの質問を考えると、軽量のものを使用したいかもしれません(直接JDBCほど低くなく、Hibernateほど高くもありません)。
しかし、車輪を再発明しないでください。たとえば Commons DbUtils のようなものが、出発点として適しています。データベースとのやり取りを大幅に変更/追加することなく、JDBCボイラープレートコードを取り除きます。
したがって、クエリを呼び出すには、次のようにします。
String Querry = "SELECT seatID,movieID,Tanda,seatNum,isBooked,BookedBy FROM ROOT.SEATS";
Map<String, List< Object>> map = getListQuerry(Querry);
map.forEach((key, value) -> System.out.println(key + ":" + value));
メソッドは次のようになります。
Map<String, List< Object>> getListQuerry(String query) {
System.out.println("getListQuerry will run SQL Querry:\n\t\t" + query);
Map<String, List< Object>> result = new HashMap<>();
String[] keys = query.replace(" ", "").replace("SELECT", "").split("FROM")[0].split(",");
for (String Key : keys) {
result.put(Key, new ArrayList<>());
}
try (Connection Connection = DriverManager.getConnection(Host, DBUsername, DBpassword)) {
PreparedStatement stmt = Connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet resultSet = stmt.executeQuery();
while (resultSet.next()) {
for (int i = 1; i < keys.length; i++) {
result.get(keys[i]).add(resultSet.getInt(keys[i]));
}
}
} catch (SQLException ex) {
Logger.getLogger(Stage1Bootup.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Query failed to run");
}
return result;
}