缓存框架(Java缓存)与框架缓存(介绍mybatis缓存)

Java缓存主要分为三种:java

一、FIFOsql

二、LRU数据库

三、LFUapache

它们通常应用于浏览器中,使不少操做更加方便快捷。浏览器

一、FIFO:缓存

FIFO是按存入的顺序进行排序的,若是命中缓存中的任意一个数据,也不会破坏先进先出的规则。若是新增了一个缓存以外的数据,会把最早存入的数据移除。 先入先出,就和队列同样,先进队列的先出队列。bash

import java.util.LinkedHashMap;

public class FIFOCache<K,V> extends LinkedHashMap<K, V> {
    private static final long serialVersionUID = 436014030358073695L;
    private final int SIZE;
    public FIFOCache(int size) {
    super();
    SIZE = size;
    }
    @Override
    protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
    return size() > SIZE;
    }
}

public class FIFOCacheTest {
    public static void main(String[] args) {
    FIFOCache<Integer, Integer> map = new FIFOCache<Integer, Integer>(10);
    for (int i = 0; i++ < 10;) {
   map.put(i, i);
    }
    System.out.println("起始存储状况:"+map.toString());
    map.put(8, 8);
    System.out.println("命中一个已存在的数据:"+map.toString());
    map.put(11, 11);
   System.out.println("新增一个数据后:"+map.toString());
    }
}
复制代码

二、LRU: 当某一个数据被访问命中就会按照LRU规则放到队列最前面。若是新增一个不存在缓存的数据,会把该数据放到最前面,同时移除最先访问过的数据。session

import java.util.LinkedHashMap;

public class LRUCache<K,V> extends LinkedHashMap<K, V> {

    private static final long serialVersionUID = 5853563362972200456L;
    private final int SIZE;
    public LRUCache(int size) {
    
   super(size, 0.75f, true); 
   
    SIZE = size;
    }
    @Override
    protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
    return size() > SIZE;
    }
}
public class LRUCacheTest {
    public static void main(String[] args) {
    LRUCache<Integer, Integer> map = new LRUCache<Integer, Integer>(10);
    for (int i = 0; i++ < 10; ) {
    map.put(i, i); 
    }
    System.out.println("起始存储状况:"+map.toString());
    map.get(7);
  System.out.println("命中一个已存在的数据:"+map.toString());
    map.put(8, 8+1);  
    System.out.println("覆盖一个已存在的数据:"+map.toString());
    map.put(11, 11); 
    System.out.println("新增一个数据后:"+map.toString());
   }
}
复制代码

三、LFU: 对存储的数据都会有一个计数引用,而后队列按数据引用次数排序,引用数多的排在最前面,引用数少的排在后面。若是这个时候有新的数据进来,把最后面的数据删除,把新进数据排在最后面,且引用次数为1mybatis

import java.util.*;
public class LFUCache{
    static class Value implements Comparable<Value>{    
   Object key;
    Object val;
    int hitCount;
   public Value(Object v, Object key) {
    this.key = key;
    this.val = v;
    this.hitCount = 1; 
    }
    public void setVal(Object obj){
    this.val = obj;
    }
   public void countInc(){
  hitCount++;
    }
    @Override
    public int compareTo(Value o) {
    if(o instanceof Value){  
    Value v = (Value) o;
    if(this.hitCount > v.hitCount)
    return 1;
    else
    return -1;
    }
  return 0;
    }
    }
    final int SIZE;
    private Map<Object, Value> map = new HashMap<Object, Value>();
    public LFUCache(int size) {
   SIZE = size;
    }
    public Object get(Object k){
    if(k == null)
    return null;
   map.get(k).countInc();
   return map.get(k).val;
    }
    public void put(Object k, Object v){
   if(map.get(k) != null){
    map.get(k).countInc();
   map.get(k).setVal(v);
    }else{
   if(map.size() >= SIZE){
  remove();
    }
    Value value  = new Value(v, k);
    map.put(k, value);
    }
    }
    public void remove(){
    Value v = Collections.min(map.values());
    map.remove(v.key);
    }
    public String showList(){
   List<Value> list = new ArrayList<Value>();
    list.addAll(map.values());
    Collections.sort(list);
    String result = "";
    for (Value value : list) {
    result +=value.key+"="+value.val+" ";
    }
   return result;
    }
}

public class LFUCacheTest {
    public static void main(String[] args) {
   LFUCache map = new LFUCache(10);
    for (int i = 0; i++ < 10; ) {
    map.put(i, i);
    }
    System.out.println("起始存储状况:"+map.showList());
   map.get(7);
   System.out.println("命中一个已存在的数据:"+map.showList());
    map.put(8, 8+1);  
   System.out.println("覆盖一个已存在的数据:"+map.showList());
    map.put(11, 11); 
   System.out.println("新增一个数据后:"+map.showList());
    map.put(5, 5); 
    map.put(5, 5);
    map.put(6, 6); 
    map.put(6, 6);
    map.put(6, 6);
    System.out.println("修改命中次数后:"+map.showList());
    }
}
复制代码

mybatis的缓存能够分为一级和二级缓存。app

其中一级缓存也叫本地缓存;当你要在一段时间内获取相同的数据时,若是每次都去查询数据库,就会显得特别麻烦,这时候一级缓存就派上了用场,它可以将与数据库会话时查询到的数据放在本地的缓存中,这时候要相同数据就能够直接从缓存中获取,就省去不少麻烦。

二级缓存也叫做全局缓存。一个命名域对应一个二级缓存,发生一个会话的时候查询数据中的数据,这个数据就会被保留在当前的一级缓存中。当会话关闭的时候一级缓存的数据就会被保存在二级缓存中;开始新会话的时候,若是要查询新的信息就能够用二级缓存中的内容。

//截取的一部分实现代码

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import com.atguigu.mybatis.bean.Department;
import com.atguigu.mybatis.bean.Employee;
import com.atguigu.mybatis.dao.DepartmentMapper;
import com.atguigu.mybatis.dao.EmployeeMapper;
import com.atguigu.mybatis.dao.EmployeeMapperAnnotation;
import com.atguigu.mybatis.dao.EmployeeMapperDynamicSQL;
import com.atguigu.mybatis.dao.EmployeeMapperPlus;

public class MyBatisTest {
	

	public SqlSessionFactory getSqlSessionFactory() throws IOException {
	String resource = "mybatis-config.xml";
	InputStream inputStream = Resources.getResourceAsStream(resource);
	return new SqlSessionFactoryBuilder().build(inputStream);
	}
@Test
public void testFirstLevelCache() throws IOException{
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
	try{
	EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
	Employee emp01 = mapper.getEmpById(1);
	System.out.println(emp01);
	}finally{
	openSession.close();
	}
	}
	
	@Test
public void testSecondLevelCache() throws IOException{
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
SqlSession openSession2 = sqlSessionFactory.openSession();
	try{
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
	EmployeeMapper mapper2 = openSession2.getMapper(EmployeeMapper.class);
	
	Employee emp01 = mapper.getEmpById(1);
	System.out.println(emp01);
	
	openSession.close();
	Employee emp02 = mapper2.getEmpById(1);//从二级缓存中拿的数据
	System.out.println(emp02);
	openSession2.close();
	
	}finally{
	
	}
	}
	
}
复制代码
相关文章
相关标签/搜索