緩存框架(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{
	
	}
	}
	
}
複製代碼
相關文章
相關標籤/搜索