hibernate 总结

hibernate 总结

 

配置:


一 Hibernate基本映射:

类-->数据库表
普通属性--> 表字段

通过<class>标签映射到数据库表,通过<property>标签将普通属性映射到表字段
所谓普通属性,不包括自定义类,集合类和数组等。

实体类四条主要的规则:
 * 实现一个默认的(即无参数的)构造方法(constructor)
 * 提供一个标识属性(identifier property)(可选)
 * 使用非final的类 (可选)
 * 为持久化字段声明访问器(accessors)(可选)

<class>标签用来将一个类映射到数据库表,其name属性表示这个类的全路径,默认情况下,
映射到数据库表名,与类名相同。我们可以通过<class>标签的table属性更改表的名称

!!注意:如果类的名称是数据库的关键字,则必须通过table属性来重新定义对应的表名;

类属性的映射包括:
 * 普通属性
 * 自定义属性
 * 集合(数组)

ID的映射:
了解id的生成策略,重点了解uuid、native、assigned
------------------
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
 <class name="com.bjsxt.hibernate.User1" table="t_user1">
  <id name="id">
   <generator class="uuid"/>
   <!--
   <generator class="native"/>
   oracle会自动指定sequence为自增长
   <generator class="assigned"/>手动
   -->
  </id>
  <property name="name" length="20" unique="true"/>
  <property name="password"/>
  <property name="createTime"/>
  <property name="expireTime"/>
 </class>
</hibernate-mapping> 


Hibernate一对多单向关联映射

<set name="students" inverse="true" orderby="asfd"><!-- 在表现层可以有稳定的输出-->
 <key column="classid"/>
 <one-to-many class="com.bjsxt.hibernate.Student"/>
</set>

这种映射的本质是利用了多对一的关联映射的原理

多对一关联映射:是在多的一端添加一个外键维护多指向一的关联引用
一对多关联映射:是在多的一端添加一个外键维护一指向多的关联引用

也就是说,一对多和多对一的映射策略是一致的,只是站的角度不同

缺点:
  * 更新student表中的classesid字段时,需要对每一个student发出一个update的sql,
    来更新classesid字段
  * 如果将t_student表中的classesis设置为非空,则不能保存student数据,因为关系是由
    classes维护的,在保存student时,还没有对应的classesid被生成  


Hibernate 一对多双向关联映射

一对多双向关联映射的方法:

在一一端:
在集合标签里面使用<key>标签来表明需要在对方的表中添加一个外键指向一一端。

在多一端:
使用<many-to-one>标签来映射。

需要注意:<key>标签所指定的外键字段名需要与<many-to-one>标签定义的外键字段名一致,否则便会造成引用数据的
丢失!

--------------------------------------------------------------------------------------
如果从一端来维护一对多双向关联的关系,hibernate会发出多余的update语句,所以
一般地情况下,我们便会从多一端来维护其关联关系!
----------------------------------------------------

关于inverse属性:
inverse属性可以被设置到集合标签<set>上,表示在存储双向一对多关联映射的时候,
存储的是那一方的关联引用。默认情况下,inverse=“false”,所以,我们可以从一一端
或者多一端来维护两者之间的关系;如果我们设置inverse=“true”,则只能通过多一端来
维护两者之间的关系。inverse属性可以被用在一对多和多对多双向关联中;

注意:inverse属性只是在将数据持久化到数据库的过程中发挥作用.
多的一方维护没有了UPDATE
一的一方维护先insert后update
使用inverse后如果还用一的一维护db中就会有null,持久化就不成功。 也就说使用了inverse=true后只能从一的一方来维护,所谓维护就是,谁使用setXXXX方法,即student.setClass(class1);


Hibernate多对一关联

 关联映射的本质
 * 是将关联关系映射到数据库中,关联关系在对象模型中体现为内存中的一个或多个引用
 
<many-to-one>标签会在“多”的一端添加一个外键,指向“一”的一端,这个外键是由<many-to-one>
标签中的column属性定义的,如果忽略column属性,默认创建的外键与属性名相同

<many-to-one>标签的定义实例:
 <many-to-one name="group" column="relatedGroup"/>
可以指定class属性,如果不指定Hibernate会自动找其关联类

理解级联的含义 casecade=update-delete all等 使用casecade设置可避免抛出非持久化异常


