hibernate 一級(jí)緩存:(緩存的是實(shí)體對(duì)象)
一級(jí)緩存很短和session的生命周期一致,一級(jí)緩存也叫session級(jí)的緩存或事務(wù)緩存
哪些方法支持一級(jí)緩存:
*get()
*load()
*iterate() (查詢實(shí)體對(duì)象)
如何管理一級(jí)緩存:
* session.clear() session.evict()
如何避免一次性大量的實(shí)體數(shù)據(jù)入庫導(dǎo)致內(nèi)存溢出
*先flush,再clear
如果數(shù)據(jù)量特別大,考慮采用jdbc實(shí)現(xiàn),如果jdbc也不能滿足要求,可以考慮采用數(shù)據(jù)庫本身的特定導(dǎo)入工具
一.Load測試: 在同一個(gè)session中發(fā)出兩次load查詢
Student sutdent = (Student)session.load(Student.class,1);
System.out.println(student.getName());
sutdent = (Student)session.load(Student.class,1);
System.out.println(student.getName());
在同一個(gè)session中發(fā)出兩次load查詢,第一次load的時(shí)候不會(huì)去查詢數(shù)據(jù)庫,因?yàn)樗荓AZY的,當(dāng)使用的時(shí)候才去查詢數(shù)據(jù)庫, 第二次load的時(shí)候也不會(huì),當(dāng)使用的時(shí)候也不會(huì)查詢數(shù)據(jù)庫,因?yàn)樗诰彺胬镎业剑粫?huì)發(fā)出sql
Load測試: 開啟兩個(gè)session中發(fā)出兩次load查詢
Student sutdent = (Student)session.load(Student.class,1);
System.out.println(student.getName());
sessioin.close();
………..
sutdent = (Student)session.load(Student.class,1);
System.out.println(student.getName());
開啟兩個(gè)session中發(fā)出兩次load查詢,第一次load的時(shí)候不會(huì)去查詢數(shù)據(jù)庫,因?yàn)樗荓AZY的,當(dāng)使用的時(shí)候才去查詢數(shù)據(jù)庫, 第二次load的時(shí)候也不會(huì),當(dāng)使用的時(shí)候查詢數(shù)據(jù)庫,因?yàn)閟ession間不能共享一級(jí)緩存的數(shù)據(jù),因?yàn)樗麜?huì)隨session的生命周期存在和消亡
二.Get測試: 在同一個(gè)session中發(fā)出兩次get查詢
Student sutdent = (Student)session.get(Student.class,1);
System.out.println(student.getName());
sutdent = (Student)session.get(Student.class,1);
System.out.println(student.getName());
在同一個(gè)session中發(fā)出兩次get查詢, 第一次get的時(shí)候去查詢數(shù)據(jù)庫,第二次get的時(shí)候不會(huì)查詢數(shù)據(jù)庫,因?yàn)樗诰彺胬镎业剑粫?huì)發(fā)出sql
三.iterate測試: 在同一個(gè)session中發(fā)出兩次iterator查詢
Student student = (Student)session.createQuery(“from Student s where s.id=1”).iterate().next();
System.out.println(student.getName());
student = (Student)session.createQuery(“from Student s where s.id=1”).iterate().next();
System.out.println(student.getName());
在同一個(gè)session中發(fā)出兩次iterator查詢,第一次iterate().next()的時(shí)候會(huì)發(fā)出查詢id的sql,使用的時(shí)候會(huì)發(fā)出相應(yīng)的查詢實(shí)體對(duì)象,第二次iterate().next()的時(shí)候會(huì)發(fā)出查詢id的sql,不會(huì)發(fā)出查詢實(shí)體對(duì)象的sql,因?yàn)閕terate使用緩存,不會(huì)發(fā)出sql
四.Iterate查詢屬性測試: 同一個(gè)session中發(fā)出兩次查詢屬性
String name = (String)session.createQuery(“select s.name from Student s where s.id=1”).iterate().next();
System.out.println(name);
String name = (String)session.createQuery(“select s.name from Student s where s.id=1”).iterate().next();
System.out.println(name);
在同一個(gè)session中發(fā)出兩次查詢屬性, 第一次iterate().next()的時(shí)候會(huì)發(fā)出查詢屬性的sql,第二次iterate().next()的時(shí)候會(huì)發(fā)出查詢屬性的sql,iterate查詢普通屬性,一級(jí)緩存不會(huì)緩存,所以會(huì)發(fā)出sql
五.同一個(gè)session中先save,再發(fā)出load查詢save過的數(shù)據(jù)
Student stu = new Student();
stu.setName(“王五”);
Serializable id = session.save(stu);
Student sutdent = (Student)session.load(Student.class,id);
System.out.println(student.getName());
save的時(shí)候,他會(huì)在緩存里放一份,不會(huì)發(fā)出sql,因?yàn)閟ave是使用緩存的
六.同一個(gè)session中先調(diào)用load查詢,然后執(zhí)行sessio.clear()或session.evict(),再調(diào)用load查詢
Student sutdent = (Student)session.load(Student.class,1);
System.out.println(student.getName());
session.clear();
Student sutdent = (Student)session.load(Student.class,1);
System.out.println(student.getName());
sessio.clear()或session.evict()可以管理一級(jí)緩存,一級(jí)緩存無法取消,但可以管理.
上面的語句都會(huì)發(fā)出sql 因?yàn)橐患?jí)緩存中的實(shí)體被清除了
七.向數(shù)據(jù)庫中批量加入1000條數(shù)據(jù)
for(int i=0;i<1000;i++){
Student student = new Student();
student.setName(“s” + i);
session.save(student);
//每20條數(shù)據(jù)就強(qiáng)制session將數(shù)據(jù)持久化,同時(shí)清除緩存,避免大量數(shù)據(jù)造成內(nèi)存溢出
if( i %20 == 0 ){
session.flush();
session.clear();
}
}