【视频 & 交流平台】
http://study.163.com/course/introduction.htm?courseId=1004329008&utm_campaign=commission&utm_source=400000000155061&utm_medium=share
http://study.163.com/course/introduction.htm?courseId=1004638001&utm_campaign=commission&utm_source=400000000155061&utm_medium=share
https://gitee.com/happyangellxq520/spring-boot
http://412887952-qq-com.iteye.com/blog/2321532
【本文章是否对你有用以及是否有好的建议,请留言】
写后感:博主写这么一系列文章也不容易啊,请评论支持下。
如果看过我之前(35)的文章这一篇的文章就会很简单,没有什么挑战性了。
那么我们先说说这一篇文章我们都会学到的技术点:Spring Data JPA,SpringBoot使用Mysql,Spring MVC,EHCache,Spring Cache等(其中@Cacheable请看上一节的理论知识),具体分如下几个步骤:
(1)新建Maven Java Project
(2)在pom.xml中加入依赖包
(3)编写Spring Boot启动类;
(4)配置application.properties;
(5)编写缓存配置类以及ehcache.xml配置文件;
(6)编写DemoInfo实体类进行测试;
(7)编写持久类DemoInfoRepository;
(8)编写处理类DemoInfoService;
(9)编写DemoInfoController测试类;
(10)运行测试;
以上就是具体的步骤了,那么接下来我们一起按照这个步骤来进行实现吧。
(1)新建Maven Java Project
新建一个工程名为spring-boot-ehcache的maven java project。
(2)在pom.xml中加入依赖包
在pom.xml文件中加入相应的依赖包,SpringBoot父节点依赖包;spring boot web支持;缓存依赖spring-context-support;集成ehcache需要的依赖;JPA操作数据库;mysql 数据库驱动,具体pom.xml文件:
<projectxmlns="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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.kfit</groupId>
<artifactId>spring-boot-ehcache</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-boot-ehcache</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 配置JDK编译版本. -->
<java.version>1.8</java.version>
</properties>
<!-- springboot 父节点依赖,
引入这个之后相关的引入就不需要添加version配置,
spring boot会自动选择最合适的版本进行添加。
-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
<!-- 单元测试. -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- springboot web支持:mvc,aop... -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--
包含支持UI模版(Velocity,FreeMarker,JasperReports),
邮件服务,
脚本服务(JRuby),
缓存Cache(EHCache),
任务计划Scheduling(uartz)。
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!-- 集成ehcache需要的依赖-->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<!-- JPA操作数据库. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- mysql数据库驱动. -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Spring boot单元测试. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
(3)编写Spring Boot启动类(com.kfit.App.java);
package com.kfit;
importorg.springframework.boot.SpringApplication;
importorg.springframework.boot.autoconfigure.SpringBootApplication;
/**
*
*
*@SpringBootApplication申明让spring boot自动给程序进行必要的配置,
*
@SpringBootApplication
等待于:
@Configuration
@EnableAutoConfiguration
@ComponentScan
*
*@author Angel(QQ:412887952)
*@version v.0.1
*/
@SpringBootApplication
publicclass App {
publicstaticvoid main(String[]args) {
SpringApplication.run(App.class,args);
}
}
(4)配置application.properties;
在application.properties中主要配置数据库连接和JPA的基本配置,具体如下:
Src/main/resouces/application.properties:
########################################################
###datasource ,mysql数据库连接配置
########################################################
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username= root
spring.datasource.password= root
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.max-active=20
spring.datasource.max-idle=8
spring.datasource.min-idle=8
spring.datasource.initial-size=10
########################################################
### Java Persistence Api,JPA自动建表操作配置
########################################################
# Specify the DBMS
spring.jpa.database= MYSQL
# Show or not log for each sqlquery
spring.jpa.show-sql= true
# Hibernate ddl auto (create,create-drop, update)
spring.jpa.hibernate.ddl-auto= update
# Naming strategy
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
# stripped before adding them tothe entity manager)
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
(5)编写缓存配置类以及ehcache.xml配置文件:
这个类主要是注册缓存管理对象EhCacheCacheManager、缓存工厂对象EhCacheManagerFactoryBean,具体代码如下:
EhCacheManagerFactoryBean:
package com.kfit.config;
importorg.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
importorg.springframework.cache.ehcache.EhCacheManagerFactoryBean;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.core.io.ClassPathResource;
/**
*缓存配置.
*@author Angel(QQ:412887952)
*@version v.0.1
*/
@Configuration
@EnableCaching//标注启动缓存.
publicclass CacheConfiguration {
/**
* ehcache主要的管理器
*@param bean
*@return
*/
@Bean
publicEhCacheCacheManager ehCacheCacheManager(EhCacheManagerFactoryBeanbean){
System.out.println("CacheConfiguration.ehCacheCacheManager()");
returnnewEhCacheCacheManager(bean.getObject());
}
/*
*据shared与否的设置,
* Spring分别通过CacheManager.create()
*或new CacheManager()方式来创建一个ehcache基地.
*
*也说是说通过这个来设置cache的基地是这里的Spring独用,还是跟别的(如hibernate的Ehcache共享)
*
*/
@Bean
public EhCacheManagerFactoryBean ehCacheManagerFactoryBean(){
System.out.println("CacheConfiguration.ehCacheManagerFactoryBean()");
EhCacheManagerFactoryBeancacheManagerFactoryBean =newEhCacheManagerFactoryBean ();
cacheManagerFactoryBean.setConfigLocation (newClassPathResource("conf/ehcache.xml"));
cacheManagerFactoryBean.setShared(true);
returncacheManagerFactoryBean;
}
}
在src/main/resouces/conf下编写ehcache.xml配置文件,当然这个文件你可以放在其它目录下:
<?xmlversion="1.0"encoding="UTF-8"?>
<ehcachexmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<!--
diskStore:为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置。参数解释如下:
user.home–用户主目录
user.dir –用户当前工作目录
java.io.tmpdir–默认临时文件路径
-->
<diskStore path="java.io.tmpdir/Tmp_EhCache"/>
<!--
defaultCache: 默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策略。只能定义一个。
-->
<!--
name:缓存名称。
maxElementsInMemory:缓存最大数目
maxElementsOnDisk:硬盘最大缓存个数。
eternal:对象是否永久有效,一但设置了,timeout将不起作用。
overflowToDisk:是否保存到磁盘,当系统当机时
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
diskPersistent:是否缓存虚拟机重启期数据Whether the disk store persists between restarts of the Virtual Machine. Thedefault value is false.
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
clearOnFlush:内存数量最大时是否清除。
memoryStoreEvictionPolicy:可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。
FIFO,first in firstout,这个是大家最熟的,先进先出。
LFU, Less FrequentlyUsed,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
LRU,Least RecentlyUsed,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
-->
<defaultCache
eternal="false"
maxElementsInMemory="1000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LRU"/>
<cache
name="demo"
eternal="false"
maxElementsInMemory="100"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="300"
memoryStoreEvictionPolicy="LRU"/>
</ehcache>
(6)编写DemoInfo实体类进行测试;
在com.kfit.bean下编写DemoInfo实体类进行缓存测试:
package com.kfit.bean;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
*测试实体类.
*@author Angel(QQ:412887952)
*@version v.0.1
*/
@Entity
publicclass DemoInfo {
@Id @GeneratedValue
privatelongid;//主键.
private Stringname;//名称;
private Stringpwd;//密码;
privateintstate;
publiclong getId() {
returnid;
}
publicvoid setId(longid) {
this.id =id;
}
public String getName(){
returnname;
}
publicvoid setName(Stringname) {
this.name =name;
}
public String getPwd(){
returnpwd;
}
publicvoid setPwd(Stringpwd) {
this.pwd =pwd;
}
publicint getState() {
returnstate;
}
publicvoid setState(intstate) {
this.state =state;
}
@Override
public StringtoString() {
return"DemoInfo[id=" +id +", name=" +name +", pwd=" +pwd +", state=" +state +"]";
}
}
(7)编写持久类DemoInfoRepository;
编写持久类DemoInfoRepository:
com.kfit.repository.DemoInfoRepository:
package com.kfit.repository;
importorg.springframework.data.repository.CrudRepository;
import com.kfit.bean.DemoInfo;
/**
*操作数据库.
*@author Angel(QQ:412887952)
*@version v.0.1
*/
publicinterfaceDemoInfoRepositoryextends CrudRepository<DemoInfo,Long>{
}
(8)编写处理类DemoInfoService;
编写增删改查的方法,在这几个方法中都使用注解缓存,进行缓存的创建以及删除,修改等操作:
com.kfit.service.DemoInfoService:
package com.kfit.service;
import com.kfit.bean.DemoInfo;
import javassist.NotFoundException;
publicinterface DemoInfoService{
void delete(Longid);
DemoInfoupdate(DemoInfoupdated)throws NotFoundException;
DemoInfofindById(Long id);
DemoInfosave(DemoInfo demoInfo);
}
com.kfit.service.impl.DemoInfoServiceImpl:
package com.kfit.service.impl;
import javax.annotation.Resource;
importorg.springframework.cache.annotation.CacheEvict;
importorg.springframework.cache.annotation.CachePut;
importorg.springframework.cache.annotation.Cacheable;
importorg.springframework.stereotype.Service;
import com.kfit.bean.DemoInfo;
import com.kfit.repository.DemoInfoRepository;
import com.kfit.service.DemoInfoService;
import javassist.NotFoundException;
@Service
publicclass DemoInfoServiceImplimplements DemoInfoService{
//这里的单引号不能少,否则会报错,被识别是一个对象;
publicstaticfinal StringCACHE_KEY ="'demoInfo'";
@Resource
private DemoInfoRepositorydemoInfoRepository;
/**
* value属性表示使用哪个缓存策略,缓存策略在ehcache.xml
*/
publicstaticfinal StringDEMO_CACHE_NAME ="demo";
/**
*保存数据.
*@param demoInfo
*/
@CacheEvict(value=DEMO_CACHE_NAME,key=CACHE_KEY)
@Override
public DemoInfosave(DemoInfodemoInfo){
returndemoInfoRepository.save(demoInfo);
}
/**
*查询数据.
*@param id
*@return
*/
@Cacheable(value=DEMO_CACHE_NAME,key="'demoInfo_'+#id")
@Override
public DemoInfofindById(Longid){
System.err.println("没有走缓存!"+id);
returndemoInfoRepository.findOne(id);
}
/**
* http://www.mincoder.com/article/2096.shtml:
*
*修改数据.
*
*在支持Spring Cache的环境下,对于使用@Cacheable标注的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。@CachePut也可以声明一个方法支持缓存功能。与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。
@CachePut也可以标注在类上和方法上。使用@CachePut时我们可以指定的属性跟@Cacheable是一样的。
*
*@param updated
*@return
*
*@throws NotFoundException
*/
@CachePut(value = DEMO_CACHE_NAME,key ="'demoInfo_'+#updated.getId()")
//@CacheEvict(value= DEMO_CACHE_NAME,key = "'demoInfo_'+#updated.getId()")//这是清除缓存.
@Override
public DemoInfoupdate(DemoInfoupdated)throws NotFoundException{
DemoInfodemoInfo =demoInfoRepository.findOne(updated.getId());
if(demoInfo ==null){
throw newNotFoundException("No find");
}
demoInfo.setName(updated.getName());
demoInfo.setPwd(updated.getPwd());
returndemoInfo;
}
/**
*删除数据.
*@param id
*/
@CacheEvict(value = DEMO_CACHE_NAME,key ="'demoInfo_'+#id")//这是清除缓存.
@Override
publicvoid delete(Longid){
demoInfoRepository.delete(id);
}
}
(9)编写DemoInfoController测试类;
编写一个rest进行测试:
com.kfit.controller.DemoInfoController:
package com.kfit.controller;
import javax.annotation.Resource;
importorg.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.kfit.bean.DemoInfo;
import com.kfit.service.DemoInfoService;
import javassist.NotFoundException;
@RestController
publicclass DemoInfoController {
@Resource
private DemoInfoServicedemoInfoService;
@RequestMapping("/test")
public String test(){
//存入两条数据.
DemoInfo demoInfo = new DemoInfo();
demoInfo.setName("张三");
demoInfo.setPwd("123456");
DemoInfo demoInfo2 = demoInfoService.save(demoInfo);
//不走缓存.
System.out.println(demoInfoService.findById(demoInfo2.getId()));
//走缓存.
System.out.println(demoInfoService.findById(demoInfo2.getId()));
demoInfo = new DemoInfo();
demoInfo.setName("李四");
demoInfo.setPwd("123456");
DemoInfo demoInfo3 = demoInfoService.save(demoInfo);
//不走缓存.
System.out.println(demoInfoService.findById(demoInfo3.getId()));
//走缓存.
System.out.println(demoInfoService.findById(demoInfo3.getId()));
System.out.println("============修改数据=====================");
//修改数据.
DemoInfo updated = new DemoInfo();
updated.setName("李四-updated");
updated.setPwd("123456");
updated.setId(demoInfo3.getId());
try {
System.out.println(demoInfoService.update(updated));
}catch(NotFoundExceptione) {
e.printStackTrace();
}
//不走缓存.
System.out.println(demoInfoService.findById(updated.getId()));
return"ok";
}
}
(10)运行测试;
运行App.java进行测试,访问:http://127.0.0.1:8080/test 进行测试,主要是观察控制台的打印信息。
Hibernate: insert into demo_info(name, pwd, state) values (?, ?, ?)
没有走缓存!52
DemoInfo [id=52, name=张三, pwd=123456,state=0]
DemoInfo [id=52, name=张三, pwd=123456,state=0]
Hibernate: insert into demo_info(name, pwd, state) values (?, ?, ?)
没有走缓存!53
DemoInfo [id=53, name=李四, pwd=123456,state=0]
DemoInfo [id=53, name=李四, pwd=123456,state=0]
============修改数据=====================
DemoInfo [id=53, name=李四-updated,pwd=123456, state=0]
DemoInfo [id=53, name=李四-updated,pwd=123456, state=0]
C:\Users\ADMINI~1.ANG\AppData\Local\Temp\
Hibernate: insert into demo_info(name, pwd, state) values (?, ?, ?)
没有走缓存!54
DemoInfo [id=54, name=张三, pwd=123456,state=0]
DemoInfo [id=54, name=张三, pwd=123456,state=0]
Hibernate: insert into demo_info(name, pwd, state) values (?, ?, ?)
没有走缓存!55
DemoInfo [id=55, name=李四, pwd=123456,state=0]
DemoInfo [id=55, name=李四, pwd=123456,state=0]
============修改数据=====================
DemoInfo [id=55, name=李四-updated,pwd=123456, state=0]
DemoInfo[id=55, name=李四-updated,pwd=123456, state=0]
好了本篇文章就写到这里吧,打烊休息了,实在是动不了!
【Spring Boot 系列视频】
视频&交流平台:
http://study.163.com/course/introduction.htm?courseId=1004329008
http://412887952-qq-com.iteye.com/blog/2321532
网易云课堂视频最新更新:
第十一章 Spring Boot 日志
1、spring boot日志—理论
2、Spring Boot日志-logback
3、Spring Boot日志-log4j2
第十二章 Spring Boot 知识点2
1、spring boot 服务配置和部署
2、Spring Boot 定制URL匹配规则
历史章节:
第一章 快速开始
1、Spring Boot之Hello World
2、Spring Boot之Hello World访问404
第二章 Spring Boot之JSON
1、spring boot返回json数据
2、Spring Boot完美使用FastJson解析JSON数据
第三章 Spring Boot热部署
1、Spring Boot热部署(springloader)
2、springboot + devtools(热部署)
第四章 Spring Boot数据库
1、Spring Boot JPA/Hibernate/Spring Data概念
2、Spring Boot JPA-Hibernate
3、Spring Boot Spring Data JPA介绍
4、Spring Boot JdbcTemplate
5、Spring Boot集成MyBatis
第五章 web开发
1、全局异常捕捉
2、配置server信息
3、spring boot使用thymeleaf
4、Spring Boot 使用freemarker
5、Spring Boot添加JSP支持
第六章 定时任务
1、Spring Boot定时任务
2、Spring Boot 定时任务升级篇(动态修改cron参数)
3、Spring Boot 定时任务升级篇(动态添加修改删除定时任务)
4、Spring Boot 定时任务升级篇(集群/分布式下的定时任务说明)
5、Spring Boot Quartz介绍
6、Spring Boot Quartz在Java Project中使用
7、Spring Boot 集成Quartz普通使用
8、Spring Boot 集成Quartz升级版
9、Spring Boot 集成Quartz二次升级版
10、Spring Boot 集成Quartz-Job如何自动注入Spring容器托管的对象
第七章 Spring Boot MyBatis升级篇
1、Spring Boot MyBatis升级篇-注解
2、Spring Boot MyBatis升级篇-注解-自增ID
3、Spring Boot MyBatis升级篇-注解-增删改查
4、Spring Boot MyBatis升级篇-注解-分页查询
5、Spring Boot MyBatis升级篇-注解-分页PageHelper不生效
6、Spring Boot MyBatis升级篇-注解- mybatic insert异常:BindingException: Parameter 'name' not found
7、Spring Boot MyBatis升级篇-注解- #和$符号特别篇
8、Spring Boot MyBatis升级篇-注解-@Result
9、Spring Boot MyBatis升级篇-注解-动态SQL(if test)-方案一:<script>
10、Spring Boot MyBatis升级篇-注解-动态SQL(if test)-方案二:@Provider
11、Spring Boot MyBatis升级篇-注解-动态SQL-参数问题
12、Spring Boot MyBatis升级篇-注解-特别篇:@MapperScan和@Mapper
13、Spring Boot MyBatis升级篇-XML
14、Spring Boot MyBatis升级篇-XML-自增ID
15、Spring Boot MyBatis升级篇-XML-增删改查
16、Spring Boot MyBatis升级篇-XML-分页查询
17、Spring Boot MyBatis升级篇-XML-分页PageHelper不生效
18、Spring Boot MyBatis升级篇-XML-动态SQL(if test)
19、Spring Boot MyBatis升级篇-XML-注解-初尝试
20、Spring Boot MyBatis升级篇- pagehelper替换为pagehelper-spring-boot-starter
第八章 Spring Boot 知识点1
1、Spring Boot 拦截器HandlerInterceptor
2、Spring Boot启动加载数据CommandLineRunner
3、Spring Boot环境变量读取和属性对象的绑定
4、Spring Boot使用自定义的properties
5、Spring Boot使用自定义的properties
6、Spring Boot使用@SpringBootApplication
7、Spring Boot 监控和管理生产环境
第十章 Spring Boot 打包部署
1、Spring Boot打包部署((提供Linux的sh文件))
第十一章 Spring Boot 日志
1、spring boot日志—理论
2、Spring Boot日志-logback
3、Spring Boot日志-log4j2