初识Spring Data全家族(3)

每天叫醒你的不是闹钟,而是梦想

4

Spring Data JPA的事务支持

      Spring Data JPA对所有的默认方法都开启了事务支持,且查询事务默认启用readOnly = true属性(指定当前事务是只读事务

我们通过查看SimpleJpaRepository的部分源码,来查看Spring Data JPA的事务支持

@Repository
@Transactional(
 readOnly = true
)
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {
@Transactional
public void delete(T entity) {
 Assert.notNull(entity, "The entity must not be null!");
 this.em.remove(this.em.contains(entity) ? entity : this.em.merge(entity));
}

@Transactional
public void deleteAll(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);
 }

}

@Transactional
public void deleteInBatch(Iterable<T> entities) {
 Assert.notNull(entities, "The given Iterable of entities not be null!");
 if (entities.iterator().hasNext()) {
 QueryUtils.applyAndBind(QueryUtils.getQueryString("delete from %s x", this.entityInformation.getEntityName()), entities, this.em).executeUpdate();
 }
}

@Transactional
public void deleteAll() {
 Iterator var1 = this.findAll().iterator();

 while(var1.hasNext()) {
 T element = var1.next();
 this.delete(element);
 }

}
public T getOne(ID id) {
 Assert.notNull(id, "The given id must not be null!");
 return this.em.getReference(this.getDomainClass(), id);
}


public List<T> findAll() {
 return this.getQuery((Specification)null, (Sort)Sort.unsorted()).getResultList();
}



public List<T> findAll(Sort sort) {
 return this.getQuery((Specification)null, (Sort)sort).getResultList();
}

public Page<T> findAll(Pageable pageable) {
 return (Page)(isUnpaged(pageable) ? new PageImpl(this.findAll()) : this.findAll((Specification)null, pageable));
}


@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);
 }
}

@Transactional
public <S extends T> S saveAndFlush(S entity) {
 S result = this.save(entity);
 this.flush();
 return result;
}

@Transactional
public <S extends T> List<S> saveAll(Iterable<S> entities) {
 Assert.notNull(entities, "The given Iterable of entities not be null!");
 List<S> result = new ArrayList();
 Iterator var3 = entities.iterator();

 while(var3.hasNext()) {
 S entity = var3.next();
 result.add(this.save(entity));
 }

 return result;
}

@Transactional
public void flush() {
 this.em.flush();
}
}

从源码中我们可以看出, SimpleJpaRepository在类级别定义了@Transactional(readOnly = true), 而在和save、delete相关的操作重写了@Transactional属性,此时readOnly属性是false,其余查询操作readOnly仍然为true

注意:@Transactional不仅可以注解在方法上, 也可以注解在类。当注解在类上的时候意味着此类的所有public方法都是开启事务的。如果类级别和方法级别同时使用了@Transactional注解,则使用方法级别覆盖类级别注解

readOnly的默认值为false

5

Spring Data JPA事务回滚实例

package com.zero.ch8_2.service.impl;

import com.zero.ch8_2.dao.PersonRepository;
import com.zero.ch8_2.domain.Person;
import com.zero.ch8_2.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Author: Zero
 * @Date: 2019/4/15 22:33
*/
public class PersonServiceImpl implements PersonService {

 @Autowired
 PersonRepository personRepository;


 @Override
 @Transactional(rollbackFor = {IllegalArgumentException.class}) //rollbackFor属性,指定特定异常时,数据回滚
 public Person savePersonWithRollBack(Person person) {
 Person p = personRepository.save(person);

 if(person.getName() .equals("zero")){
 throw new IllegalArgumentException("zero already exist,data will rollback");
 }
 return p;
 }

 @Override
 @Transactional(noRollbackFor = {IllegalArgumentException.class}) noRollbackFor属性,指定特定异常时,数据不回滚
 public Person savePersonWithoutRollBack(Person person) {

 Person p = personRepository.save(person);

 if(person.getName() .equals("zero")){
 throw new IllegalArgumentException("zero already exist,data will not rollback");
 }
 return p;
 }
}

6

数据缓存 Cache

6.1 什么是缓存

       我们知道一个程序的瓶颈在于数据库, 我们也知道内存的速度是大大快于硬盘的速度的。 当我们需要重复地获取相同的数据的时候,我们一次又一次的请求数据库, 导致大量的时间耗费在数据库查询方法的调用上,导致程序性能的恶化,这便是数据缓存要解决的问题。

6.2声名式缓存注解

  • @Cacheble  : 在方法执行前Spring先查看缓存中是否有数据, 如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放进缓存

  • @CachePut : 无论怎样,都会将方法的返回值放到缓存中。 @CachePut的属性与@Cacheable保持一致。

  • @CacheEvict : 将一条或多条数据从缓存中删除。

  • @Caching : 可以通过@Caching注解组合多个注解策略在一个方法上。

首先在启动类中添加缓存注解

package com.zero.ch8_2;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class Ch82Application {

 public static void main(String[] args) {
 SpringApplication.run(Ch82Application.class, args);
 }

}
package com.zero.ch8_2.service.impl;

import com.zero.ch8_2.dao.PersonRepository;
import com.zero.ch8_2.domain.Person;
import com.zero.ch8_2.service.CacheService;
import org.hibernate.annotations.Cache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;



/**
 * @Author: Zero
 * @Date: 2019/4/15 23:58
*/
public class CacheServiceImpl implements CacheService {

 @Autowired
 PersonRepository personRepository;


 @Override
 @CachePut(value = "people", key = "#person.id")
 // 缓存新增的或更新的数据到缓存, 其中缓存名称为people, 数据的key是person的id
 public Person save(Person person) {
 Person p = personRepository.save(person);

 return p;
 }

 @Override
 @CacheEvict(value = "people")
 // @CacheEvict从缓存people中删除key为id的数据
 public void remove(Long id) {

 personRepository.delete(id);
 }

 @Override
 @Cacheable(value = "people", key = "#people.id")
 // @Cacheable缓存key为person的id数据到缓存people中
 public Person findOne(Person person) {
 Person p = personRepository.findOne(person.getId());
 return p;
 }
}

历史文章

初始Spring Data全家族(2)

初识Spring Data 全家族(1)

点击蓝字关注我们

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值