hibernate应用笔记

mySql数据库的隔离级别

Mysql:

查询隔离级别:  select @@tx_isolation;     REPEATABLE-READ  (可重复读)

 

更改隔离级别:  set transaction isolation level read uncommitted;(未提交读, 没commit也能读到)

 

 

 

cascade="all"   级联操作

inverse="true"  控制反转

 

◆继承映射

1)父、子类在一个表中:

 

<class name="Animal" package="extendsMapping" table="t_animal">

   <id name="id">

     <generator class="native"/>

   </id>

  <!--鉴别器要紧挨着放到id下面这个string是hibernate类型,也可以-->

  <discriminator column="type" type="string"/>用java类型  

   <property name="name"/>

   <property name="sex"/>

   <subclass name="Pig" discriminator-value="P">

       <property name="weight"/>

   </subclass>

   <subclass name="Bird" discriminator-value="B">

       <property name="height">

   </subclass>

</class>

 

2)每个父、子类在一个表中:

<class name="Animal" package="extendsMapping" table="t_animal">

   <id name="id">

     <generator class="native"/>

   </id>

   <property name="name"/>

   <property name="sex"/>

    <joined-subclass name="Pig">

      <key column="pid"/>

      <property name ="weight"/>

   </joined-subclass>

   <joined-subclass name="Bird">

     <key column="bid"/>

      <property name="height"/>

  </joined-subclass>

</class>

 

3)父类无表(有,设成抽象也不导出的),每个子类都对应一张表:(子类间id不能从)

<class name="Animal" package="extendsMapping" table="t_animal" abstract="true">

   <id name="id">

     <generator class="assigned "/><!--主键不能重复需要手动分配-->

   </id>

   <property name="name"/>

   <property name="sex"/>

   <union-subclass name="Pig" tabble="t_pig">

         <property name="weight"/>

  </union-subclass>

 

<union-subclass name="Bird" tabble="t_birg">

         <property name="height"/>

  </union-subclass>

</class>

 

◆component 映射 :

       在hibernate中,component是实体对象的逻辑组成部分,component与实体对象的本质区别是它没有oid,

 

       component的好处,它实现了对象的层次细粒度划分,层次分明,利于复用

 

   <hibernate-mapping>

      <class name="mapping.User">

           <id name="id">

              <generator class="native"/>

           </id>

           <property name="name">

            <component name="contact">

                    <property name="contactTel"/>

                    <property name="email"/>

                    <property name="zipCode"/>                        

                    <property name="address"/>

            </component>

   </hibernate-mapping>

 

◆复合主键(联合主键)映射

通常将复合主键相关的属性,放到单独的实体类中

    该实体类

            ● 必须实现序列化接口 implements Serializable

            ● 必须重写equals和hashcode方法

<hibernate-mapping>

    <class name="ormapping.FiscalYearPeriod" table="t_fiscal_year_period">

       <composite-id name="fiscalYearPeriodPK">

             <key-property name="fiscalYear"/>

             <key-property name="fiscalPeriod"/>

       </composite-id>

       <property name="beginDate"/>

       <property name="endDate"/>

       <property name="periodSts"/>

      </class>

</hiberante-mapping>

 

◆集合映射映射

         ●set

         ●list

         ●array

         ●map

 

<hibernate-mapping>

   <class name="ormapping.CollectionMapping">

     <id name="id">

          <generator class="native"/>

     </id>

     <property name="name"/>

      

      <set name="setValues" table="t_setvalues">

         <key column="setid"/>

          <element type="string" column="value"></element>

       </set>

 

      <list name="listValues" table="t_listvalues">

         <key cloumn="lid"/>

         <list-index column="list_index"/><!--维护list的顺序-->

         <element type="string" column="value"/>

      </list>

 

     <array name="arrayValues" table="t_arrayvalues">

         <key column="arrayid"/>

         <list-index column="array_index"/>

          <element type="string" column="value"/>

          <!--如果不是普通属性用<composite-element>-->

     </array>

 

      <map name="mapValues" table="t_mapvalues">

           <key column="mapid">

           <map-key type="string" column="key"/>

           <element type="string"  column="value"/>

      </map>

   </class>

</hibernate-mapping>

 

◆树的映射,

     节点-父节点  many-to-one, 节点-子节点  one-to-many

   <hibernate-mapping>

      <class name="ormapping.Node" table="t_node">

          <id name="id">

                <generator class="native"/>

          </id>

           <porperty name="name"/>

           <property name="levle"/>

           <property name="leaf"/>

             <!--<many-to--one>在多的一段加个外键指向一的一端,这个例子中就一个表,加的外键指向本表,即自关联-->

           <many-to-one name="parent" column="pid"/>

           <set name="children" lazy="extra" inverse ="true">

                  <key column="pid"/>

                   <one-to-many class="ORMapping.Node" >

           </set>

 

      </class>

   </hibernate-mapping>

 

 

hibernate中的锁

