1、 对象的状态
<1>瞬时对象是new出来的,与Session和数据库都无关;
<2>持久对象是放入Session中,与Session有关的,Hibernate可以检测到,更新对象的值,可以影响到数据库中的值;
<3>脱管对象是在存入数据库,session关闭的时候由持久对象变换过来的,因此它只与数据库有关,因此Hibernate检测不到,数据库要更新需要更新语句update。
<4>Hibernate只能检测到Session中的对象变化情况。
<5>当不知道对象是瞬时的还是脱管的,如果要保存或更新数据库中的值,这个时候就需要用到saveOrUpdate(),让Hibernate去判断该对象是什么状态。
2、 HQL和Criteria
<1>、HQL查询(官方推荐):
String hql = "from User as user where user.name=?";
Query query = session.createQuery(hql);
query.setString(0, name);
List<User> list = query.list(); //如果有多条记录,用list
User u = (User)query.uniqueResult();//确定查到结果集只有一条记录录时使用
对于上面的hql语句,我们可以这样写(为name取别名):
String hql = "from User as user where user.name=:n";
query.setString(“n”, name);
Hibernate中的分页可以用以下语句:
query.setFirstResult(100); //从哪一条开始查询
query.setMaxResults(20); //每页显示多少条
<2>、Criteria条件查询(比较常用,功能有限):
Criteria c = session.createCriteria(User.class);
c.add(Restrictions.eq(“name”,name)); //从数据库中查出等于name数据
c.add(Restrictions.lt(“birthday”,new Date());//查出小于birthday数据
分页语句:
c.setFirstResult(0); //从哪一条开始查询
c.setMaxResults(10); //每页显示多少条
List<User> list = c.list(); //如果有多条记录,用list
User u = (User)c.uniqueResult();//确定查到的结果集只有一条记录时使用
<3>、外置命名查询(很少用)
在实体映射文件的<class>标签后加上如下配置: <!-- 外置命名查询(例子:TestOutName) --> <!-- <query name="queryUser"> <![CDATA[from User u where u.id>?]]> </query> 调用时如下: Session session = HibernateUtil.getSession(); Query query = null; session.beginTransaction(); query = session.getNamedQuery("queryUser"); List<User> urs = query.setParameter(0, 5).list(); for(User u : urs) { System.out.println("id:"+u.getId()+" name:"+u.getName()+" createTime:"+u.getCreateTime()); session.getTransaction().commit();
|
<4>、过滤器(很少用)
过滤器配置如下:
在<class>标签中加入如下代码: <filter name="idFilter" condition="id >:uid"></filter> 在<class>标签外加入如下代码: <filter-def name="idFilter"> <filter-param name="uid" type="integer"/> </filter-def> |
例子代码:
session.beginTransaction(); session.enableFilter("idFilter").setParameter("uid", 4); query = session.createQuery(“from User”); List<User> urs = query.list(); for(User u : urs) { System.out.println("id:"+u.getId()+" name:"+u.getName()+" createTime:"+u.getCreateTime()); } session.getTransaction().commit(); |
<5>内、外连接问题
l 内连接
内连接就是满足Document中的uid等于User的id时,将两个表的数据连接成类似一张表信息的过程。
from Document d inner join d.user on d.uid=d.user.id
l 外连接
外连接分为左外连、右外连和全外连。
外连接是将两个表的信息都一一对应后进行连接,得到结果行数可能是两表行数的乘积。下面两个HQL语句功能相同。
select * from User u,Document d where u.id=d.user.id
select * from User u outter join Document d on u.id = d.user.id
<6>、聚合函数和子查询
在HQL中*只能出现在count(*)中。
select d.user.name, count(*) from Document d group by d.user having count(*)>1 order by d.user.id";
<7>、Iterator查询与N+1问题
Session session = HibernateUtil.getSession(); Query query = null; try { session.beginTransaction(); query = session.createQuery("from User u where u.id>=4 and u.id<=6"); List<User> urs = query.list(); for(User u : urs) { System.out.println("id:"+u.getId()+" name:"+u.getName()+" createTime:"+u.getCreateTime()); } //上面通过List查询过的那些User将会在缓存中存在,当下面的Iterator再查询的时候,它会先从数据库查出所有User的ID,然后再用ID从缓存中找,如果缓存中有的话,就从缓存中取,不用向数据库发select语句。 System.out.println("======================================"); query = session.createQuery("from User"); Iterator<User> iter = query.iterate(); while(iter.hasNext()) { User u = iter.next(); System.out.println("id:"+u.getId()+" name:"+u.getName()+" createTime:"+u.getCreateTime()); } session.getTransaction().commit(); } catch (HibernateException e) { session.getTransaction().rollback(); e.printStackTrace(); } finally { HibernateUtil.closeSession(); } |
<8>、导航查询
给个例子如下:(利用本对象中另外对象的属性条件来查询本对象的信息)
String hql = "from Document d where d.user.name=?"; Session session = HibernateUtil.getSession(); Query query = null; session.beginTransaction(); query = session.createQuery(hql); query.setParameter(0, "user5"); List<Document> ds = query.list(); for(Document d : ds) { System.out.println("id:"+d.getId()+" title:"+d.getTitle()+" content:"+d.getContent()+" createTime:"+d.getCreateTime()); |
<9>、HQL中的DML(很少用)
hql的DML语句不受缓存管理,所以很少使用
示例代码:
3、 Hibernate中CURD的模板代码如下:
4、 Hibernate中对象状态图
flush()可以清除临时缓存,以保证执行的顺序。
evict()可以将对象从缓存中剔除,使其从持久态变为脱管态。
clear()可以将缓存中的所有对象剔除。
lock()可以为某对象加锁机制。
