1.session.clear()
注意session.clear()的运用,尤其在不断分页循环的时候
a.比如:在一个大集合中进行遍历,遍历msg,取出其中的含有敏感字样的对象
如果每次翻页都产生一个session,那之前的session就被清除了
(实际上由java虚拟机的GC帮忙清除),不会产生问题;
但如果一直在同一个session里不断读取,之前的数据因为存在引用,GC不会清除,
那么会产生内存溢出。
一般分页每个页面单独产生一个session,但如果是导数据和处理数据就会有这个问题。
b.另外一种形式的内存泄露
//面试题:java有内存泄露吗?
语法级别上没有,实际上运用的时候会产生。
因为不用回收内存,GC会自动回收。但如果用到了某些资源,一定要注意回收,
比如打开了连接池的连接要记得关闭;比如打开了文件要记得关闭,
否则就不能调用本地的资源把文件关闭,打开文件相当于调了C,C调了windows的API,
C需要手动回收内存,那么就会产生java内存泄露。
2.1+N问题//典型面试题
问题描述:
public void testSave(){//类设计参考17hibernate
Session session = sf.openSession();
session.beginTransaction();
for(int i=0;i<10;i++){
Category c = new Category();
c.setName("c"+i);
Topic t = new Topic();
t.setCategory(c);
t.setTitle("t"+i);
t.setCreateDate(new Date());
session.save(c);
session.save(t);
}
session.getTransaction().commit();
session.close();
}
public void testQuery1(){
Session session = sf.openSession();
session.beginTransaction();
List<Topic> topics =
(List<Topic>)session.createQuery("from Topic").list();
for(Topic t:topics){
System.out.println(t.getId()+"-"+t.getTitle());
}
session.getTransaction().commit();
session.close();
}
//1+N问题阐述(OneToMany或ManyToOne):
Topic对Category是ManyToOne,fetchType设为eager时
查询Topic时,查询语句如下:
一条语句查询出所有符合条件的Topic,
同时被关联的对象Category被取出的时候又发出N条sql语句
所以一共是:一条语句查询Topic + N条语句查询Category
解决方案:
a.Lazy//此时N条语句在使用的时候才发出
b.BatchSize//不是正规的解决方法,因为其他关联Category的类也会被限制
在Category类上加注解 @BatchSize(size=5),
即加载Category类的时候一次最多加载5条,
此时发出的sql语句是N/5(N%5=0)或N/5+1(N%5!=0)条
c.join fetch//Criteria默认使用join fetch,本质是外连接,只发出一条sql语句
List<Topic> topics =
(List<Topic>)session.createQuery("from Topic t left join fetch t.category c").list();
3.Query的list方法和iterate方法不同之处
public void testQueryList(){
Session session = sf.openSession();
session.beginTransaction();
List<Topic> topics =
(List<Topic>)session.createQuery("from Topic").list();
for(Topic t:topics){
System.out.println(t.getTitle());
}
session.getTransaction().commit();
session.close();
}
public void testQueryIterate(){
Session session = sf.openSession();
session.beginTransaction();
Iterator<Topic> topics =
(Iterator<Topic>)session.createQuery("from Topic").iterate();
//此处返回List<Topic>也可以,因为List实现了Iterator接口
while(topics.hasNext()){
t = topics.next();
System.out.println(t.getTitle());
}
session.getTransaction().commit();
session.close();
}
a.list取所有
b.iterate先取ID,等用到的时候再根据ID来取对象
c.session中list第二次发出,仍会到数据库查询
d.iterate第二次,首先找session缓存
18hibernate hibernate的性能优化之session.clear()、1+N问题、list和iterate的区别
最新推荐文章于 2016-11-25 12:42:30 发布