Hibernate一对一主键关联映射(双向关联)
<one-to-one>不会在表中添加新的列

<hibernate-mapping>
 <class name="com.bjsxt.hibernate.Person" table="t_person">
  <!-- 主键一致 要引对方的主键 -->
  <id name="id">
   <generator class="foreign">
    <param name="property">idCard</param>
   </generator>
  </id>
  <property name="name"/>
  <one-to-one name="idCard" constrained="true"/>
 </class>
</hibernate-mapping>

<hibernate-mapping>
 <class name="com.bjsxt.hibernate.IdCard" table="t_idcard">
  <id name="id">
   <generator class="native"/>
  </id>
  <property name="cardNo"/>
  
  <one-to-one name="person"/>
 </class>
</hibernate-mapping>

 

Hibernate一对一外键关联映射(双向关联)

<hibernate-mapping>
 <class name="com.bjsxt.hibernate.IdCard" table="t_idcard">
  <id name="id">
   <generator class="native"/>
  </id>
  <property name="cardNo"/>
  <one-to-one name="person" property-ref="idCard" /><!-- 根据person中的属性idCard来确定 -->
 </class>
</hibernate-mapping>

<hibernate-mapping>
 <class name="com.bjsxt.hibernate.Person" table="t_person">
  <id name="id">
   <generator class="native"/> 
  </id>
  <property name="name"/>
  <many-to-one name="idCard" unique="true"/>
 </class>
</hibernate-mapping>


多对多单向关联
要有中间表来引入,有时在设计时也可在中间表中入其它列

需要注意映射规则:
<set name="users" table="t_user_role">
 <key column="roleid"/><!--中间表-->
 <many-to-many class="com.bjsxt.hibernate.User" column="userid"/>
</set>

多对多双向关联

注意映射规则:
<set name="roles" table="t_user_role">
 <key column="userid"/>
 <many-to-many class="com.bjsxt.hibernate.Role" column="roleid"/>
</set>

table属性必须和单向关联中table的 名称相同;
<key>中的column属性值必须等于单向关联中<many-to-many>标签指向的column的属性值
<many-to-many>中column属性值必须等于单向关联中<key>中column的属性值

在user_role模式中也使用单向的many-to-one(inverse)映射,由中间表指向user  和 role 来维护多对多的情况

 

Hibernate继承映射

 

Hibernate继承映射的第一种策略:每棵类继承树对应一张表

1、理解如何映射
因为类继承树肯定是对应多个类,要把多个类的信息存放在一张表中,必须有某种机制来区分哪些记录是属于哪个类的。
这种机制就是,在表中添加一个字段,用这个字段的值来进行区分。用hibernate实现这种策略的时候,有如下步骤:
父类用普通的<class>标签定义
在父类中定义一个discriminator,即指定这个区分的字段的名称和类型
如:<discriminator column=”XXX” type=”string”/>
子类使用<subclass>标签定义,在定义subclass的时候,需要注意如下几点:
Subclass标签的name属性是子类的全路径名
在Subclass标签中,用discriminator-value属性来标明本子类的discriminator字段(用来区分不同类的字段)的值
Subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标签平行。
当subclass标签的定义与class标签平行的时候,需要在subclass标签中,添加extends属性,里面的值是父类的全路径名称。
子类的其它属性,像普通类一样,定义在subclass标签的内部。

2、理解如何存储
在存储数据的时候,hibernate会自动将鉴别字段的值插入到数据库中,在加载数据的时候,
hibernate便能根据这个鉴别字段正确的加载对象

3、理解何为多态查询,即hibernate能够加载数据的时候自动鉴别其真正的类型(class参数类型), instanceof 返回false 代理的原因
 //因为我们load默认是Lazy,因为Lazy所以我们看到的是Animal的代理类
 //所以通过instance是具体反映不
多态get(),支持
多态load(),设置Lazy=“false”时,支持
多态查询,支持

 

Hibernate继承映射的第二种策略:每个类对应一张表

 

