ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|---|
|
@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=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページ
子ページはありません
人気ページ
- 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 Spring Frameworkのアノテーション一覧
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- PHPでのファイルアップロード方法|multipart/form-dataと$_FILES 2026-08-07 17:15:57
- PHP $_SERVERとは|DOCUMENT_ROOT・PHP_SELFなど主な要素 2026-08-07 17:15:57
- Scratchのアカウントの作り方|メールアドレスとユーザー名の登録手順 2026-08-07 17:15:57
- djangoにおけるMVCアプリケーション実装例 2026-08-07 17:15:57
- Bluetoothとは|仕組み・BLEとClassicの違い・用途 2026-08-07 17:15:57
- Spring Bootのテスト入門|@SpringBootTestとJUnitでの単体・結合テスト 2026-08-07 17:15:57
- APIキー取得方法 2026-08-07 17:15:56
- インストール方法(Windows版) 2026-08-07 17:15:56
- Java とは?言語仕様・JVM・主要フレームワーク一覧 2026-08-07 17:15:56
- 【PHPフレームワーク】Laravelの使い方 2026-08-07 17:15:56
- Scratch 作品の公開方法 2026-08-07 17:15:56
- Google OAuth 2.0 認証の実装方法 2026-08-07 17:15:56
- データベースとは?RDB / NoSQL / SQL の基礎 2026-08-07 17:15:56
- インストール(eclipseプラグイン) 2026-08-07 17:15:56
- Spring Frameworkの使い方 2026-08-07 17:15:56
コメントを削除してもよろしいでしょうか?