| この記事の要点 |
|---|
|
@Repository の役割
@Repository は次の 3 つの役割を持ちます:
- Bean 登録(
@Componentと同じ) - 意味付け: 「これは DAO 層のクラス」と明示
- 例外変換: JDBC / JPA の例外を
DataAccessException階層(Spring 標準)に変換
基本的な使い方
① 手書き DAO
@Repository
public class UserRepository {
private final JdbcTemplate jdbc;
public UserRepository(JdbcTemplate jdbc) {
this.jdbc = jdbc;
}
public User findById(Long id) {
return jdbc.queryForObject(
"SELECT id, name FROM users WHERE id = ?",
new BeanPropertyRowMapper<>(User.class),
id
);
}
public int save(User user) {
return jdbc.update(
"INSERT INTO users (name) VALUES (?)",
user.getName()
);
}
}
② Spring Data JPA のインタフェース
// インタフェースだけ書く(実装は Spring が自動生成)
@Repository // 省略しても認識される (Spring Boot)
public interface UserRepository extends JpaRepository<User, Long> {
// メソッド名から SQL を自動生成
Optional<User> findByEmail(String email);
List<User> findByStatusOrderByCreatedAtDesc(String status);
long countByStatus(String status);
// カスタムクエリ
@Query("SELECT u FROM User u WHERE u.email LIKE %:keyword%")
List<User> searchByEmail(@Param("keyword") String keyword);
// 更新クエリ
@Modifying
@Query("UPDATE User u SET u.status = :status WHERE u.id = :id")
int updateStatus(@Param("id") Long id, @Param("status") String status);
}
例外変換の効果
@Repository が付いていると、Spring の PersistenceExceptionTranslationPostProcessor が例外を変換します:
// 変換前 (生の SQLException や Hibernate 例外)
java.sql.SQLException: Duplicate entry 'user@example.com' for key 'users.email_unique'
// 変換後 (DataAccessException 階層)
org.springframework.dao.DuplicateKeyException
extends DataIntegrityViolationException
extends NonTransientDataAccessException
extends DataAccessException
extends RuntimeException
これによって:
- RuntimeException 化:
throws SQLException等を書かなくて済む(checked → unchecked) - DB 非依存: MySQL でも PostgreSQL でも同じ例外クラスでハンドリング
- サブクラス階層が利く:
catch(DataIntegrityViolationException)で UNIQUE 違反等を一括キャッチ
主な DataAccessException
| 例外 | 意味 |
|---|---|
EmptyResultDataAccessException | queryForObject で結果が 0 件 |
IncorrectResultSizeDataAccessException | queryForObject で複数件 |
DuplicateKeyException | UNIQUE 制約違反 |
DataIntegrityViolationException | 制約違反(NOT NULL / FK / CHECK) |
DeadlockLoserDataAccessException | デッドロック |
QueryTimeoutException | クエリタイムアウト |
BadSqlGrammarException | SQL 構文エラー |
OptimisticLockingFailureException | 楽観ロック失敗(@Version 使用時) |
PessimisticLockingFailureException | 悲観ロック失敗 |
例外ハンドリング例
@Service
public class UserService {
private final UserRepository userRepository;
public User register(User user) {
try {
return userRepository.save(user);
} catch (DuplicateKeyException e) {
throw new BusinessException("このメールアドレスは既に登録済みです");
} catch (DataIntegrityViolationException e) {
throw new BusinessException("入力データに問題があります: " + e.getMessage());
} catch (DataAccessException e) {
log.error("DB エラー", e);
throw new SystemException("システムエラーが発生しました");
}
}
}
@Repository vs @Service vs @Component
| アノテーション | 用途 | 特殊機能 |
|---|---|---|
@Component | 汎用 Bean | ― |
@Service | ビジネスロジック | 意味付けのみ |
@Repository | データアクセス | 例外変換 |
JPA Repository での自動実装
Spring Data JPA を使うと、インタフェースだけ書けば実装は自動生成されます:
// インタフェース宣言
public interface UserRepository extends JpaRepository<User, Long> { }
// Spring が自動でプロキシ実装を生成
// 主要メソッドが利用可能:
userRepository.save(user);
userRepository.findById(id);
userRepository.findAll();
userRepository.deleteById(id);
userRepository.count();
userRepository.existsById(id);
// 派生クエリ (Method Name Query)
List<User> findByName(String name);
List<User> findByStatusAndCreatedAtBetween(String status, LocalDateTime from, LocalDateTime to);
Page<User> findByName(String name, Pageable pageable);
// @Query で JPQL / Native SQL
@Query("SELECT u FROM User u WHERE u.email = ?1")
Optional<User> findByEmailCustom(String email);
@Query(value = "SELECT * FROM users WHERE email = ?1", nativeQuery = true)
Optional<User> findByEmailNative(String email);
関連記事
子ページ
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- プロジェクトをTomcatプロジェクトとして認識させる方法 2026-10-07 22:32:50
- MySQLの1366 Incorrect string value|Laravelの文字コード・絵文字エラー 2026-10-07 21:54:03
- curlの証明書ホスト名不一致|旧エラー51・現行60の確認と対処 2026-10-07 21:54:03
- LaravelのMassAssignmentException|fillableの原因と安全な対処 2026-10-07 21:54:03
- Eclipse で Tomcat の起動ログがコンソールに出ない時の確認手順 2026-10-07 21:54:02
- MySQLにおける中央値(Median)の導き方(バージョン8未満) 2026-10-07 13:49:45
- getInputForward 2026-10-07 13:41:15
- JSONから配列に変換 2026-10-07 13:41:15
- ビューから値をモデルに格納しコントローラーで受け取る方法 2026-10-07 13:23:41
- Laravelのテーブル作成と定義変更|マイグレーション・up/down・注意点 2026-10-07 13:23:41
- NumPy 配列に要素を追加する方法 (append / concatenate) 2026-10-07 13:23:41
- MariaDB・MySQLで現在日時を取得する方法|NOW・タイムゾーン・保存型 2026-10-07 13:13:36
- 【django】テンプレートで定数を使用する方法 2026-10-07 13:10:15
- Spring BootにおけるApplication.propertiesの環境依存設定の分割方法 2026-10-07 12:09:35
- Not supported for DML operations【Springエラー】 2026-10-07 11:09:38