Hibernate基本知识(三)

来源:互联网 发布:java中的关键字 编辑:程序博客网 时间:2024/05/22 13:31

1、 对象的状态

<1>瞬时对象是new出来的,与Session和数据库都无关;

<2>持久对象是放入Session中,与Session有关的,Hibernate可以检测到,更新对象的值,可以影响到数据库中的值;

<3>脱管对象是在存入数据库,session关闭的时候由持久对象变换过来的,因此它只与数据库有关,因此Hibernate检测不到,数据库要更新需要更新语句update。

<4>Hibernate只能检测到Session中的对象变化情况。

<5>当不知道对象是瞬时的还是脱管的,如果要保存或更新数据库中的值,这个时候就需要用到saveOrUpdate(),让Hibernate去判断该对象是什么状态。

2、 HQLCriteria

 

    <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 &gt;:uid"></filter>

<class>标签外加入如下代码:

<filter-defname="idFilter">

    <filter-paramname="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>内、外连接问题

内连接

内连接就是满足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、 HibernateCURD的模板代码如下:

4、 Hibernate中对象状态图

flush()可以清除临时缓存,以保证执行的顺序。

evict()可以将对象从缓存中剔除,使其从持久态变为脱管态。

clear()可以将缓存中的所有对象剔除。

lock()可以为某对象加锁机制。

原创粉丝点击