1、如何映射
这种策略是使用joined-subclass标签来定义子类的。父类、子类,每个类都对应一张数据库表。
在父类对应的数据库表中,实际上会存储所有的记录,包括父类和子类的记录;在子类对应的数据库表中,
这个表只定义了子类中所特有的属性映射的字段。子类与父类,通过相同的主键值来关联。实现这种策略的时候,有如下步骤:
父类用普通的<class>标签定义即可
父类不再需要定义discriminator字段
子类用<joined-subclass>标签定义,在定义joined-subclass的时候,需要注意如下几点:
Joined-subclass标签的name属性是子类的全路径名
Joined-subclass标签需要包含一个key标签,这个标签指定了子类和父类之间是通过哪个字段来关联的。
如:<key column=”PARENT_KEY_ID”/>,这里的column,实际上就是父类的主键对应的映射字段名称。
Joined-subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),
也可以与class标签平行。 当Joined-subclass标签的定义与class标签平行的时候,需要在Joined-subclass标签中,添加extends属性,里面的值是父类的全路径名称。
子类的其它属性,像普通类一样,定义在joined-subclass标签的内部。

2、存储和多态查询参见策略一:每棵类继承树对应一张表

 

Hibernate继承映射的第三种策略:每个具体类一张表

 

1、如何映射
这种策略是使用union-subclass标签来定义子类的。每个子类对应一张表,而且这个表的信息是完备的,
即包含了所有从父类继承下来的属性映射的字段(这就是它跟joined-subclass的不同之处,joined-subclass定义的子类的表,
只包含子类特有属性映射的字段)。实现这种策略的时候,有如下步骤:
父类用普通<class>标签定义即可
子类用<union-subclass>标签定义,在定义union-subclass的时候,需要注意如下几点:
Union-subclass标签不再需要包含key标签(与joined-subclass不同)
Union-subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),
也可以与class标签平行。 当Union-subclass标签的定义与class标签平行的时候,需要在Union-subclass标签中,添加extends属性,里面的值是父类的全路径名称。
子类的其它属性,像普通类一样,定义在Union-subclass标签的内部。这个时候,虽然在union-subclass里面定义的只有子类的属性,但是因为它继承了父类,所以,
不需要定义其它的属性,在映射到数据库表的时候,依然包含了父类的所有属性的映射字段。

!!!特别注意:在保存对象的时候,id不能重复(所以不能用自增方法生成主键)

2、存储和多态查询参见策略一:每棵类继承树对应一张


集合的映射
set
list
array
map


<hibernate-mapping>
 <class name="com.bjsxt.hibernate.CollectionMapping" table="t_collection_mapping">
  <id name="id">
   <generator class="native"/>
  </id>
  <property name="name"/>
  <set name="setValues" table="t_set_values">
   <key column="set_id"/>
   <element type="string" column="set_value"/>
  </set>
  <list name="listValues" table="t_list_values">
   <key column="list_id"/>
   <list-index column="list_index"/><!-- 有序的-->
   <element type="string" column="list_value"/>
  </list>
  <array name="arrayValues" table="t_array_values">
   <key column="array_id"/>
   <list-index column="array_index"/><!-- 有序的-->
   <element type="string" column="array_value"/>
  </array>  
  <map name="mapValues" table="t_map_values">
   <key column="map_id"/>
   <map-key type="string" column="map_key"/>
   <element type="string" column="map_value"/>
  </map>
 </class>
</hibernate-mapping>


component(组件映射)
 
在hibernate中,component是某个实体对象的逻辑组成部分,它与实体的根本区别是
component是没有标识的,它是一个逻辑组成部分,完全从属于某个实体
 
这样就在传统数据库上,实现了对象的细粒度划分,层次分明,实现了面向对象的领域划分
<hibernate-mapping>
 <class name="com.bjsxt.hibernate.User" table="t_user">
  <id name="id">
   <generator class="native"/>
  </id>
  <property name="name"/>
  <component name="contact">
   <property name="address"/>
   <property name="contactTel"/>
   <property name="email"/>
   <property name="zipCode"/>
  </component>
 </class>
</hibernate-mapping>


复合主键映射

 

通常将复合主键相关属性,单独抽取出来,建立一个独立的类
  * 必须实现序列化接口
  * 必须实现equals和hashcode方法
 
  采用<composite-id>标签进行映射,其它属性采用<property>正常映射
