为什么需要缓存:
当我们去查询对象的时候,首先到一级缓存去取数据,如果有,则不到数据库中取,如果没有则到数据库中取,同时在一级缓存中放入对象.
缓存的作用主要用来提高性能,可以简单的理解成一个Map;使用缓存涉及到三个操作:把数据放入缓存、从缓存中获取数据、删除缓存中的无效数据。
一级缓存的细节
什么操作会向一级缓存放入数据:
save,update,saveOrUpdate,load,get,list,iterate,lock
save 案例:
//添加一个学生
Student student=new Student();
student.setName("小东");
s.save(student);//放入一级缓存
//我马上查询
Student stu2=(Student) s.get(Student.class, student.getId()); //select
System.out.println("你刚刚加入的学生名字是"+stu2.getName());
什么操作会从一级缓存取数据:
get / load
get / load 会首先从一级缓存中取,如没有.再有不同的操作[get 会立即向数据库发请求,而load 会返回一个代理对象,直到用户真的去使用数据,才会向数据库发请求]
list 会不会从session缓存取数据?
案例:
//查询45号学生
Student stu=(Student) s.get(Student.class, 45);
System.out.println("|||||||||||||||||||");
String hql="from Student where id=45";
Student stu2=(Student) s.createQuery(hql).uniqueResult();
System.out.println(stu2.getName());
从上面的案例,我看出 query.list() query.uniueResut() 不会从一级缓取数据! 但是query.list 或者query.uniqueRestu() 会向一级缓存放数据的.
一级缓存不需要配置,就可以使用,它本身没有保护机制,不能控制缓存的数量,所以要注意大批量操作数据时可能造成内存溢出,所以我们程序员要考虑这个问题,我们可以通过 evict 或者 clear来清除session缓存中对象.
evict 是清除一个对象,clear是清除所有的sesion缓存对象
session级缓存中对象的生命周期, 当session关闭后,就自动销毁.
用HashMap 来模拟一个Session缓存,加深对缓存的深入:
package com.cz.cache; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class MyCache { //使用map来模拟缓存 static Map<Integer,Student> maps=new HashMap<Integer,Student>(); public static void main(String[] args) { // TODO Auto-generated method stub getStudent(1); getStudent(1); getStudent(1); getStudent(4); getStudent(4); } public static Student getStudent(Integer id){ //s.get() //先到缓存去 if(maps.containsKey(id)){ //在缓存有 System.out.println("从缓存取出"); return maps.get(id); }else{ System.out.println("从数据库中取"); //到数据库取 Student stu=MyDB.getStudentFromDB(id); //放入缓存 maps.put(id, stu); return stu; } } } //我的数据库 class MyDB{ static List<Student> lists=new ArrayList<Student>(); //初始化数据库,假设有三个学生 static{ Student s1=new Student(); s1.setId(1); s1.setName("aaa"); Student s2=new Student(); s2.setId(2); s2.setName("bbb"); Student s3=new Student(); s3.setId(3); s3.setName("ccc"); lists.add(s1); lists.add(s2); lists.add(s3); } public static Student getStudentFromDB(Integer id){ for(Student s: lists){ if(s.getId().equals(id)){ return s; } } return null;// 在数据库中没有. } } class Student{ private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
从控制台输出:
从数据库中取
从缓存取出
从缓存取出
从数据库中取
从缓存取出