悲观锁:其实现一般依赖于数据库提供的机制,在整个处理过程中数据将处于锁定状态

 

例如: select * from user for update

        select * from user for update nowait(oracle用)

 

hibernate中用  load(Class theClass,Serializable id,LockMode lockMode),

lockMode: UPGRADE(ORACLE用 UPGRADE_NOWAIT)

 

乐观锁:大多数是基于数据版本记录机制实现(version),一般在数据库中加一个version字段

         读取数据时连同版本号一同读出,之后更新是版本号加一,如果提交数据小于当前版本

         号则认为数据是过期的否则才能更新。(也有用时间戳实现的。)

<hibernate-mapping>

   <class name="ormapping.user" optimistic-lock="version" ><!--不写也可以默认就是version-->

          <id name="id">

                <generator class="uuid"/>

          </id>

          <version name="version"/>

           <property name="name"/>

              ...

   </class>

</hibernate-mappin>

 

 

 

 

 

 

hibernate的 lazy(延迟加载):

lazy的策略可以用在:

   ● <class>标签上,可以去值:true/false

   ● <property>标签上,可以取:true/false,这个属性需要类增强工具

   ● <set><list>等集合上,可以去值:true/false/extra

   ● <one-to-one>和<many-to-one>(单端关联)等标签上,可以取:false/proxy/noproxy

 

概念:

   ● lazy是只有需要的时候才发出sql语句

   ● hibernate支持lazy策略,只有session打开状态才有效可以用 ThreadLocale和Filter->OpenSessionInView来解  决。

    hibernate在class级别的lazy可以控制什么时候加载这些普通属性(property),但不能控制many-to-one one-to-many等。

 

 

 hibernate在集合上的lazy策略,可以取值ture/false/extra (智能推荐)

 

 hibernate在单端关联的lazy策略<one-to-one>和<many-to-one>,可以取值: false/proxy/noproxy(noproxy需要类增强工具)

 

 

HQL查询

简单属性查询

 

 ●单个属性查询,返回结果集为单个属性的集合。

   List students= session.createQuery("select name from Student").list();

   //students 为name对应的类型String集合List<String>

    for(Iterator iter=students.iterator();iter.hasNext()){

       String  name =(String)iter.next();

    }

 

 ●多个属性查询,返回结果为对象数组的集合,对象数组的长度取决于查询属性的个数,类型取决于属性类型

   List students = session.createQuery("select id,name from Student").list();

 

     for(Iterator iter=students.iterator();iter.hasNext()){

         Object[] objs=(Object[])iter.next();

    }

 

 ●多个属性查询,用hql动态实例化对象返回

   List students = session.createQuery("select new Strudent (id,name) from Student").list();

 

     for(Iterator iter=students.iterator();iter.hasNext()){

       Student student = iter.next();

    }

 

 ●别名

   List students = session.createQuery("select s.id, s.name from Student s").list();

   或

   List students = session.createQuery("select s.id, s.name from Student as s").list();

 

查询实体对象

 

●查询实体对象 可以忽略select,但如果用select了必须使用别名,hql不支持*,支持count(*)

   List students = session.createQuery("from Student").list();

 //List students = session.createQuery("select s from Student as s").list();

    for(Iterator iter=students.iterator();iter.hasNext()){

       Student student = iter.next();

    }

   ●)n+1问题,在默认情况下使用query .iterate()查询,可能会引发n+1问题,所为n+1是指在查询

   对象的时候发出了n+1条查询语句

   1:首先发出查询实体对象id列表的sql

   n:根据id在缓存中查询,如果缓存中有与之匹配的数据,那么就区缓存中的数据,否则依次根据id发出查询语句。

 

   ●)query.list()默认只往缓存中放不从缓存中读。

     发出 select student0_.id as id1_,student0_.name as name1,.... from t_student as   student0_

    query.iterate(),会利用缓存读取查询,第一次查询 会发出n+1条select语句,1为先查id的sql语句,然后根据id 查

     n为记录的总数,如果第2回就不会了....

  select student0_.id as col_0_0_ from t_student as student0_

 

  select student0_.id as col_0_0_,student0_.name as name1,.... from t_student as student0_ where student0_.id = ?

 

3 条件查询

  可以拼HQL串,

    List students = session.createQuery("select s.id ,s.name from Student s where s.name like '%1%'").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 like : myname

