但可以这样用:List不会使用换成,只往一级缓存里放
List students=session.createQuery(“select id,name from student”).list();
Iterator iter=session.createQuery(“from student”).iterator() while(iter.hasNest()){
Student student=(Student)iter.next();
System.out.println(student.getId()+”,”+student.getName());
}
总结List和iterate区别
l list每次都会发出sql语句,list会向缓存中放入数据,不利于利用缓存中的数据
l Iterator:默认情况下利用缓存中的数据,但如果缓存中不存在数据有可能出现N+1问题
条件查询:
拼字符串:
Iterator iter=session.createQuery(“from student a where a.name like ‘%1%’”).iterator() while(iter.hasNest()){
Student student=(Student)iter.next();
System.out.println(student.getId()+”,”+student.getName());
}
Query query=session.createQuery(“select s.id, s.name from Student s where s.name like=?”);
Query.setParameter(0,”%1%”);
List students = query.list();
可以用方法链编程:
List students =session.createQuery(“select s.id, s.name from Student s where s.name like=?”).setParameter(0,”%1%”).list();
命名的重构方式:
List students =session.createQuery(“select s.id, s.name from Student s where s.name :myname”).setParameter(myname,”%1%”).list();
List students =session.createQuery(“select s.id, s.name from Student s where s.name :myname and s.id=myid”).setParameter(myname,”%1%”).setParameter(myid,1).list();
//支持in
List students =session.createQuery(“select s.id, s.name from Student s where s.id in(:myids)”).setParameterList(“myids”,new Object[]{1,2,3,4,5}).list();
//取年月
List students =session.createQuery(“select s.id, s.name from Student s where date_format(s.createTime,’%Y-%m’)=?”)
.setParameter(0,”2008-02”).list();
//取between
SimpleDateFormat sdf=new SimpleDateFormat(‘yyyy-MM-dd HH:mm:ss’);
List students =session.createQuery(“select s.id, s.name from Student s where c.createTime between ? and ?”)
.setParameter(0,sdf.parse(“2008-01-10 00:00:00”)) .setParameter(0,sdf.parse(“2008-02-15 23:59:59”)).list();
支持sql查询
List students=session.createSQLQuery(“select * from t_student”).list();
外置命名查询
在任何映射xml文件中如:hbm.xml在用<query>
</class>
<query name="searchStudent">
<![CDATA[
select s from Student s where s.id<?
]]>
</query>
使用:
List list=session.getNamedQuery("searchStudent")
.setParameter(0, 10)
.list();
查询过滤器
在类中使用过滤器
<filter name="filtertest" condition="id < ;:myid"/>
</class>
定义过滤器
<filter-def name="filtertest">
<filter-param name="myid" type="integer"/>
</filter-def>
在类中使用过滤器
session.enableFilter("filtertest")
.setParameter("myid", 10);
List list=session.createQuery("from java.lang.Object")
.list();
分页查询
List list=session.createQuery("from java.lang.Object")
.setFirstResult(0)从0开始
.setMaxResults(10)每页显示多少
.list();
导航查询
List students =session.createQuery(“select s.id, s.name from Student s where s.class.name like=?”).setParameter(0,”%1%”).list();
连接查询
内连默认、、
List students =session.createQuery(“select s.name, c.name from Student s join s.class c”).list();
左连接
List students =session.createQuery(“select s.name, c.name from Class c left join c.student s”).list();
右连接
List students =session.createQuery(“select s.name, c.name from Class c right join c.student s”).list();
统计查询
List students =session.createQuery(“select count(*) from Class”).list();
Long count=(Long)students.get(0);
另一种
Long count =(Long)session.createQuery(“select count(*) from Class”).uniqueResult;
List students =session.createQuery(“select s.name, count(c) from Student s join s.class c group by c.name orderby c.name”).list();
For(Iterator iter=students.iterator();iter.hasNext();){
Object[] obj=(Object[])iter.next();
System.out.println(obj[0]+”,”+obj[1]);
}
DML风格的操作,尽量少用,因为和缓存不同步,给hibernate增加压力
?站位符
session.createQuery(“update Student s set s.name=? where s.id<? ”)
.setParameter(0,”李四”)
.setParameter(1,5)
.executeUpdate();
NRU=最近不使用
FIFO-先进先出
LRU-最近最少使用
一级缓存和session生命周期一至,一级缓存也叫session或事务级缓存
同一session中
一级缓存是缓存实体对项不缓存普通属性
不同缓存,不同Session间不能共享缓存
Serializable id=session.save(stu);返回id
Student student =(Student)session.load(Student.class,id);使用缓存
Session。Clear()清楚全部
而session。Evict()制定清除
一级缓存无法取消,但可以管理
大批量更行用hibernate会导致内存溢出
批量更新
For(int i=0;i<1000;i++){
Student student=new Student();
Student.setName(“name”+i);
Session.save(student);
避免大量数据造成内存溢出
If(i%20==0){
Session.flush();
Session.clear();
}
}
数据库量特别大用jdbc实现,如果还不行,就采用数据库本身的特定的导入工具
hibernate二级缓存
二级缓存也称进程级的缓存或SessionFactory级的缓存,二级缓存可以被所有的session共享
二级缓存的生命周期和SessionFactory的生命周期一致,SessionFactory可以管理二级缓存
二级缓存是缓存实体对象的
二级缓存的配置和使用:
* 将echcache.xml文件拷贝到src下
* 开启二级缓存,修改hibernate.cfg.xml文件
默认开启的
<property name="hibernate.cache.use_second_level_cache">true</property>
* 指定缓存产品提供商,修改hibernate.cfg.xml文件
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
* 指定那些实体类使用二级缓存(两种方法)
* 在映射文件hbm中采用<cache>标签
<cache usage=”read-only>”
l 在hibernate.cfg.xml文件中,采用<class-cache>标签,推荐使用
l <class-cache class=”com.gxcme.student” usage=”read-only”/>
public void TestLoad1() {
Session session=null;
Transaction tran=null;
try {
session=HibernateSessionFactory.getSession();
tran=session.beginTransaction();
Bird bird=(Bird)session.load(Bird.class, 1);
System.out.println("bird.name:"+bird.getName());
tran.commit();
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
tran.rollback();
}finally{
HibernateSessionFactory.closeSession();
}
try {
session=HibernateSessionFactory.getSession();
tran=session.beginTransaction();
Bird bird=(Bird)session.load(Bird.class, 1);
System.out.println("bird.name:"+bird.getName());
tran.commit();
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
HibernateSessionFactory.closeSession();
}
}
管理二级缓存
//管理二级缓存
SessionFactory factory=HibernateSessionFactory.getSessionFactory();
/*factory.evict(Bird.class);*/
factory.evict(Bird.class, 1);
//模式的设置,一般不用设置
tran=session.beginTransaction();
session.setCacheMode(CacheMode.GET);
查询缓存只对query.list()起作用,对query。Iterate不起作用:
一般二级缓存和查询缓存一起使用
<!-- 开启查询缓存 -->
<property name="hibernate.cache.use_query_cache">true</property>
使用:
Query query=session.createQuery("select s from student s");
query.setCacheable(true);
List list =query.list();
for(Iterator iter=list.iterator();iter.hasNext();){
Student student=(Student)iter.next();
}
设置抓取策略
对象上可以批量加载集合
<many –to-one name=”classes” column=”classesid” fetch=”select”/>
Fetch=”select”,另外发送一条select语句抓取当前关联实体或集合
Fetch=”join”,hibernate会通过select语句使用外连接来加载其关联实体或集和
此时Lazy会失效
集合上:
保存默认 同fetch=“select”
<set name=”students” inverse=”true” cascade=”all” fetch=”select”>
和上面一样。另外发出一条语句。
设置为Join和上面一样;
设置成subselect,会影响sql语句另外发送一条前面查询到的实体对象和关联集合
抓取优化
在查询一的一端如下设置
<class name="Group" table="t_group" batch-size="20">
<id name="id">
<generator class="native" />
</id>
当查询多个连接的时候就20个才发出一条语句,起到优化作用
List students=session.createQuery(“select s from s where s.id in(:ids)”)
.setParameterList(“ids”,new Object[]{1,2,3,4,5,6,7,8,9}).list();
For(Iterator iter=students.iterator();iter.hasNext();){
Student student=(Student)iter.next();
System.out.println(“student.name=”+student.getName());
System.out.println(“classes.name=”+student.getClasses().getName();
}
集合上也是一样的
<set name=”student” inverse=”true” cascade=”all”batch-size=”5”>
批量更新fetch每次取多少50,batch每次更新多少30
<property name="hibernate.jdbc.fetch_size">50</property>
<property name="hibernate.jdbc.batch_size">30</property>
Hibernate使用技巧
抛出异常
e.printStackTrace();
throw new AppException(“error.add”);
分页
/**
* 根据条件查询物料信息
* @param queryStr 查询条件
* @return item对象的集合
*/
public PageModel findAllItem(int pageNo, int pageSize, String queryStr) {
Session session = null;
PageModel pageModel = null;
try {
//session = HibernateUtils.getSession();
session = HibernateFilter.getSession();
session.beginTransaction();
Query query = null;
if (queryStr != null && queryStr.trim().length() != 0) {
query = session.createQuery("from Item a where a.itemNo like ? or a.itemName like ? order by a.itemNo")
.setParameter(0, queryStr + "%")
.setParameter(1, queryStr + "%");
}else {
//query = session.createQuery("from Item a order by a.itemNo");
query = session.createQuery("select a from Item a join fetch a.category b join fetch a.unit c order by a.itemNo");
}
List itemList = query.setFirstResult((pageNo - 1) * pageSize)
.setMaxResults(pageSize)
.list();
pageModel = new PageModel();
pageModel.setPageNo(pageNo);
pageModel.setPageSize(pageSize);
pageModel.setList(itemList);
pageModel.setTotalRecords(getTotalRecords(session, queryStr));
session.getTransaction().commit();
}catch(Exception e) {
//记录日志,log4j等......
e.printStackTrace();
session.getTransaction().rollback();
throw new AppException("drp.database.item.error.findallitem");
// }finally {
// HibernateUtils.closeSession(session);
}
return pageModel;
}