Spring Boot+Spring Data JPA+Spring Cache

本文使用spring boot 快速构建项目工程,spring data jpa 控制数据访问服务层,spring cache 缓存查询数据html

1.pom.xml 配置信息及application.propertiesjava

<strong><?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>org.springframework</groupId>
	<artifactId>com-my-data-cache</artifactId>
	<version>0.1.0</version>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.3.1.RELEASE</version>
	</parent>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
	
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<!-- data jpa注解 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
			<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>
		<dependency>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-thymeleaf</artifactId>  
        </dependency>  
		<!-- 应用容器 -->
			<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jetty</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
		</dependency>
		<!-- 缓存cache -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>
		<!-- redis缓存 -->
	<!-- 	<dependency>  
          <groupId>org.springframework.boot</groupId>  
          <artifactId>spring-boot-starter-redis</artifactId>  
      </dependency>   -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-commons</artifactId>
		</dependency>
		<!-- 日志管理log -->
			<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-log4j</artifactId>
		</dependency>
		<!-- 配置权限拦截 -->
		<!-- <dependency>
		 <groupId>org.springframework.boot</groupId>
		  <artifactId>spring-boot-starter-security</artifactId> 
			</dependency>  -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
			<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
			<dependency>
				<groupId>org.hibernate</groupId>
				<artifactId>hibernate-entitymanager</artifactId>
			</dependency>
			<dependency>
	<groupId>javax.servlet</groupId>
	<artifactId>javax.servlet-api</artifactId>
</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>
</strong>
# primary datasource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url= jdbc:mysql://localhost/mydat
spring.datasource.username=root
spring.datasource.password= wb12345



2.新建实体类对象 BOOKmysql

<strong>package com.my.data.cache.domain;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="book")
public class Book implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -6283522837937163003L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", nullable = true)
	private Integer id;
    private String isbn;
    private String title;

    public Book(String isbn, String title) {
        this.isbn = isbn;
        this.title = title;
    }
    public Book() {
	}
	public Book(int id, String isbn, String title) {
		super();
		this.id = id;
		this.isbn = isbn;
		this.title = title;
	}


	public int getId() {
		return id;
	}




	public void setId(int id) {
		this.id = id;
	}




	public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    @Override
    public String toString() {
        return "Book{" + "isbn='" + isbn + '\'' + ", title='" + title + '\'' + '}';
    }
}
</strong>
3.建立DAO接口,该接口采用Spring Data JPA 持久层技术,能够采用命名查询,注解查询,命名参数查询等查询方式,
<strong>package com.my.data.cache.repository;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import com.my.data.cache.domain.Book;
/**
 * 接口
 * @author wbw
 *
 */
public interface BookRepository extends JpaRepository<Book, Integer> {

  @Query("select b from Book b  where 1=1")
  public   List<Book> findBookAll();
  /**
   * 根据isbn查询
   * @param name
   * @return
   */
  @Query("select  b from Book b where b.id =?1")
  public  Book findById(Integer bid);
   /**
    * 统计size  
    * @return
    */
  @Query("select count(*) from Book where 1=1 ")
  public int countBook();
  /**
   * 根据命名规范查询 findBy+属性
   * @param isbn
   * @return
   */
  public Book findByIsbn(String isbn);

}
</strong>

4.建立service业务逻辑处理层接口及实现接口

<strong>package com.my.data.cache.service;

import java.util.List;

import com.my.data.cache.domain.Book;

public interface BookService {

	public Book findById(Integer bid);

	public List<Book> findBookAll();

	public void insertBook(Book book);

	public Book findByTitle(String title);
	
	public int countBook();
	
	public void modifyBook(Book book);
	
	 public Book findByIsbn(String isbn);
	
	
}
</strong>

<strong>package com.my.data.cache.service.impl;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.my.data.cache.annotation.LogAnnotation;
import com.my.data.cache.domain.Book;
import com.my.data.cache.exception.MyException;
import com.my.data.cache.repository.BookRepository;
import com.my.data.cache.service.BookService;

@Service
@Transactional
public class BookServiceImpl  implements BookService{
	private static final Logger log = LoggerFactory.getLogger(BookServiceImpl.class);
	@Autowired
	private BookRepository bookRepository;
	
	/*@PersistenceContext
	private EntityManager em;*/
	
	//将缓存保存进andCache,并使用参数中的bid加上一个字符串(这里使用方法名称)做为缓存的key
	@Cacheable(value="andCache",key="#bid+'findById'")
	//@LogAnnotation(value="经过Id查询Book")
	public Book findById(Integer bid) {
		this.simulateSlowService();
		return bookRepository.findById(bid);
	}
	