").setParameter("myname","%1%").list();

 

    ● 条件查询支持in ,通常用setParameterList来赋值

   List students = session.createQuery("select s.id ,s.name from Student s where s.id in (:myids) ")

           .setParameterList("myname",new Objects[]{1,3,5}).list();

    ●between

   List students = session.createQuery("select s.id ,s.name from Student s where s.createTime

between ? and ? order by s.id ").setParameterList(0,mydateformat.parse("2008/08/01")).setParameterList(1,dateformat.parse("2008/08/25")).list();

   ●调用数据库的函数

   List students = session.createQuery("select s.id ,s.name from Student s where date_format(s.createTime,'%Y-%m')=? order by s.id ")。setParameterList(1,"2008/08/25").list();

 

4 外置命名查询

   ● 在映射文件中采用<query>类定义hql

<hibernate-mapping>

  <class name=...>

  ...

  </class>

  <query><![CDTA[

             select s from Student s where s.di <?

  ]]>

  </query>

</hibernate-mapping>

   ●在程序中使用session.getNamedQuery()方法来得到查询(query对象)


5 查询过滤器

   ●定义过滤器参数

   ●在类映射文件中使用过滤参数

   ●在程序中启用过滤器

<hibernate-mapping>

  <class name=...>

  ...

  <!--在类映射文件中使用过滤参数-->

 <filter name="filtertest" condition="id &lt; :myid " />

  </class>

 

     <!--定义过滤器参数-->

    <filter-def name="filtertest">

         <filter-param name="myid" type="integer">

    </filter-def>

<hiberante-mappingapping>

 

 //在程序中启用过滤器,并设置参数

 session.enableFileter("filtertest").setParameter("myid",10);

 

6.hibernate3开始支持原生sql查询

  //返回结果是对象数组的集合,顺序同数据库中表的顺序

   session.createSqlQuery("select * from t_student").list();

     for(Iterator iter=students.iterator();iter.hasNext()){

         Object[] objs=(Object[])iter.next();

    }

 

7分页查询

   session.createQuery("from student").setFirstResult(0).setMaxResults(2).list();

 

8 对象导航查询 在hql中,使用.进行导航

   session.createQuery("select s from student s where s.classes.id <5")

 

9 连接查询

   ●内连接

     session.createQuery("select c.name, s.name from Student s join s.classes c").list();

   ●外连接(左连接/右连接)

     左连接 把所有班级都显示出来

     session.createQuery("select c.name, s.name from Classes c left join c.students s").list();

     右连接 把所有学生都显示出来

      session.createQuery("select c.name, s.name from Classes c right join c.students s").list();

 

10.统计查询

     List students=session.createQuery("select count(*) from Student").list();

     Long count = (Long)students.get(0);

 

     Long count=session.createQuery("select count(*) from Student").uniqueResult();

 

     session.createQuery("select c.name,count(s) from Student s join s.class c

     group by c.name order by c.id").uniqueResult();

 

 

hibernate的一级缓存

  一级缓存的生命周期和session一致,随着session的关闭而销亡。

    ●get/load/iterate(查询实体对象)使用一级缓存

  一级缓存缓存的是实体对象。   

  如何管理一级缓存

    ●session.clear/session.evict

 

  如何避免一次性大批量的实体数据插入

    ●先flush,在clear清除缓存

 

hibernate的二级缓存

   二级缓存也是缓存实体类

   二级缓存也称进程级缓存或叫SessionFactory级缓存,它可以被所有session共享

   二级缓存的生命周期伴随SessionFactory的生命周期存在和销往

   SessionFactory可以管理二级缓存

   二级缓存的配置和使用:

      ●将ehcache.xml文件拷贝到src下

      ●在hibernate.cfg.xml中配置启用二级缓存,默认就是开启

 

     <hibernate-configuration>

         <session-factory>

                    ...

          <!--是否启用二级缓存-->

          <property name="hibernate.cache.use_second_level_cache">true</property>

          <!--指定使用的二级缓存产品-->

          <property name="hibernate.cache.EhCacheProvider_class"

         </session-factory>

     </hibernate-configuration>

    ●指定哪些实体类使用二级缓存

     1)可以在hibernate.xml配置文件中定义

     <class-cache class="xxx" usage="read-only"/>

     2)可以在映射文件中配置缓存策略

      <hibernate-mapping>

         <class name="xxx">

           <cache usage="read-only"/>

         </class>

      </hibernate-mapping>

 

    ●一二级缓存的交互,通过setCacheMode(Cache.Mode.GET)(PUT)默认读写

hibernate的查询缓存

    查询缓存是针对普通属结果集的缓存

    对实体对象的结果集只缓存主键id.

 

    查询缓存的生命周期,当查询关联的表发生修改,那么查询缓存的生命周期结束。

 

    查询缓存的配置和使用:()

           在hibernate.cfg.xml文件中加入

           <property name="hibernate.cache.use_query_cache">true</property>

 

           在程序中显式开启查询缓存

           query.setCacheable(true);            

 

说明:转义字符应以“&”开头,以“;”结尾。

HTML常用转义字符:

字符

转义字符

描述

&

&amp;

<

&lt;

小于号

>

&gt;

大于号

"

&quot;

双引号

 

&nbsp;

空格

©

&copy;

版权符

®

&reg;

注册符

XML常用转义字符:

字符

转义字符

描述

&

&amp;

<

&lt;

小于号

>

&gt;

大于号

"

&quot;

双引号

'

&apos;

单引号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值