boy in green shirt
Photo by CDC on Pexels.com

【授業レポート】システム開発(2年) 第36週目

〜マイグレーション実装&DAO設計:DBとアプリをつなぐ週〜

第36週目は、先週作成したER図とDDLをもとに、実際にアプリからデータベースを操作するための基盤づくりを行いました。
テーマは マイグレーション(テーブル作成)と DAO(データアクセス層)設計
データ設計から実装へ橋渡しする“つなぎ”の工程を学ぶ実践回です。


■ 先生の導入:「データに触るコードは“慎重に、丁寧に”」

田中先生:「DAOはアプリとDBをつなぐ“境界のコード”。
安全性・可読性・変更に強い設計が求められます。」

先生はまず「ビジネスロジックとSQLを混在させると、後で修正が困難になる」という実例を紹介し、DAO(Repositoryパターン)を採用する理由を説明しました。


■ 今日のポイント(まとめ)

  • DDL を実行し、ローカル/学習環境にテーブルを正しく作成する
  • DAO レイヤーで「CRUD(Create/Read/Update/Delete)」を分離
  • SQL インジェクション防止のためプレースホルダ必須
  • トランザクションの境界を明確にする
  • ログ出力・例外処理を統一し、運用時の調査性を高める

■ 実習①:マイグレーション(DDL)の実行

班ごとに作成した DDL を実際に実行し、テーブルが期待どおり作成されているか確認しました。

チェック項目

  • PK・FK が正しく設定されているか
  • NOT NULL 制約が正しく効いているか
  • UNIQUE や CHECK 制約の付け忘れがないか
  • サンプル INSERT が正常に入るか
  • JOIN が期待通り動作するか

生徒A:「FK を忘れてて JOIN が変になってた…気づけてよかった!」
生徒B:「制約を付けるだけでエラーを早期に防げることが分かった」


■ 実習②:DAO設計(インターフェース定義)

次に DAO(Data Access Object)のクラス構成を検討しました。

DAOの役割(先生の説明)

  • SQL をまとめて管理する
  • ビジネスロジックから DB を切り離す
  • テストしやすくする(モック化が容易)
  • アプリの規模が大きくなっても破綻しない構造にする

DAO の基本メソッド(例:BooksDao)

  • get(book_id)
  • find_by_title(keyword)
  • create(book)
  • update(book)
  • delete(book_id)

生徒の反応:「SQLを散らさず一箇所に書けるのが良い。“責務分離”が少し分かってきた!」


■ 実習③:実際にDAOを実装してみる

SQLite/PostgreSQL 学習用環境で実際に CRUD を作成。

例:BooksDao(一部抜粋・学習用)

class BooksDao:
    def __init__(self, conn):
        self.conn = conn

    def get(self, book_id):
        cur = self.conn.cursor()
        cur.execute("SELECT id, title, author, is_available FROM books WHERE id = %s", (book_id,))
        row = cur.fetchone()
        return row

    def create(self, title, author):
        cur = self.conn.cursor()
        cur.execute(
            "INSERT INTO books (title, author) VALUES (%s, %s) RETURNING id",
            (title, author)
        )
        new_id = cur.fetchone()[0]
        self.conn.commit()
        return new_id

DAO 実装で気をつけた点

  • 例外発生時はロールバックする
  • 不正データは DAO に入る前(サービス層)で弾く
  • キャッシュを使うクラスは DAO の外に置く(責務の分離)
  • ログに SQL を直接書かない(セキュリティ配慮)

■ 実習④:サービス層との連携(責務分離)

DAO をそのまま UI から呼ぶのではなく、Service 層(ビジネスロジック)を挟む構造を実習しました。

例:BooksService の責務

  • 貸出可能かのチェック
  • 延滞時の例外処理
  • タイトル検索にバリデーションをかける
  • DAO の戻り値を UI 向けの形式に整形

生徒C:「実際に書いてみると DAO とサービスの境界が理解できてきた!」


■ 実習⑤:ミニ動作テスト(テーブル → DAO → サービス)

最後に、以下の流れでミニテストを実施。

サンプルデータ挿入
→ DAOで読み取り
→ Serviceでロジック適用
→ 結果の確認

例外が出たチームはその場で原因をログから追い、修正。
特に FK 整合性と NULL 制約に関するエラーが多く、良い学習機会になりました。


■ レビューとフィードバック

  • 良かった点:DAOの責務を守れている、SQL が整理されていた、例外時のロールバックが適切。
  • 改善点:返り値の型が曖昧、サービス層が肥大化しているチームあり。
  • 先生:「DAOは“薄く”、Serviceは“整理され”、Controller/UIは“最低限”が理想です。」

■ 先生のまとめのひとこと

「データベースとアプリをつなぐ設計は、品質に直結する大事な工程です。
今日学んだ“境界を丁寧に作ること”は、大規模開発でも必ず役立ちます。」


■ 宿題(次週に向けて)

  1. 各班の DAO クラス一覧とメソッド表 を作成し提出。
  2. DAO と Service のクラス図(簡易)を 1 枚まとめる。
  3. 来週の実装演習に向けて、主要ユースケース1つの処理フロー図を作成。

■ 来週の予告:アプリ全体のユースケース実装(結合)

次週は DAO とサービス層を実際の UI(Web/CLI)と結びつけ、
ユースケース単位でアプリを“動く形”へ組み立てる実装演習に入ります。


第36週目は「設計 → DB → 実装」への橋渡しを体験する密度の濃い週でした。
生徒たちは本格的なアプリケーションアーキテクチャを理解し始め、
次の“ユースケース結合フェーズ”に向けて着実に準備を進めています。

投稿者 greeden

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)