	@Override
	public List<Book> findBookAll() {
		return bookRepository.findBookAll();
	}
    
	//将缓存保存进andCache,并当参数title的长度小于32时才保存进缓存,默认使用参数值及类型做为缓存的key 
	@Cacheable(value="andCache",condition="#title.length >5") 
	public Book findByTitle(String title){
		return null;
		
	}
	/**
	 * 新增
	 * @param book
	 * @return
	 */
	public void insertBook(Book book){
		bookRepository.save(book);
	}
	
	@Override
	public int countBook() {
		return bookRepository.countBook();
	}  
	//清除掉指定key中的缓存
	@CacheEvict(value="andCache",key="#book.id + 'findById'")
	public void modifyBook(Book book) {
		log.info("清除指定缓存"+book.getId()+"findById");
		bookRepository.save(book);
	}
	
	//清除掉所有缓存  
	@CacheEvict(value="andCache",allEntries=true,beforeInvocation=true)  
	public void ReservedBook() {  
		log.info("清除所有的缓存");  
	}

	// Don't do this at home
    private void simulateSlowService() {
        try {
            long time = 5000L;
            Thread.sleep(time);
        } catch (InterruptedException e) {
            throw new MyException("程序出错", e);
        }
    }

	@Override
	public Book findByIsbn(String isbn) {
		return bookRepository.findByIsbn(isbn);
	}
}
</strong>

5.建立controller控制器

<strong>package com.my.data.cache.controller;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.my.data.cache.domain.Book;
import com.my.data.cache.service.BookService;

@RestController 
@RequestMapping("/user")  
public class BookController {
	private static final Logger log = LoggerFactory.getLogger(BookController.class);
    
	@Autowired
    private BookService bookService;
	
    
    @RequestMapping("/{id}")
	public @ResponseBody Book index(@PathVariable("id") Integer id){
		Book b = bookService.findById(id);
	    log.info(b.getIsbn()+"------>"+b.getTitle());
  		return b;
	}
    
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public  @ResponseBody List<Book> list(){
    	List<Book> b = bookService.findBookAll();
		return  b;
    	
    }
    @RequestMapping(value = "/add")
    public String  insertBook(){
    	Book b = new Book();
    	b.setId(4);
    	b.setIsbn("1111");
    	b.setTitle("相信本身");
    	bookService.insertBook(b);
    	return "success";
    	
    }    
    /**
     * 更新
     * @return
     */
    @RequestMapping(value = "/update")
    public String update(){
    	Book b = new Book();
    	b.setId(1);
    	b.setIsbn("1");
    	b.setTitle("爱的力量");
    	bookService.modifyBook(b);
    	return "success";
    }
}
</strong>

6.测试

<strong>package com.my.data.cache;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

import com.my.data.cache.domain.Book;
import com.my.data.cache.service.BookService;


/**
 * 
 * 启动器
 *
 */
@SpringBootApplication
@EnableCaching//扫描cahce注解
public class Application1  implements CommandLineRunner{
	
	@Autowired
    private BookService bookService;
	@Override
	public void run(String... args) throws Exception {
		Book b1 = bookService.findByIsbn("1");
		Book b2 = bookService.findByIsbn("2");
		Book b3 = bookService.findById(3);
	    System.out.println(b1);
        System.out.println(b2);
        System.out.println(b3);
		
	}
	public static void main(String[] args) {
		 SpringApplication.run(Application1.class,args);
	}

}</strong>

Spring Cache

3.1开始,Spring引入了对Cache的支持。其使用方法和原理都相似于Spring对事务管理的支持。Spring Cache是做用在方法上的,其核心思想是这样的:当咱们在调用一个缓存方法时会把该方法参数和返回结果做为一个键值对存放在缓存中,等到下次利用一样的参数来调用该方法时将再也不执行该方法,而是直接从缓存中获取结果进行返回。因此在使用Spring Cache的时候咱们要保证咱们缓存的方法对于相同的方法参数要有相同的返回结果。
web

 使用Spring Cache须要咱们作两方面的事:redis

n  声明某些方法使用缓存spring

n  配置Spring对Cache的支持sql

和Spring对事务管理的支持同样,Spring对Cache的支持也有基于注解和基于XML配置两种方式apache

想了解更多相关的信息连接该地址:
https://www.ibm.com/developerworks/cn/opensource/os-cn-spring-cache/