<hibernate-mapping>
 <class name="com.bjsxt.hibernate.FiscalYearPeriod" table="t_fiscal_year_period">
  <composite-id name="fiscalYearPeriodPK">
   <key-property name="fiscalYear" column="fiscal_year"/>
   <key-property name="fiscalPeriod" column="fiscal_period"/>
  </composite-id>
  <property name="beginDate" column="begin_date"/>
  <property name="endDate" column="end_date"/>
  <property name="periodSts" column="period_sts"/>
 </class>
</hibernate-mapping>

 

 


---------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------

操作:

  理解通过session接口进行CRUD的基本操作方法。      
 
  get和load的区别?
 
  Transient对象具有的特征:
  * 不处于session缓存中,不被任何一个session实例关联
  * 在数据库中没有相应的记录
 
  persistent对象具有的特征:
  * 位于一个Session的缓存中,持久对象总是和一个session实例关联
  * 持久对象和数据库中的记录对应
  * 持久对象的变化会自动同步到数据库
 
  detached对象具有的特征:
  * 不再位于session的缓存中,不被session关联
  * detached对象是由persistent对象转变过来的,因此数据库中会存在一条记录与之对应
 


  Hibernate hql

* 注意hql的大小写敏感性

1、实体对象的查询,查询的是实体对象的数据【重要】
  * n+1问题,在默认配置的情况下,使用query.iterate()操作,有可能有n+1问题,所谓
  n+1,指在查询对象数据的时候,发出了n+1条查询语句。
  1:首先发出了一条查询语句,查询对象的id列表
  n:在迭代访问每个对象的时候,如果缓存中没有对象数据,Hibernate会在此发出一条查询语句,
     查询相应的对象
 
  *List操作与Iterate操作的区别
   list,每次都会发出一条查询语句,查询所有的对象
   iterate,首先发出一条查询语句,查询对象的id列表,然后根据缓存情况,决定
    是否发出更多的查询语句,来查询对象数据
   参见:SimpleObjectQueryTest2.java
  
2、简单属性查询 在调优上与查询缓存相关
  * 单个属性查询,返回的结果集属性的列表,其元素和属性的类型一致
  * 多个属性查询,返回的结果集是数组类型,数组的长度和查询的属性数量相关,数组中元素的类型与相应的属性类型相同
  //查询多个属性,其集合元素是对象数组
//数组元素的类型,跟实体类的属性的类型相关
List students = session.createQuery("select id, name from Student").list();
for (Iterator iter = students.iterator();iter.hasNext();) {
 Object[] obj = (Object[])iter.next();
 System.out.println(obj[0] + ", " + obj[1]);
}
 
3、条件查询【重要】                 
  * 可以拼字符串的形式传递参数
  * 可以用过?来传递参数(注意索引值是从0开始的,跟jdbc不同,jdbc是从1开始的)
  * 可以通过 :参数名 来传递参数(即命名参数方式)
  * 如果对应的参数值是多个,可以调用setParamterList()方法开传递
  * 在HQL中可以使用数据库的函数,如date_format()
  //条件查询,拼字符串
List students = session.createQuery("SELECT s.id, s.name FROM Student s WHERE s.name LIKE '%1%'").list();
 
//条件查询,使用 ? 的方式传递参数
Query query = session.createQuery("SELECT s.id, s.name FROM Student s WHERE s.name LIKE ?");
//传递参数
//参数的索引是从0开始的
//传递的字符串,无需用''单引号括起来
query.setParameter(0, "%1%");
List students = query.list();

//条件查询,使用 :参数名称 的方式传递参数
Query query = session.createQuery("SELECT s.id, s.name FROM Student s WHERE s.name LIKE :myname");
//传递参数
query.setParameter("myname", "%1%");
List students = query.list();

//条件查询,支持in,需要用setParameterList()进行参数传递
List students = session.createQuery("SELECT s.id, s.name FROM Student s WHERE s.id in(:myids)")
.setParameterList("myids", new Object[]{1, 3, 5})
.list();

List students = session.createQuery("SELECT s.id, s.name FROM Student s WHERE " + "substring(s.createTime, 1, 7) =?")
          .setParameter(0, "2007-01")
         .list();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
  List students = session.createQuery("SELECT s.id, s.name FROM Student s WHERE " +
  "s.createTime between ? and ? ")
          .setParameter(0, format.parseObject("2007-01-01"))
          .setParameter(1, format.parseObject("2007-03-01"))
         .list();


