一、说明
- 1.针对于读多写少的情况
- 2.先查缓存,没有再去查库
二、代码示例
2.1 pom依赖
<?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>com.learning</groupId><artifactId>jdbc</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.21</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.26</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.16</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.26</version></dependency></dependencies>
</project>
2.2 示例代码
package com.learning;import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.cache.CacheKey;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;public class DataCache {private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();private Map<CacheKey, Object> map = new HashMap<>();private static DruidDataSource druidDataSource = new DruidDataSource();private static JdbcTemplate jdbcTemplate;static {druidDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true");druidDataSource.setUsername("root");druidDataSource.setPassword("root");jdbcTemplate = new JdbcTemplate(druidDataSource);}public <T> T queryOne(Class<T> beanClass, String sql, Object... args){// 从缓存中查找,找到则直接返回CacheKey key = new CacheKey(new Object[]{sql, args});reentrantReadWriteLock.readLock().lock();try{T value = (T)map.get(key);if(value != null){return value;}}finally{reentrantReadWriteLock.readLock().unlock();}reentrantReadWriteLock.writeLock().lock();try{// 多个线程,再获取一遍,检查一下,是否有线程写入成功了T value = (T) map.get(key);if(value == null){// 缓存中没有,查询数据库value = queryDatabase(beanClass, sql, args);map.put(key, value);}return value;}finally {reentrantReadWriteLock.writeLock().unlock();}}private <T> T queryDatabase(Class<T> beanClass, String sql, Object[] args) {BeanPropertyRowMapper beanPropertyRowMapper = new BeanPropertyRowMapper<T>();beanPropertyRowMapper.setMappedClass(beanClass);System.out.println("sql:"+sql);List<T> list = jdbcTemplate.query(sql, args, beanPropertyRowMapper);return list.get(0);}public static void main(String[] args) {DataCache dataCache = new DataCache();String sql = "select * from student where id = ?";Object[] param = new Object[]{1};for (int i = 0; i < 10; i++) {new Thread(()->{Student student = dataCache.queryOne(Student.class, sql, param);System.out.println(student);;}).start();}}
}
2.3 实体类
package com.learning;import lombok.Data;@Data
public class Student {private String id;private String name;private int age;
}
三、示例截图