Dieser Artikel beinhaltet viele technische Punkte: Spring Data JPA, Redis, Spring MVC, Spirng Cache. Wenn Sie diesen Artikel lesen, müssen Sie ein gewisses Verständnis für die oben genannten technischen Punkte haben, sonst können Sie einen Blick darauf werfen Lesen Sie zuerst diesen Artikel und erfahren Sie mehr über die tatsächlichen technischen Punkte im Artikel (beachten Sie, dass Sie den Redis-Server in Ihrer Nähe herunterladen müssen, stellen Sie also sicher, dass Ihr lokaler Redis verfügbar ist. Hier wird auch die MySQL-Datenbank verwendet, natürlich können Sie auch In -Speicherdatenbank zum Testen). In diesem Artikel finden Sie entsprechende Eclipse-Codebeispiele, die grob in die folgenden Schritte unterteilt sind:
(1) Erstellen Sie ein neues Java Maven-Projekt. (2) In pom.xml Fügen Sie entsprechende Abhängigkeitspakete hinzu;
(3) Schreiben Sie die Spring Boot-Startup-Klasse.
(5) Schreiben Sie die RedisCacheConfig-Konfigurationsklasse ;
(7) Schreiben Sie die DemoInfoRepository-Klasse
(9) Schreiben Sie die DemoInfoController-Klasse; (11) Benutzerdefinierter Cache-Schlüssel;
(1) Erstellen Sie ein neues Java Maven-Projekt 🎜>
(2) Fügen Sie das entsprechende Abhängigkeitspaket in pom.xml hinzu;
Fügen Sie das entsprechende Abhängigkeitspaket in Maven hinzu, einschließlich: Spring Boot-Webunterstützung; Unterstützung für den Redis-Datenbankbetrieb; Die Datei lautet wie folgt:
Das Obige ist die vollständige pom.xml-Datei, in der jeweils einfache Anmerkungen erstellt wurden.
(3) Schreiben Sie die Spring Boot-Startup-Klasse (com.kfit.App);
<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>com.kfit</groupId> <artifactId>spring-boot-redis</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring-boot-redis</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- 配置JDK编译版本. --> <java.version>1.8</java.version> </properties> <!-- spring boot 父节点依赖, 引入这个之后相关的引入就不需要添加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> <!-- spring boot 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> <!-- 添加redis支持--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</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> <!-- 单元测试. --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
Der obige Code enthält sehr detaillierte Kommentare, aber hier wird er kurz erwähnt:
RedisCacheConfig muss hier nicht vererbt werden: CachingConfigurerSupport, das heißt, verwenden Sie einfach eine gewöhnliche Klasse Okay ; Die Hauptsache hier ist, dass wir die Schlüsselgenerierungsstrategie später erneut implementieren müssen. Solange der KeyGenerator hier geändert wird, wird er ohne Änderung an anderen Standorten wirksam. Wenn Sie die normale Klassenmethode verwenden, müssen Sie bei Verwendung von @Cacheable auch den Namen des KeyGenerators angeben. Dies ist beim Codieren problematischer.
package com.kfit; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot启动类; * * @author Angel(QQ:412887952) * @version v.0.1 */ @SpringBootApplication public class App { /** * -javaagent:.\lib\springloaded-1.2.4.RELEASE.jar -noverify * @param args */ public static void main(String[] args) { SpringApplication.run(App.class, args); } }
(6) Schreiben Sie eine DemoInfo-Test-Entitätsklasse;
Schreiben Sie eine Test-Entitätsklasse: com.kfit.bean.DemoInfo:
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 ######################################################## ###REDIS (RedisProperties) redis基本配置; ######################################################## # database name spring.redis.database=0 # server host1 spring.redis.host=127.0.0.1 # server password #spring.redis.password= #connection port spring.redis.port=6379 # pool settings ... spring.redis.pool.max-idle=8 spring.redis.pool.min-idle=0 spring.redis.pool.max-active=8 spring.redis.pool.max-wait=-1 # name of Redis server #spring.redis.sentinel.master= # comma-separated list of host:port pairs #spring.redis.sentinel.nodes= ######################################################## ### Java Persistence Api 自动进行建表 ######################################################## # Specify the DBMS spring.jpa.database = MYSQL # Show or not log for each sql query 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 to the entity manager) spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
(7 ) Schreiben Sie die DemoInfoRepository-Persistenzklasse.
DemoInfoRepository wird mit Spirng Data JPA implementiert:
com.kfit.config/RedisCacheConfig: package com.kfit.config; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; /** * redis 缓存配置; * * 注意:RedisCacheConfig这里也可以不用继承:CachingConfigurerSupport,也就是直接一个普通的Class就好了; * * 这里主要我们之后要重新实现 key的生成策略,只要这里修改KeyGenerator,其它位置不用修改就生效了。 * * 普通使用普通类的方式的话,那么在使用@Cacheable的时候还需要指定KeyGenerator的名称;这样编码的时候比较麻烦。 * * @author Angel(QQ:412887952) * @version v.0.1 */ @Configuration @EnableCaching//启用缓存,这个注解很重要; publicclass RedisCacheConfig extends CachingConfigurerSupport { /** * 缓存管理器. * @param redisTemplate * @return */ @Bean public CacheManager cacheManager(RedisTemplate<?,?> redisTemplate) { CacheManager cacheManager = new RedisCacheManager(redisTemplate); returncacheManager; } /** * redis模板操作类,类似于jdbcTemplate的一个类; * * 虽然CacheManager也能获取到Cache对象,但是操作起来没有那么灵活; * * 这里在扩展下:RedisTemplate这个类不见得很好操作,我们可以在进行扩展一个我们 * * 自己的缓存类,比如:RedisStorage类; * * @param factory : 通过Spring进行注入,参数在application.properties进行配置; * @return */ @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>(); redisTemplate.setConnectionFactory(factory); //key序列化方式;(不然会出现乱码;),但是如果方法上有Long等非String类型的话,会报类型转换错误; //所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer //或者JdkSerializationRedisSerializer序列化方式; // RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long类型不可以会出现异常信息; // redisTemplate.setKeySerializer(redisSerializer); // redisTemplate.setHashKeySerializer(redisSerializer); returnredisTemplate; } }
(8) Schreiben Sie die DemoInfoService-Klasse Hier gibt es zwei technische Aspekte. Der erste besteht darin, die Annotation Spring @Cacheable und das RedisTemplate-Objekt zu verwenden. Der spezifische Code lautet wie folgt:
com.kfit.service.DemoInfoService:
(9) Schreiben Sie die Klasse DemoInfoController; /test
Konsole anzeigen Sie können Folgendes anzeigen:
package com.kfit.bean; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; /** * 测试实体类,这个随便; * @author Angel(QQ:412887952) * @version v.0.1 */ @Entity publicclass DemoInfo implements Serializable{ privatestaticfinallongserialVersionUID = 1L; @Id@GeneratedValue privatelongid; private String name; private String pwd; publiclong getId() { returnid; } publicvoid setId(longid) { this.id = id; } public String getName() { returnname; } publicvoid setName(String name) { this.name = name; } public String getPwd() { returnpwd; } publicvoid setPwd(String pwd) { this.pwd = pwd; } @Override public String toString() { return"DemoInfo [id=" + id + ", name=" + name + ", pwd=" + pwd + "]"; } }DemoInfoServiceImpl.findById()========== Aus der Datenbank erhalten....id=1
geladen=DemoInfo [id=1, name=张Three, pwd=123456]
cached=DemoInfo [id=1, name=Zhang San, pwd=123456]DemoInfoServiceImpl.findById()===== ===== Aus der Datenbank bezogen. ...id=2
loaded2=DemoInfo [id=2, name=Zhang San, pwd=123456]com.kfit.repository.DemoInfoRepository: package com.kfit.repository; import org.springframework.data.repository.CrudRepository; import com.kfit.bean.DemoInfo; /** * DemoInfo持久化类 * @author Angel(QQ:412887952) * @version v.0.1 */ publicinterface DemoInfoRepository extends CrudRepository<DemoInfo,Long> { }
Wenn Sie die oben genannten Druckinformationen sehen, dann ist der Cache erfolgreich.
Zugriffsadresse: http://127.0.0.1:8080/test1random1=0.9985031320746356package com.kfit.service; import com.kfit.bean.DemoInfo; /** * demoInfo 服务接口 * @author Angel(QQ:412887952) * @version v.0.1 */ publicinterface DemoInfoService { public DemoInfo findById(longid); publicvoid deleteFromCache(longid); void test(); } com.kfit.service.impl.DemoInfoServiceImpl: package com.kfit.service.impl; import javax.annotation.Resource; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Service; import com.kfit.bean.DemoInfo; import com.kfit.repository.DemoInfoRepository; import com.kfit.service.DemoInfoService; /** * *DemoInfo数据处理类 * * @author Angel(QQ:412887952) * @version v.0.1 */ @Service publicclass DemoInfoServiceImpl implements DemoInfoService { @Resource private DemoInfoRepository demoInfoRepository; @Resource private RedisTemplate<String,String> redisTemplate; @Override publicvoid test(){ ValueOperations<String,String> valueOperations = redisTemplate.opsForValue(); valueOperations.set("mykey4", "random1="+Math.random()); System.out.println(valueOperations.get("mykey4")); } //keyGenerator="myKeyGenerator" @Cacheable(value="demoInfo") //缓存,这里没有指定key. @Override public DemoInfo findById(longid) { System.err.println("DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id="+id); returndemoInfoRepository.findOne(id); } @CacheEvict(value="demoInfo") @Override publicvoid deleteFromCache(longid) { System.out.println("DemoInfoServiceImpl.delete().从缓存中删除."); } }DemoInfoController.test1()
package com.kfit.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.kfit.bean.DemoInfo; import com.kfit.service.DemoInfoService; /** * 测试类. * @author Angel(QQ:412887952) * @version v.0.1 */ @Controller publicclass DemoInfoController { @Autowired DemoInfoService demoInfoService; @RequestMapping("/test") public@ResponseBody String test(){ DemoInfo loaded = demoInfoService.findById(1); System.out.println("loaded="+loaded); DemoInfo cached = demoInfoService.findById(1); System.out.println("cached="+cached); loaded = demoInfoService.findById(2); System.out.println("loaded2="+loaded); return"ok"; } @RequestMapping("/delete") public@ResponseBody String delete(longid){ demoInfoService.deleteFromCache(id); return"ok"; } @RequestMapping("/test1") public@ResponseBody String test1(){ demoInfoService.test(); System.out.println("DemoInfoController.test1()"); return"ok"; } }Zwei Besuche: 127.0.0.1:8080/test
cached=DemoInfo [id=1, name=Zhang Three , pwd=123456]
loaded2=DemoInfo [id=2, name=Zhang San, pwd=123456]Zu diesem Zeitpunkt werden alle Daten zwischengespeichert.
Führen Sie zu diesem Zeitpunkt die Löschaktion aus: http://127.0.0.1:8080/delete?id=1
DemoInfoServiceImpl.findById()========== Aus der Datenbank erhalten....id=1
cached=DemoInfo [id=1, name=张三, pwd=123456]
loaded2=DemoInfo [id=2, name=张三, pwd=123456]
(11) Benutzerdefinierter Cache-Schlüssel;
在com.kfit.config.RedisCacheConfig类中重写CachingConfigurerSupport中的keyGenerator ,具体实现代码如下:
/** * 自定义key. * 此方法将会根据类名+方法名+所有参数的值生成唯一的一个key,即使@Cacheable中的value属性一样,key也会不一样。 */ @Override public KeyGenerator keyGenerator() { System.out.println("RedisCacheConfig.keyGenerator()"); returnnew KeyGenerator() { @Override public Object generate(Object o, Method method, Object... objects) { // This will generate a unique key of the class name, the method name //and all method parameters appended. StringBuilder sb = new StringBuilder(); sb.append(o.getClass().getName()); sb.append(method.getName()); for (Object obj : objects) { sb.append(obj.toString()); } System.out.println("keyGenerator=" + sb.toString()); returnsb.toString(); } }; }
这时候在redis的客户端查看key的话还是序列化的肉眼看到就是乱码了,那么我改变key的序列方式,这个很简单,redis底层已经有具体的实现类了,我们只需要配置下:
//key序列化方式;(不然会出现乱码;),但是如果方法上有Long等非String类型的话,会报类型转换错误; //所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer //或者JdkSerializationRedisSerializer序列化方式; RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long类型不可以会出现异常信息; redisTemplate.setKeySerializer(redisSerializer); redisTemplate.setHashKeySerializer(redisSerializer);
综上以上分析:RedisCacheConfig类的方法调整为:
package com.kfit.config; import java.lang.reflect.Method; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; /** * redis 缓存配置; * * 注意:RedisCacheConfig这里也可以不用继承:CachingConfigurerSupport,也就是直接一个普通的Class就好了; * * 这里主要我们之后要重新实现 key的生成策略,只要这里修改KeyGenerator,其它位置不用修改就生效了。 * * 普通使用普通类的方式的话,那么在使用@Cacheable的时候还需要指定KeyGenerator的名称;这样编码的时候比较麻烦。 * * @author Angel(QQ:412887952) * @version v.0.1 */ @Configuration @EnableCaching//启用缓存,这个注解很重要; publicclass RedisCacheConfig extends CachingConfigurerSupport { /** * 缓存管理器. * @param redisTemplate * @return */ @Bean public CacheManager cacheManager(RedisTemplate<?,?> redisTemplate) { CacheManager cacheManager = new RedisCacheManager(redisTemplate); returncacheManager; } /** * RedisTemplate缓存操作类,类似于jdbcTemplate的一个类; * * 虽然CacheManager也能获取到Cache对象,但是操作起来没有那么灵活; * * 这里在扩展下:RedisTemplate这个类不见得很好操作,我们可以在进行扩展一个我们 * * 自己的缓存类,比如:RedisStorage类; * * @param factory : 通过Spring进行注入,参数在application.properties进行配置; * @return */ @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>(); redisTemplate.setConnectionFactory(factory); //key序列化方式;(不然会出现乱码;),但是如果方法上有Long等非String类型的话,会报类型转换错误; //所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer //或者JdkSerializationRedisSerializer序列化方式; RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long类型不可以会出现异常信息; redisTemplate.setKeySerializer(redisSerializer); redisTemplate.setHashKeySerializer(redisSerializer); returnredisTemplate; } /** * 自定义key. * 此方法将会根据类名+方法名+所有参数的值生成唯一的一个key,即使@Cacheable中的value属性一样,key也会不一样。 */ @Override public KeyGenerator keyGenerator() { System.out.println("RedisCacheConfig.keyGenerator()"); returnnew KeyGenerator() { @Override public Object generate(Object o, Method method, Object... objects) { // This will generate a unique key of the class name, the method name //and all method parameters appended. StringBuilder sb = new StringBuilder(); sb.append(o.getClass().getName()); sb.append(method.getName()); for (Object obj : objects) { sb.append(obj.toString()); } System.out.println("keyGenerator=" + sb.toString()); returnsb.toString(); } }; } }
这时候在访问地址:127.0.0.1:8080/test
这时候看到的Key就是:com.kfit.service.impl.DemoInfoServiceImplfindById1
在控制台打印信息是:
(1)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById1
(2)DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id=1
(3)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById1
(4)loaded=DemoInfo [id=1, name=张三, pwd=123456]
(5)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById1
(6)cached=DemoInfo [id=1, name=张三, pwd=123456]
(7)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById2
(8)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById2
(10)DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id=2
(11)loaded2=DemoInfo [id=2, name=张三, pwd=123456]
其中@Cacheable,@CacheEvict下节进行简单的介绍,这节的东西实在是太多了,到这里就打住吧,剩下的就需要靠你们自己进行扩展了。
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung von Beispielen für die Integration von Redis durch Spring Boot zur Implementierung des Caching-Mechanismus. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!