はじめに
今回はServiceを実装していきます!
ServiceはSpring Boot アプリケーションにおける「ビジネスロジック層(サービス層)」
ですね!
では実装していきましょう!
コード
package com.example.noteapp.backend.service;
import com.example.noteapp.backend.entity.User;
import com.example.noteapp.backend.repository.UserRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Service
@Transactional
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public List<User> findAll() {
return userRepository.findAll();
}
public Optional<User> findById(Long id) {
return userRepository.findById(id);
}
public User save(User user) {
return userRepository.save(user);
}
public void deleteById(Long id) {
userRepository.deleteById(id);
}
}
アノテーションの説明
@Service
- このクラスが サービス層であることを示す
- Spring によってDI対象(Bean)として管理される
@Transactional
- メソッド単位で トランザクション処理を行う
- 複数のDB操作がある場合、一括でコミット/ロールバックできる
コンストラクタ
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
-
UserRepository
を依存注入(DI) - DBアクセスに必要なリポジトリをサービスクラスに渡している
各メソッドの解説
findAll()
public List<User> findAll()
- 全ユーザーを取得する
- 戻り値は
List<User>
findById(Long id)
public Optional<User> findById(Long id)
- 指定した ID のユーザーを取得
-
Optional<User>
を返し、ユーザーが存在しないケースにも対応
Optionalを使う理由
理由 | 解説 |
---|---|
存在しないIDを扱う可能性があるから |
findById は「見つからないかも」という状況を想定しているため。 |
例外を投げずに、呼び出し側に判断を委ねられるから | Controllerや別のServiceが「404返す?例外投げる?無視する?」などを自由に選べる。 |
柔軟性・テスト性が上がる | 「存在しないとき」のテストも書きやすくなる。 |
save(User user)
public User save(User user)
- ユーザー情報を 新規作成 or 更新
- ID がある → 更新、ID がない → 新規登録
deleteById(Long id)
public void deleteById(Long id)
- 指定したユーザーを 削除
補足
コントローラーにビジネスロジックを直接書かないことで、責務の分離が実現できます。
将来的に処理が増えても、この UserService
に処理を集約することで保守性が高まります。
まとめ
メソッド名 | 説明 |
---|---|
findAll() |
全ユーザーの一覧を取得 |
findById(id) |
ID を指定してユーザー取得 |
save(user) |
ユーザーの保存(新規/更新) |
deleteById(id) |
ユーザーの削除 |