4、hibernate也支持直接使用原生sql进行查询
  参见:SqlQueryTest.java
 
5、外置的命名查询
  * 在映射文件中通过<query>标签定义hql
  * 在程序中使用session.getNameQuery()方法获得这个查询
  参见:Student.hbm.xml,NameQueryTest.java
 
6、查询过滤器
  * 定义过滤器参数
  * 在类映射文件中使用这些参数
  * 在session中启用过滤器

  参见:Student.hbm.xml,FilterQueryTest.java
 
7、对象导航查询,在HQL语句中,可以使用.的方式进行对象导航【重要】
   参见:ObjectNavQueryTest.java

8、连接查询(在对象里可以直接导航)【重要】
  * 内连接
  * 外连接(左连接/右连接) 
  内连接,从Student连接到Classes:  List students = session.createQuery("select c.name, s.name from Student s join s.classes c ").list();
   左外连接:List students = session.createQuery("select c.name, s.name from Classes c left join c.students s ").list();
右外连接:List students = session.createQuery("select c.name, s.name from Classes c right join c.students s ").list();
9、统计查询
  List students = session.createQuery("select count(*) from Student").list();
 
10、分页查询【重要】
  * 通过query接口中的setFirstResult()和setMaxResults() 进行分页

Query query = session.createQuery("from Student");
query.setFirstResult(27);
query.setMaxResults(5);
List students = query.list();
 
11、DML风格的操作(尽量) 

 


---------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------

----------------
hibernate性能调优


缓存的设置 主要是减少对数据的访问次数 包括 query session sessionfactory

 

hibernate查询缓存 不常用

配置:
  在hibernate.cfg.xml文件中加入:<property name="hibernate.cache.use_query_cache">true</property>
 
 1、针对普通属性结果集的缓存
 2、对是实体对象的结果集,只缓存id
 3、使用查询缓存,需要打开查询缓存,并且在调用list方法之前需要显示的调用query.setCacheable(true);

session一级缓存

1、一级缓存很短,和session的生命周期一致,随着session的关闭而消失
   *load/get/iterate(查询实体对象)可以使用缓存数据
2、一级缓存它缓存的是实体对象  
3、如果管理缓存,如session.clear()/session.evict()
4、如何避免一次性大批量实体数据插入内存溢出的问题?
  *先执行flush,在用clear清除缓存

 

一级缓存的管理
 /**
  * 向数据库中插入10000学生数据
  session.flush();
 session.clear();
  *
  */
 public void testCache8() {
  Session session = null;
  try {
   session = HibernateUtils.getSession();
   session.beginTransaction();
   for (int i = 0; i < 10000; i++) {
    Student student = new Student();
    student.setName("Student_" + i);
    session.save(student);
    
    //每100条数据就强制session将数据持久化
    //同时清空缓存,以避免在大量的数据下,造成内存溢出
    if ( i % 100 == 0) {
     session.flush();
     session.clear();
    }
   }
   session.getTransaction().commit();
  }catch(Exception e) {
   e.printStackTrace();
   session.getTransaction().rollback();
  }finally {
   HibernateUtils.closeSession(session);
  }  
 }

 

hibernate二级缓存

 

定义步骤:
1、打开缓存,在hibernate.cfg.xm中加入:
<property name="hibernate.cache.use_second_level_cache">true</property>

2、指定缓存策略提供商,在hibernate.cfg.xm中加入:
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

3、拷贝echcahe.xml到src下,可以针对不同的策略配置缓存

4、指定那些类使用缓存(两种方式)
  * 在hibernate.cfg.xml
  * 在映射文件中

二级缓存中存储的也是实体对象,他们都属于SessionFactory级别,
是全局的,伴随SessionFactory的生命周期存在和消亡 在WEB开发中应该是所有用户共享的 对相应的缓存类的设置要注意使用

需要了解一级缓存和二级缓存的交互模式(CacheMode)先一级后二级

 

二抓取策略

 

Hibernate抓取策略

在单端映射(many-to-one or one-to-one)情况下:

1,默认fetch的配置,也就fetch="select",如:
<many-to-one name="classes" column="classid" fetch="select" />
由于默认lazy在对象导航时,引用一个对象的数据就发一sql语句

