1.Hibernate的HQL语言扩展学习
注意哦,HQL语法的关键字是不区分大小的,比如select ,Select ,SELECt 都是一样的。但是要查的类和字段是严格区分大小的比如EMP和emp是不同的。
HQL支持inner join
举例Emp类员工类,Dept类部门类
String hql= "from Emp e inner join e.dept"//一定要连接e里面的dept.如果不加e那么就是笛卡尔积。可以跟with条件查询 with e.dept.deptno=10.with语句条件必须只能是右边关联出来的。
Query query = session.createQuery(hql);//用Query接收,用session的createQuery()来执行;
然后通过List
如果使用的是myenclipse开发工具,并且里面的类和配置文件都是通过myenclipse向导生成的。那么就可以使用myenclipse工具自带的HQL查询工具。写HQL语句前在这里进行简单的测试。路径在选择工程名,右键myenclipse-----------HQL editor
HQL支持left outer join,right outer join,full join
String hql="from Emp e left outer join e.dept";//左连接,右连接类似。
HQL的聚合函数:max,min,sum没有avg和count.例如:select sum(e.sal),e.dept.deptno from Emp e group by e.dept.deptno.
current_date获取当前时间
有函数to_char,to_date.例如String hql="select to_char(e.hiredate,'yyyy-MM-dd') from Emp e";显示出来的是字符串1991-03-23.
HQL支持where 查询。where 后加条件
标准sql也能在hibernate中使用。调用方法是Query query = session.createSQLQuery(hql);
Hibernate一级缓存和二级缓存
一级缓存:get()/load()/iterator()/list()/save()/update()/saveOrUpdate()/delete()
二级缓存:get()/load()/iterator()
不用缓存:find()
iterator()是先查出主键标识,然后要据主键标识从一级缓存中去找,如果没有找到就去二级缓存找,如果二级缓存还没有就要查询数据库了
例如:
Session session = null;
Transaction ts = null;
try{
session = HibernateFactory.getSession();
ts = session.beginTransaction();
Dept d =(Dept)sesssion.load(Dept.class,10);
System.out.println(d);
Dept d1 = (Dept)session.load(Dept.class,10);
System.out.println(d1);
ts.commit();
}catch(HibernateException e){
e.printstackTrace();
}
finally{
HibernateFactory.closeSession(session);
}
}
上面如果是延迟加载,即Dept.hbm.xml的class属性的lazy=true。只发送一条sql查询。
Session session = null;
Transaction ts = null;
try{
session = HibernateFactory.getSession();
ts = session.beginTransaction();
Dept d =(Dept)sesssion.load(Dept.class,10);
System.out.println(d);
ts.commit();
ts = session.beginTransaction();
Dept d1 = (Dept)session.load(Dept.class,10);
System.out.println(d1);
ts.commit();
}catch(HibernateException e){
e.printstackTrace();
}
finally{
HibernateFactory.closeSession(session);
}
}
上面查询虽然事务提交了,但是在一个session范围内。还是发送一次sql查询。
Session session = null;
Transaction ts = null;
try{
session = HibernateFactory.getSession();
ts = session.beginTransaction();
Dept d =(Dept)sesssion.load(Dept.class,10);
System.out.println(d);
ts.commit();
}catch(HibernateException e){
e.printstackTrace();
}
finally{
HibernateFactory.closeSession(session);
}
try{
session = HibernateFactory.getSession();
ts = session.beginTransaction();
Dept d =(Dept)sesssion.load(Dept.class,10);
System.out.println(d);
ts.commit();
}catch(HibernateException e){
e.printstackTrace();
}
finally{
HibernateFactory.closeSession(session);
}
}
上面的load查询虽然设了延迟加载,但还是会发送两次查询。这里是两个事务。前一次的session的关闭又打开了。如果想发送一次查询怎么办呢。使用二级缓存。
默认情况下,Hibernate使用EHCache进行JVM级别的缓存(目前,Hibernate已经废弃了对JCS的支持,未来版本中将会去掉它)。 你可以通过设置hibernate.cache.provider_class属性,指定其他的缓存策略, 该缓存策略必须实现org.hibernate.cache.CacheProvider接口。
表 20.1. 缓存策略提供商(Cache Providers)
Cache | Provider class | Type | Cluster Safe | Query Cache Supported |
---|---|---|---|---|
Hashtable (not intended for production use) | org.hibernate.cache.HashtableCacheProvider | memory | yes | |
EHCache | org.hibernate.cache.EhCacheProvider | memory, disk | yes | |
OSCache | org.hibernate.cache.OSCacheProvider | memory, disk | yes | |
SwarmCache | org.hibernate.cache.SwarmCacheProvider | clustered (ip multicast) | yes (clustered invalidation) | |
JBoss TreeCache | org.hibernate.cache.TreeCacheProvider | clustered (ip multicast), transactional | yes (replication) | yes (clock sync req.) |
在hibernate.cfg.xml中加入缓存配置如下
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
在相应映射文件Dept.hbm.xml中的class中加
在hibernate的源码下面的etc文件夹下面有一个ehcache.xml文件。拷到工程的src目录下。
还要保证jar包里有ehcache.jar包。
注意:一级缓存是指缓存内容放在内存中。二级缓存有放在内存中和硬盘上两种,如果要放在硬盘上,那么这个类就要实现序列化。即java.io.Serializable接口