DAO
チェスゲームを通じて、DAOオブジェクトのDB接続を初めて体験しました.
DAO의 개념
とDB 접근을 DAO로 분리하는 이유
について説明しましょう.DAOとは?
次に示すように、データベースに値(データ・アクセス・オブジェクト)を格納し、データベースから値を取り出してコントローラまたはサービス・オブジェクトに渡す役割を果たします.
public class PieceDao {
public void savePiece(final Position position, final Piece piece) {
final String sql = "insert into piece (position, team, name) values (?, ?, ?)";
try (final PreparedStatement statement = getConnection().prepareStatement(sql)) {
statement.setString(1, position.toString());
statement.setString(2, piece.getTeam());
statement.setString(3, position.getName());
statement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
なぜDBアクセス責任をDAOに分割するのか
1.責任分離
オブジェクト向けの例では、共通のターゲットの機能を複数の責任に分割し、責任を複数のオブジェクトに分割します.分離の責任では、DAOがデータベース接続を担当します.
データベースに複数のテーブルがある場合は、1つのテーブルにアクセスする責任をオブジェクトに付与できます.
2.変化に柔軟に対応(拡張可能)
使用するデータがOracleデータベースにアクセスするとします.
public class PieceDaoOracle {
public void savePiece(final Position position, final Piece piece) {
}
}
その後、データベースがMySQLに変更された場合、どうすればいいですか?データベース・アクセス責任をDAOに分離し、次のインタフェースを使用して変更に応答します.
public interface PieceDao {
void savePiece(final Position position, final Piece piece);
}
PieceDaoインタフェースを使用して抽象化し、必要に応じて以下の実装を置き換えることができます.public class PieceDaoOracle implements PieceDao {
@Override
public void savePiece(final Position position, final Piece piece) {
//Oracle DB Connection
}
}
public class PieceDaoMySQL implements PieceDao {
@Override
public void savePiece(final Position position, final Piece piece) {
//MySQL DB Connection
}
}
ただし、DAOの役割を分離するのではなく、サービス・オブジェクトに次のような内容を持たせます.サービス・オブジェクトをインタフェースに分離し、データベース・タイプに基づいてサービス・インプリメンテーション・オブジェクトを作成する必要があります.
public interface ChessGameService {
void movePiece(final Position source, final Position target);
}
public interface ChessGameServiceMySQL {
@Override
public void movePiece(final Position source, final Position target) {
//MySQL DB로 이뤄지는 Service 로직
}
}
public interface ChessGameServiceOracle {
@Override
public void movePiece(final Position source, final Position target) {
//Oracle DB로 이뤄지는 Service 로직
}
}
3.テストしやすい
サービス・オブジェクトでサービス・ロジックのテストを作成することを考慮します.
サービスの論理はDAOを介してDBにアクセスすることである.
そうであれば、テスト中のデータがデータベースを汚染します.
この場合、データベース・アクセスをDAOに分離し、DAOをサービス・オブジェクトに注入することで問題を解決できます.
1.データベースにアクセスしてテストするDAO
テスト・データベースを作成し、データベースにアクセスしたDAOをサービス・オブジェクトに注入します.
テスト中、生産データベースは汚染されません.
public class ChessGameService {
private final PieceDao pieceDao;
public ChessGameService(final PieceDao pieceDao) {
this.pieceDao = pieceDao;
}
void movePiece(final Position source, final Position target) {
}
}
class ChessGameSerciceTest {
private final ChessGameService chessGameService =
new ChessGameService(new PieceDaoFake);
}
public class PieceDaoTestDB implements PieceDao {
//프로덕션 DB가 아닌 Test를 위한 DB에 Connection
}
2.DBのように表現されたダミーを注入するデータベースが実際に接続されている場合は、サービス・オブジェクトをテストします.
テスト中にデータベースへの接続とアクセスが必要になるため、テストのパフォーマンスが低下します.
サービステストでは、データベースが実際に接続されているかどうかは重要ではありません.
サービスロジックが正常に動作しているかどうかを確認するだけです.
したがって、DB接続のないDAOをサービス・オブジェクトに注入する場合は、次の操作を行います.
サービス・オブジェクトのテスト・パフォーマンスを向上させます.
public class ChessGameService {
private final PieceDao pieceDao;
public ChessGameService(final PieceDao pieceDao) {
this.pieceDao = pieceDao;
}
void movePiece(final Position source, final Position target) {
}
}
class ChessGameSerciceTest {
private final ChessGameService chessGameService =
new ChessGameService(new PieceDaoFake);
}
public class PieceDaoFake implements PieceDao {
private final Map<String, Piece> fakeDB = new HashMap<>();
}
PieceDaoFakeオブジェクトのfakeDBフィールドは、DBの役割を置き換えることができます.サービス・オブジェクトのテスト中に、実際にはデータベース接続はありません.
生産データベースは汚染されず、テスト性能が向上する可能性があります.
ある面白いジョークでこの文章を終わらせる
ソース:https://okky.kr/article/153941
Reference
この問題について(DAO), 我々は、より多くの情報をここで見つけました https://velog.io/@byeongju/DAO란テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol