继承映射:
一个类继承体系一张表
每个子类一张表
混合使用“一个类继承体系一张表”和“每个子类一张表”
每个具体类一张表
1.一个类继承体系一张表
公司一般的员工 Emp实体类
public class Emp
{
private int empId; //员工编号
private String empName; //员工姓名
//省略get和set方法
}
//Emp中包含了公司员工的一些基本信息
公司销售人员Saler实体类
public class Saler extends Emp
{
private String product; //销售的产品
//省略get和set方法
}
公司技术人员Skiller实体类
public class Skiller extends Emp
{
String exp; //技术经验
//省略get和set方法
}
Emp.hbm.xml的配置
<hibernate-mapping package="entity2">
discriminator-value是设置默认鉴别器的值,普通员工为0,技术人员为1,销售人员为2
<class name="entity2.Emp"table="t_emp2" discriminator-value="0">
<id name="empId">
<generator class="native"/>
</id>
discriminator是鉴别器,用来在同一个表中区别员工的类型
<discriminator column="emp_type" type="int"/>
<property name="empName"/>
Subclass表示是子类
<subclass name="Skiller"discriminator-value="1">
<property name="exp"/>
</subclass>
<subclass name="Saler"discriminator-value="2">
<property name="product"/>
</subclass>
</class>
</hibernate-mapping>
2. 每个子类一张表
公司员工的三个实体类不变,需要改变的是Emp.hbm.xml文件的配置
<hibernate-mapping package="entity2">
<class name="entity2.Emp" table="t_emp2" >
<id name="empId">
<generator class="native"/>
</id>
<property name="empName"/>
每一个子类一张表,所以要为实体类指明table,和表中的主键key,使用的是joined-subclass标签,这里就不需要鉴别器了
<joined-subclass name="Skiller" table="skiller">
<key column="employee_id"/>
<property name="exp"/>
</joined-subclass>
<joined-subclass name="Sales" table="sales">
<keycolumn="employee_id"/>
<propertyname="product"/>
</joined-subclass>
</class>
</hibernate-mapping>
3.混合使用“一个类继承体系一张表”和“每个子类一张表”
实体类依然不变,配置Emp.hbm.xml文件
<hibernate-mapping package="entity2">
混合使用时,需要加上鉴别器
<class name="Emp" table="t_emp"discriminator-value="0" >
<id name="empid">
<generator class="native"/>
</id>
<discriminator column=“emp_type“type=“int”/>
<property name="empname"/>
<subclass name="Skiller"discriminator-value=“1" >
<property name="exp"/>
</subclass>
<subclass name=”Sales”" discriminator-value=“2" >
<join table="sales">
<key column="employee_id"/>
<property name="product"/>
</join>
</subclass>
</class>
</hibernate-mapping>
4.每个具体类一张表
实体类依然不变,配置Emp.hbm.xml文件
<class name="Emp" table=”t_emp”>
<id name="empid">
<generator class="native"/>
</id>
<property name="empname"/>
<union-subclass name="Skiller"table="skiller">
<property name="exp"/>
</union-subclass>
<union-subclass name="Sales"table="sales">
<property name="product"/>
</union-subclass>
</class>
懒加载
1.session.load懒加载。
2.one-to-one(元素)懒加载:
必需同时满足下面三个条件时才能实现懒加载
(主表不能有constrained=true,所以主表没有懒加载)
lazy!=false 2)constrained=true3)fetch=select
3.one-to-many (元素)懒加载:1)lazy!=false 2)fetch=select
4.many-to-one (元素) :1)lazy!=false 2)fetch=select
5.many-to-many (元素) :1)lazy!=false 2)fetch=select
6.能够懒加载的对象都是被改写过的代理对象,当相关联的session没有关闭时,访问这些懒加载对象(代理对象)的属性(getId和getClass除外)hibernate会初始化这些代理,或用Hibernate.initialize(proxy)来初始化代理对象;当相关联的session关闭后,再访问懒加载的对象将出现异常
总结下:如果使用fetch=join既是使用级联查询,此时懒加载lazy设置为proxy代理也是没有用的,都会马上查询出来。当设置了懒加载后,可是又想在session关闭后去得到数据,就可以在session关闭前调用Hibernate.initialize(proxy)中的proxy为代理对象
缓存
缓存的作用主要用来提高性能,可以简单的理解成一个Map;使用缓存涉及到三个操作:把数据放入缓存、从缓存中获取数据、删除缓存中的无效数据。
二级缓存步骤:
1、导入缓存使用的接口JAR包:
路径:lib\optional\ehcache\ehcache-core-2.4.3.jar
2、添加缓存配置文件
路径:project\etc\ehcache.xml
3、配置hibernate.cfg.xml文件
Hibernate.cfg.xml文件的配置
<!-- 设置打开二级缓存 -->
<propertyname="hibernate.cache.use_second_level_cache">true</property>
<!-- 设置指定二级缓存的实现接口 -->
<propertyname="hibernate.cache.region.factory_class">org.hibernate.cache.EhCacheRegionFactory</property>
<!-- 设置二级缓存所使用的配置文件 -->
<propertyname="net.sf.ehcache.configurationResourceName">/ehcache.xml</property>
<!-- 设置使用QUERY查询也实现二级缓存 -->
<propertyname="hibernate.cache.use_query_cache">true</property>
<!– 必须在导入资源映射文件后再设置有使用二级缓存的实体类 à
<class-cache usage="read-only"class="entity.Emp"/>
Query查询也实现二级缓存除了在hibernate.cfg.xml文件配置了意外还需要在查询的代码中加上q.setCacheable(true);才会生效
打开二级缓存查询功能:
代码中:
Query q=s.createQuery();
q.setCacheable(true);