Hibernate补充

来源:互联网 发布:caffe alexnet 训练 编辑:程序博客网 时间:2024/06/05 04:49

HQL

  • hql(hibernate query language )是完全面向对象的查询语言,可以理解继承,多态,关联等概念,区分大小写。但是对应sql关键字(select,from where)不区分

hql基本查询

单属性查询

public void testQuery1(){        //查询所有书名        //Book是实体类的名字        //创建Query对象        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        String hql="select name from Book";        Query query = session.createQuery(hql);        //list()方法返回查询结果        //返回结果的类型 是根据查询的列决定的        List<String> list = query.list();        for(String bookname:list){            System.out.println(bookname);        }        tx.commit();        HibernateUtil.closeSession();    }

多属性查询

public void testQuery2(){        //查询所有书 的名称和价格        //创建Query对象        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();            //list()方法返回查询结果        //查询多个列时  返回结果是数组集合 数组中元素的类型 是由查询列来决定        List<Object[]> list = session.createQuery("select name,price from Book").list();        for(Object[] objs:list){            System.out.println(objs[0]+"--"+objs[1]);        }        tx.commit();        HibernateUtil.closeSession();    }

将多个查询列封装为对象

public void testQuery3(){        //查询所有书 的名称和价格        //创建Query对象        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        //Book 大写 表示的是  cn.siggy.pojo.Book类        //name表示的 Book类中的属性名        //list()方法返回查询结果        //查询多个列时  返回结果是数组集合 数组中元素的类型 是由查询列来决定        List<Book> list = session.createQuery("select new Book(name,price) from Book").list();        for(Book b:list){            System.out.println(b);        }        tx.commit();        HibernateUtil.closeSession();    }

别名使用

public void testQuery4(){        //查询所有书 的名称和价格        //创建Query对象        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        //Book 大写 表示的是  cn.siggy.pojo.Book类        //name表示的 Book类中的属性名        //list()方法返回查询结果        //查询多个列时  返回结果是数组集合 数组中元素的类型 是由查询列来决定        List<Book> list = session.createQuery("select new Book(b.name,b.price) from Book as b").list();        for(Book b:list){            System.out.println(b);        }        tx.commit();        HibernateUtil.closeSession();    }

查询所有列 (不使用select)

public void testQuery5(){        //查询所有书 的名称和价格        //创建Query对象        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        List<Book> list = session.createQuery("from Book").list();        for(Book b:list){            System.out.println(b);        }        tx.commit();        HibernateUtil.closeSession();    }

别名使用

//查询所有列2  使用select//查询所有列2 不能使用*  需要使用别名    @Test    public void testQuery6(){        //查询所有书 的名称和价格        //创建Query对象        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        List<Book> list = session.createQuery("select b from Book b").list();        for(Book b:list){            System.out.println(b);        }        tx.commit();        HibernateUtil.closeSession();    }

hql条件查询

占位符?  从0开始    public void testQuery7(){        //查询所有书 的名称和价格        //创建Query对象        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        List<Book> list = session.createQuery("from Book b where id<?")                        .setInteger(0, 4)                        .list();        for(Book b:list){            System.out.println(b);        }        tx.commit();        HibernateUtil.closeSession();    }
占位符?  从0开始  使用setParameter@Test    public void testQuery8(){        //查询所有书 的名称和价格        //创建Query对象        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        List<Book> list = session.createQuery("from Book b where id<?")                        .setParameter(0, 4)                        .list();        for(Book b:list){            System.out.println(b);        }        tx.commit();        HibernateUtil.closeSession();    }

命名查询

//条件查询 命名查询--设置条件参数的名称  以冒号开头后更名称  设置参数时 只需指定名    @Test    public void testQuery9(){        //查询所有书 的名称和价格        //创建Query对象        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        List<Book> list = session.createQuery("from Book b where id<:id")                        .setParameter("id", 4)                        .list();        for(Book b:list){            System.out.println(b);        }        tx.commit();        HibernateUtil.closeSession();    }

分页查询

    public void testQuery10(){        //查询所有书 的名称和价格        //创建Query对象        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        List<Book> list = session.createQuery("from Book b")                        .setFirstResult(3)//开始显示的记录下标(currentPage-1)*pageSize                        .setMaxResults(3)//设置每页记录数pageSize                        .list();        for(Book b:list){            System.out.println(b);        }        tx.commit();        HibernateUtil.closeSession();    }

统计查询

public void testQuery11(){        //查询图书总数        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        //int,long        Number count = (Number)session.createQuery("select max(b.price) from Book b")                        .uniqueResult();        System.out.println("总数:"+count.byteValue());        tx.commit();        HibernateUtil.closeSession();    }

分组查询

    public void testQuery12(){        //查询图书总数        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        //int,long        List<Object[]> list = session.createQuery("select b.category.name,count(b.id) from Book b group by b.category.name")                        .list();        for(Object[] objs:list){            System.out.println(objs[0]+"--"+objs[1]);        }        tx.commit();        HibernateUtil.closeSession();    }

排序

public void testQuery13(){        //查询图书总数        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        //int,long        List<Book> list = session.createQuery("from Book order by price desc")                        .list();        for(Book b:list){            System.out.println(b);        }        tx.commit();        HibernateUtil.closeSession();    }

对象导航

//连接查询    @Test    public void testQuery14(){        //查询 "仙侠"的书籍信息        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        String hql="from Book b where b.category.name=:name";        hql="select b from Book b join b.category c where c.name=:name";        hql="select b from Book b inner join b.category c where c.name=:name";        List<Book> list = session.createQuery(hql)                        .setString("name", "仙侠")                        .list();        for(Book b:list){            System.out.println(b);        }        tx.commit();        HibernateUtil.closeSession();    }

左外链接

public void testQuery15(){        //查询 "仙侠"的书籍信息        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        String hql="select c.name,b.name from Category c left outer join c.books b";        List<Object[]> list = session.createQuery(hql)                        .list();        for(Object[] objs:list){            System.out.println(objs[0]+"----"+objs[1]);        }        tx.commit();        HibernateUtil.closeSession();    }

过滤查询

  • 定义过滤器
  • 使用:加条件
  • 在查询时候 使得过滤器生效
public void testQuery16(){        //查询 "仙侠"的书籍信息        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        //启用过滤器        session.enableFilter("bf").setParameter("id", 4);        List<Book> list =session.createQuery("from Book").list();        for(Book b:list){            System.out.println(b);        }        tx.commit();        HibernateUtil.closeSession();    }

命名查询

public void testQuery17(){        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        List<Book> list =session.getNamedQuery("getByCategoryId")                        .setInteger("id", 3)                        .list();        for(Book b:list){            System.out.println(b);        }        tx.commit();        HibernateUtil.closeSession();    }

本地SQL查询

public void testQuery18(){        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        String sql="select Name,Price from BOOK";        List<Object[]> list =session.createSQLQuery(sql)                        .list();        for(Object[]  b:list){            System.out.println(b[0]+"-"+b[1]);        }        tx.commit();        HibernateUtil.closeSession();    }

Hibernate加载策略

  • 即时加载 –get加载数据
    使用get获取数据,会立即查找(缓存—数据库)
  • 延迟加载 懒加载 lazy—load,不会立即查找,当需要的时候才会查找
    容易造成:LazyInitialaztionException异常:因为session被关闭。
  • Load支持延迟加载,get不支持延迟加载。如果没有设置延迟加载,那么load也会立即加载对象。
  • class的lazy
    a)class默认情况下是支持懒加载如果设置lazy=false,get和load都会立即加载对象。
  • set\list默认下是lazy=true的。支持懒加载,但是当使用size()的时候依然要去查询整个set集合的内容。Lazy=false;立即查询所有集合的内容。Lazy=extra比较智能。支持懒加载,当使用size()的时候,不会查询整个集合,仅仅查询集合中元素的个数。当需要使用集合元素的内容时,再去查询集合内容。
  • 单端关联上的lazy:(many-to-one,ont-to-one)默认是支持懒加载lazy=proxy

Hibernate抓取策略

抓取策略(fetching strategy) 是指:当应用程序需要在(Hibernate实体对象图的)关联关系间进行导航的时候, Hibernate如何获取关联对象的策略。

  • select抓取:当查询关联对象通过select语句去查询。Select发出时机,是根据lazy的值来决定的。如果lazy=false,那么在获取对象时,就会发出一条select语句,将关联对象查询出来。如果lazy!=false,那么只有在获取关联对象时才会发出select语句去查询。
  • join抓取:当查询关联对象时,通过outer join把关联对象一起查询出来,这个时候lazy无效。所有数据立即查询出来。
  • subselect抓取:如果要查询关联集合的内容。会查询之前已经查出的对象的所有关联集合。(Category对应了多个Book)如果查询了(”文学”,”历史”);那么在使用(lazy=true)”文学”或”历史”的集合对象(”所对应的书籍信息”).会将(“文学”和”历史”)的书籍信息一起查询。如果lazy=false;在查询“多个分类时”会将所有分类的书籍信息一起查询。

Hibernate缓存机制

一级缓存

  • 一级缓存又称为session缓存。生命周期相同。周期较短。事务级别的缓存。get使用了一级缓存,用get查数据时,首先检查缓存中是否有该数据,如果有直接从缓存中取数据,如果没有再查询数据库,并且将数据放入缓存中。load也支持一级缓存。load还支持lazy.当load从数据库中查询数据后,也会将数据放入缓存。
  • unique/list查询不会去查看缓存,但是list查询的实体对象将会放入缓存中。
  • iterate会执行查询id的操作,当查询对象时,会检查缓存中是否存在。如果存在则从缓存中取数据。Iterate查询出来的对象也会放入缓存。
  • 管理一级缓存:flush(),clear(),evict()

二级缓存

  • 二级缓存:sessionFactory ;进程级别的缓存。支持集群。
    使用步骤:
    a)在hibernate.cfg.xml中开启二级缓存(默认开启)
    b)配置cache.provider_class
<!-- 使用二级缓存  3.x -->    <property name="cache.use_second_level_cache">true</property>    <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property><!-- 使用二级缓存   4.3-->    <property name="cache.use_second_level_cache">true</property>    <property name="cache.region.factory_class">    org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

c)导入ehcache.jar
d)将ehcache.xml放入src下(etc下找)
e)在类中指定或在(hibernate.cfg.xml)指定

<hibernate-mapping>    <class name="cn.siggy.pojo.Book" table="book" catalog="hibernate4">        <cache usage="read-only"/>        <id name="id" type="java.lang.Integer">            <column name="id" />            <generator class="identity" />        </id>        <property name="author" type="java.lang.String">            <column name="author" />        </property>        <property name="name" type="java.lang.String">            <column name="name" />        </property>        <property name="price" type="java.lang.Double">            <column name="price" precision="22" scale="0" not-null="true" />        </property>        <property name="pubDate" type="java.sql.Timestamp">            <column name="pubDate" length="19" />        </property>    </class></hibernate-mapping>

在配置文件中

    <class-cache usage="read-only" class="cn.siggy.pojo.Book"/>
  • 使用:
public void testGet(){        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        Book book = (Book)session.get(Book.class, 1);        //发出sql语句取数据        System.out.println(book.getName());        HibernateUtil.closeSession();        session = HibernateUtil.getSession();        System.out.println("---------");        book = (Book)session.get(Book.class, 1);        System.out.println(book.getName());        tx.commit();        HibernateUtil.closeSession();    }

查询缓存:在二级缓存基础来的。

  • 在hibernate.cfg.xml中配置
<!-- 配置使用查询缓存 -->    <property name="cache.use_query_cache">true</property>
  • 使用.
原创粉丝点击