Hibernate的繼承映射、懶加載、緩存
繼承映射:
一個類繼承體系一張表
每個子類一張表
混合使用“一個類繼承體系一張表”和“每個子類一張表”
每個具體類一張表
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);