Terdapat keperluan untuk menanyakan produk menggunakan nama produk Ia diperlukan untuk menanyakan cache terlebih dahulu, dan jika ia tidak ditemui, pergi ke pangkalan data untuk membuat pertanyaan selepas bertanya daripada pangkalan data, tambahkannya pada cache, dan teruskan pertanyaan semula.
Anda boleh menulis penghakiman bersyarat Kod pseudo adalah seperti berikut:
//先从缓存中查询 String goodsInfoStr = redis.get(goodsName); if(StringUtils.isBlank(goodsInfoStr)){ //如果缓存中查询为空,则去数据库中查询 Goods goods = goodsMapper.queryByName(goodsName); //将查询到的数据存入缓存 goodsName.set(goodsName,JSONObject.toJSONString(goods)); //返回商品数据 return goods; }else{ //将查询到的str转换为对象并返回 return JSON.parseObject(goodsInfoStr, Goods.class); }
Rentetan kod di atas boleh. juga mencapai kesan pertanyaan Ia tidak kelihatan sangat rumit, tetapi rentetan kod ini adalah 不可复用的
dan hanya boleh digunakan dalam senario ini. Dengan mengandaikan bahawa terdapat banyak keperluan yang serupa dengan pertanyaan produk di atas dalam sistem kami, maka kami perlu menulis if(...)else{...}
sedemikian di mana-mana sahaja. Sebagai pengaturcara, adalah sangat tidak selesa untuk tidak dapat menyatukan kod yang serupa atau berulang, jadi kod untuk senario ini perlu dioptimumkan.
Masalah dengan kod di atas ialah: Parameter input tidak tetap dan nilai pulangan juga tidak tetap Jika hanya parameter tidak tetap, gunakan generik. Tetapi perkara yang paling penting ialah kaedah pertanyaan tidak tetap Sebagai contoh, pertanyaan produk dan pengguna pertanyaan pastinya bukan kaedah pertanyaan yang sama.
Jadi adalah bagus jika kita boleh lulus kaedah (iaitu pelbagai kaedah pertanyaan di atas) sebagai parameter ke dalam kaedah penghakiman bersatu, serupa dengan:
/** * 这个方法的作用是:先执行method1方法,如果method1查询或执行不成功,再执行method2方法 */ public static<T> T selectCacheByTemplate(method1,method2)
ingin Untuk mencapai kesan di atas , kita perlu menyebut ciri baharu Java8: 函数式编程
Terdapat pakej dalam Java: java.util.function
, kesemuanya adalah antara muka , dan semuanya diubah suai oleh @FunctionalInterface
anotasi.
Kategori Fungsi
Pengguna (Penggunaan): Terima parameter, tiada nilai pulangan
Fungsi (fungsi): menerima parameter dan mengembalikan nilai
Operator (operasi): menerima parameter dan mengembalikan jenis yang sama seperti parameter Nilai
Predikat (penegasan): menerima parameter dan mengembalikan jenis boolean
Pembekal (Pembekalan): Tiada parameter, nilai pulangan
Saya tidak akan menerangkan secara terperinci Anda boleh merujuk kepada: Ringkasan Pengaturcaraan Fungsian Java
Kemudian mari kita gunakan Java untuk menanya cache secara elegan dahulu dan kemudian pangkalan data!
pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.2</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>SpringBoot-query</artifactId> <version>0.0.1-SNAPSHOT</version> <name>SpringBoot-query</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.83</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
<>< . > CacheSelector.java
Antara muka berfungsi tersuai:
package com.example.springbootquery; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootQueryApplication { public static void main(String[] args) { SpringApplication.run(SpringBootQueryApplication.class, args); } }
package com.example.springbootquery.entity; public class Goods { private String goodsName; private Integer goodsTotal; private Double price; public String getGoodsName() { return goodsName; } public void setGoodsName(String goodsName) { this.goodsName = goodsName; } public Integer getGoodsTotal() { return goodsTotal; } public void setGoodsTotal(Integer goodsTotal) { this.goodsTotal = goodsTotal; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } @Override public String toString() { return "Goods{" + "goodsName='" + goodsName + '\'' + ", goodsTotal='" + goodsTotal + '\'' + ", price=" + price + '}'; } }
package com.example.springbootquery.function; @FunctionalInterface public interface CacheSelector<T> { T select() throws Exception; }
package com.example.springbootquery.service; import com.example.springbootquery.entity.Goods; public interface CacheService { /** * 从缓存中获取商品 * * @param goodsName 商品名称 * @return goods */ Goods getGoodsByName(String goodsName) throws Exception; }
package com.example.springbootquery.service.impl; import com.alibaba.fastjson.JSON; import com.example.springbootquery.entity.Goods; import com.example.springbootquery.service.CacheService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; @Service("cacheService") public class CacheServiceImpl implements CacheService { @Autowired private StringRedisTemplate redisTemplate; @Override public Goods getGoodsByName(String goodsName) throws Exception { String s = redisTemplate.opsForValue().get(goodsName); return null == s ? null : JSON.parseObject(s, Goods.class); } }
package com.example.springbootquery.service; import com.example.springbootquery.entity.Goods; public interface GoodsService { Goods getGoodsByName(String goodsName); }Salin selepas log masukPenggunaan
Pertanyaan daripada data untuk kali pertamapackage com.example.springbootquery.service.impl; import com.alibaba.fastjson.JSONObject; import com.example.springbootquery.entity.Goods; import com.example.springbootquery.service.GoodsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; @Service public class GoodsServiceImpl implements GoodsService { @Autowired private StringRedisTemplate stringRedisTemplate; @Override public Goods getGoodsByName(String goodsName) { Goods goods = new Goods(); goods.setGoodsName("商品名1"); goods.setGoodsTotal(20); goods.setPrice(30.0D); stringRedisTemplate.opsForValue().set(goodsName, JSONObject.toJSONString(goods)); return goods; } }Salin selepas log masukPertanyaan daripada cache untuk kali keduaAtas ialah kandungan terperinci Cara menggunakan Java untuk menanya cache dahulu dan kemudian menanya pangkalan data. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!