Spring BootでのDAOの設計:適切な切り分け方(新人エンジニア向け)
こんにちは。ゆうせいです。
Spring Boot でWebアプリケーションを作るとき、
「DAO(Data Access Object)ってどうやって設計すればいいの?」 と思うことがありますよね。
✅ DAOは何のために必要?
✅ DAOをどこまで作るべき?
✅ DAOをどう切り分ければ、メンテナンスしやすい設計になる?
結論:
DAOは「データベースとのやりとり専用」にし、@Repository
を使って管理するのが基本!
今回は、新人エンジニア向けに、Spring BootのDAOの適切な設計方法 をわかりやすく解説します!
1. DAO(Data Access Object)とは?
DAO(データアクセスオブジェクト)は、
データベースとのやりとりを行うクラス(レイヤー) です。
📌 DAOの役割
- データベースへの接続(CRUD操作)
- SQLを実行してデータを取得・更新
- アプリケーションの他の部分(Service や Controller)からSQLの記述を隠蔽
2. DAOを使わないとどうなる?(悪い例)
DAOを使わずに、コントローラーやサービス層に直接SQLを書いてしまう のは避けるべきです。
@RestController
@RequestMapping("/users")
public class UserController {
private final JdbcTemplate jdbcTemplate;
public UserController(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
String sql = "SELECT * FROM users WHERE id = ?";
return jdbcTemplate.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper<>(User.class));
}
}
❌ この設計の問題点
- SQLがControllerやServiceに直接書かれると、コードが汚れる
- データベースの処理が散らばり、修正が難しくなる
- テストがしにくい(データアクセスの処理をモックできない)
📌 DAOを使うことで、SQLを専用クラスに分離し、責務を明確にできる!
3. DAOの適切な設計
✅ DAOの基本的な構成
クラス | 役割 |
---|---|
DAO(UserDao など) | データベースアクセス(SQLの実行) |
Entity(User ) | データベースの1行を表す |
Repository(UserRepository ) | Spring Data JPA を利用したDB操作 |
Service(UserService ) | ビジネスロジック |
📌 DAO は @Repository
を付けて、データアクセス専用のレイヤーとして設計する!
✅ 適切なDAOの作り方(JDBC版)
1. エンティティ(User
)
public class User {
private Long id;
private String username;
private String email;
// ゲッター・セッター
}
📌 データベースの1行を表すクラス
2. DAOインターフェース(UserDao
)
public interface UserDao {
User findById(Long id);
List<User> findAll();
void save(User user);
void update(User user);
void delete(Long id);
}
📌 DAOインターフェースを定義し、実装クラスを作る
3. DAO実装(UserDaoImpl
)
@Repository
public class UserDaoImpl implements UserDao {
private final JdbcTemplate jdbcTemplate;
public UserDaoImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public User findById(Long id) {
String sql = "SELECT * FROM users WHERE id = ?";
return jdbcTemplate.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper<>(User.class));
}
@Override
public List<User> findAll() {
String sql = "SELECT * FROM users";
return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
}
@Override
public void save(User user) {
String sql = "INSERT INTO users (username, email) VALUES (?, ?)";
jdbcTemplate.update(sql, user.getUsername(), user.getEmail());
}
@Override
public void update(User user) {
String sql = "UPDATE users SET username = ?, email = ? WHERE id = ?";
jdbcTemplate.update(sql, user.getUsername(), user.getEmail(), user.getId());
}
@Override
public void delete(Long id) {
String sql = "DELETE FROM users WHERE id = ?";
jdbcTemplate.update(sql, id);
}
}
📌 JdbcTemplate
を使ってSQLを実行し、データを取得・更新する
4. サービス層でDAOを利用(UserService
)
@Service
public class UserService {
private final UserDao userDao;
public UserService(UserDao userDao) {
this.userDao = userDao;
}
public User getUserById(Long id) {
return userDao.findById(id);
}
public List<User> getAllUsers() {
return userDao.findAll();
}
public void createUser(User user) {
userDao.save(user);
}
public void updateUser(User user) {
userDao.update(user);
}
public void deleteUser(Long id) {
userDao.delete(id);
}
}
📌 Service層ではDAOを呼び出してビジネスロジックを実行!
5. コントローラーでサービスを利用(UserController
)
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.getUserById(id);
}
@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}
@PostMapping
public void createUser(@RequestBody User user) {
userService.createUser(user);
}
@PutMapping("/{id}")
public void updateUser(@PathVariable Long id, @RequestBody User user) {
user.setId(id);
userService.updateUser(user);
}
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
}
}
📌 Controller層では @Service
を呼び出して、データを取得・更新する!
4. まとめ
設計のポイント | 説明 |
---|---|
DAOはデータアクセス専用にする | SQLの記述をDAOに集約し、他のレイヤーに影響を与えない |
DAOは@Repository を付ける | Springが自動的にDI管理してくれる |
DAOのインターフェースを作る | 実装を変更しやすくなる(JPAや別DBへの移行がスムーズ) |
Controller → Service → DAO の流れを守る | コントローラーでは直接DAOを呼び出さない |
5. 結論
🚀 DAOは「データベースとのやりとり専用」にし、SQLの実行を分離!
🚀 DAOのインターフェースを作ることで、実装の変更がしやすくなる!
🚀 Controller → Service → DAO の流れを守り、レイヤーごとに役割を明確にする!
この設計を守れば、「拡張しやすく、メンテナンスしやすいSpring Bootアプリ」 を作れます!
ぜひ実践してみてください!ことが大切!
これを意識して、エンジニアが自発的に学べる環境を作っていきましょう!
セイ・コンサルティング・グループでは新人エンジニア研修のアシスタント講師を募集しています。
投稿者プロフィール

- 代表取締役
-
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。