Spring Data JPA中CrudRepository常用方法及其底层源码解读

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是否为空,来判断执行哪个操作,这个在之前的博客中有说明。
在这里需要关注下该方法上的事务注解@Transactional。我们在调用完save()方法后,从日志里可以看出有commit,这说明save方法会自动完成事务提交,而不依赖于所在方法的事务,其原因就是save方法本身就是一个事务。
2.save(Iterable entities)
Iterable其实就是我们常用的集合List,List继承了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);
        }
    }

删除多个实体,首先判断集合是否为空,不为空则遍历集合进行删除,同样会自动完成事务提交。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值