2,设置fetch="join",如:
<many-to-one name="classes" column="classid" fetch="join" />
与select策略相比只发一条sql语句
但是会导致lazy失效

对方是集合的情况下情况下:

<set name="students" inverse="true" fetch="select">
 <key column="classid"/>
 <one-to-many class="com.wanye.Student"/>
</set>
在用到集合中对象的数据时,用一个发一条

设置fetch=“join”,参见:Classes.hbm.xml,如:
<set name="students" inverse="true" fetch="join">
发一条sql语句 带有join;
但会导致lazy失效

设置fetch=“subselect”,参见:Classes.hbm.xml,如:
<set name="students" inverse="true" fetch="subselect">

public void testFetch2() {
 Session session = null;
 try {
  session = HibernateUtils.getSession();
  List Classes = session.createQuery("select c from Classes c where c.id in(1, 2, 3)").list();
  for (Iterator iter = Classes.iterator(); iter.hasNext();) {//发出一条带有子查询的sql语句
   Classes cls = (Classes)iter.next();
   System.out.println("班级:" + cls.getName());
   for (Iterator iter1 = cls.getStudents().iterator(); iter1.hasNext();) {
    Student student = (Student)iter1.next();
    System.out.println(student.getName());
   }
  }
 }catch(Exception e) {
  e.printStackTrace();
 }finally {
  HibernateUtils.closeSession(session);
 }
}

在用到集合中对象的数据时,发出一条带有子查询的sql语句

batch策略,两种方式

针对fetch="select"配置进行优化,在类映射上加入batch,如:
<class name="com.bjsxt.hibernate.Classes" table="t_classes" batch-size="5">

在集合上设置batch
<set name="students" inverse="true" batch-size="5">

在用到集合中对象的数据时,每5个对象发出一条sql语句,防止缓存溢出。

---------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------

 

 

附:


<!DOCTYPE hibernate-configuration PUBLIC
 "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
 <session-factory>
  <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1/databasename</property>
  <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
  <property name="hibernate.connection.username">root</property>
  <property name="hibernate.connection.password">123456</property>

  <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
  <property name="hibernate.show_sql">true</property>
  <property name="hibernate.hbm2ddl.auto">update</property>
  
  <!-- 是否启用二级缓存
  
  1、打开缓存,在hibernate.cfg.xm中加入:
  <property name="hibernate.cache.use_second_level_cache">true</property>

  2、指定缓存策略提供商,在hibernate.cfg.xm中加入:
  <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

  3、拷贝echcahe.xml到src下,可以针对不同的策略配置缓存

  4、指定那些类使用缓存(两种方式)
    * 在hibernate.cfg.xml
    * 在映射文件中

  二级缓存中存储的也是实体对象,他们都属于SessionFactory级别,
  是全局的,伴随SessionFactory的生命周期存在和消亡

  需要了解一级缓存和二级缓存的交互模式(CacheMode)
  
  
  
  --> 
  <property name="hibernate.cache.use_second_level_cache">true</property>
  
  <!-- 设置缓存策略提供商 -->
  <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
  <!-- 设置查询缓存
  1、针对普通属性结果集的缓存
  2、对是实体对象的结果集,只缓存id
  3、使用查询缓存,需要打开查询缓存,并且在调用list方法之前需要显示的调用query.setCacheable(true);
  -->
  <property name="hibernate.cache.use_query_cache">true</property>
  
  <mapping resource="com/bjsxt/hibernate/Classes.hbm.xml"/>
  <mapping resource="com/bjsxt/hibernate/Student.hbm.xml"/>
  <!--  指定那些类使用缓存
  usage="read-only" 即可 主要缓存那些不常变化的,最发设置成read-only
  -->
  <class-cache class="com.bjsxt.hibernate.Student" usage="read-only"/>

 </session-factory>
</hibernate-configuration>

树的映射:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.bjsxt.hibernate.Node" table="t_node">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <property name="level"/>
        <property name="leaf"/>
        <many-to-one name="parent" column="pid"/>
        <set name="children" lazy="extra">
         <key column="pid"/>
         <one-to-many class="com.bjsxt.hibernate.Node"/>
        </set>
    </class>
</hibernate-mapping>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值