hibernate总结(20-30)

但可以这样用: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());

}

 

总结Listiterate区别

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 &lt ;: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);使用缓存

 

SessionClear()清楚全部

sessionEvict()制定清除

一级缓存无法取消,但可以管理

大批量更行用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()起作用,对queryIterate不起作用:

 

一般二级缓存和查询缓存一起使用

<!-- 开启查询缓存 -->

                           <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每次取多少50batch每次更新多少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;

 

                        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值