Spring Data JPAにおけるCrudRepositoryの一般的な方法とその下位ソースコードの解読

17200 ワード

Spring Data JPAではCrudRepositoryの一般的なメソッドとその下位ソースコードの解読Spring Data JPAを使用しており、Daoレイヤオブジェクトは実際にSimpleJpaRepositoryのエージェントオブジェクトであり、このクラスでは各メソッドがどのように実現されているかを見ることができます.1.save(S entity)
@Transactional
    public <S extends T> S save(S entity) {
        if(this.entityInformation.isNew(entity)) {
            this.em.persist(entity);
            return entity;
        } else {
            return this.em.merge(entity);
        }
    }

save()メソッドには、エンティティentityに入力されたプライマリ・キーIDが空であるか否かに基づいて、どの操作が実行されるかを判断する2つの機能が含まれており、これは前のブログで説明した.ここでは,このメソッド上のトランザクション注記@Transactionalに注目する必要がある.save()メソッドを呼び出すと、ログからcommitが表示されます.これは、saveメソッドがメソッドのトランザクションに依存せずにトランザクションのコミットを自動的に完了することを示します.その理由は、saveメソッド自体がトランザクションであるためです.2.save(Iterable entities)Iterableは実は私たちがよく使う集合リストであり、リストはIterableを継承しており、以下に示す.
public interface List<E> extends Collection<E> {}
public interface Collection<E> extends Iterable<E> {
@Transactional
    public <S extends T> List<S> save(Iterable<S> entities) {
        List<S> result = new ArrayList();
        if(entities == null) {
            return result;
        } else {
            Iterator var3 = entities.iterator();
            while(var3.hasNext()) {
                S entity = var3.next();
                result.add(this.save(entity));
            }
            return result;
        }
    }

saveメソッドを使用してコレクションを保存すると、saveメソッドはまずそのコレクションが空であるかどうかを判断し、空ではないかを判断し、各エンティティを反復して取得し、エンティティを保存または更新します.同様に、このメソッドはトランザクションを持参します.
save(S entity)メソッドとsave(Iterable entities)メソッドには、操作されたエンティティオブジェクトまたはエンティティオブジェクトのセットを返す戻り値があります.3.findOne(ID id)
 public T findOne(ID id) {
        Assert.notNull(id, "The given id must not be null!");
        Class<T> domainType = this.getDomainClass();
        if(this.metadata == null) {
            return this.em.find(domainType, id);
        } else {
            LockModeType type = this.metadata.getLockModeType();
            Map<String, Object> hints = this.metadata.getQueryHints();
            return type == null?this.em.find(domainType, id, hints):this.em.find(domainType, id, type, hints);
        }
    }
public static void notNull(Object object, String message) {
        if(object == null) {
            throw new IllegalArgumentException(message);
        }
    }

findOneは、プライマリ・キーIDに基づいてクエリーを行い、まずIDが空であるか否かを判断し、空であるか否かを判断すると、IllegalArgumentExceptionの不正なパラメータ異常が投げ出され、次に現在のエンティティー・クラス・オブジェクトを取得し、反射によりデータをクエリーする.4.delete(ID id)
@Transactional
    public void delete(ID id) {
        Assert.notNull(id, "The given id must not be null!");
        T entity = this.findOne(id);
        if(entity == null) {
            throw new EmptyResultDataAccessException(String.format("No %s entity with id %s exists!", new Object[]{this.entityInformation.getJavaType(), id}), 1);
        } else {
            this.delete(entity);
        }
    }

プライマリ・キーIDを押して削除し、まずIDが空かどうかを判断し、次にfindOneを呼び出してIDに基づいてエンティティを問合せ、nullを返すと対応するエンティティに存在しない異常を投げ出し、エンティティが存在する場合は削除する.このメソッドは@Transactionalで修飾され、トランザクションのコミットが自動的に完了します.5.delete(Iterable extends T> entities)
 @Transactional
    public void delete(Iterable<? extends T> entities) {
        Assert.notNull(entities, "The given Iterable of entities not be null!");
        Iterator var2 = entities.iterator();
        while(var2.hasNext()) {
            T entity = var2.next();
            this.delete(entity);
        }
    }

複数のエンティティを削除すると、まずコレクションが空であるかどうかを判断し、空でない場合はコレクションを巡回して削除し、トランザクションのコミットも自動的に完了します.