hibernate對象的三種狀態:
(一) 瞬時(臨時)狀態: 對象被創建時的狀態,數據庫里面沒有與之對應的記錄!
(二) 持久狀態: 處于session的管理中,并且數據庫里面存在與之對應的記錄!
(三) 游離狀態: 對象不處于session的管理中,但是數據庫里面存在與之對應的記錄!
對象與session產生關系的時機:
1、save()或者saveorupdate();
2、get()或者load();
清空緩存:
1、clear();//清空所有加載的實例
2、evict(實例);//從緩存里面移除這個實例——效果同上,需要指定實例,對象
三種狀態的轉換過程:
hibernate涉及的臟檢查:
當事務提交時(commit),hibernate會檢查session中處在持久狀態的對象, 判斷與數據庫是否一致,不一致則會將緩存里面的數據更新掉數據庫里面的數據!
那么session什么時候刷新緩存:
1、執行commit方法時 //執行臟檢查
2、session.flush(); //不會提交事務執行臟檢查
更新數據的方法:
update(對象):
saveOrUpdate(對象):
1、通過id查詢主鍵,存在就更新,不存在就新增!
2、當mapping配置文件的generator節點的class屬性不為assigned時,造成只有update沒select時,更改class為assigned可以解決!
3、不會發起查詢,直接更新 merge(對象):合并,先查詢,與緩存里面的數據比較一樣時不做任何操作,不一樣時,再更新或者插入!效率更高!
saveOrUpdate(對象)與merge(對象)方法:
1、主鍵生成策略:assigned
操作一樣!
2、主鍵生成策略:sequence,動態更新(dynamic-update="true")策略
saveOrUpdate(對象)只更新
merge(對象)先發起一條查詢語句,在發起更新或者插入語句

1 public static boolean addDept(){ 2 boolean flag=false; 3 Configuration conf=null; 4 SessionFactory factory=null; 5 Session session=null; 6 Transaction trans=null; 7 try { 8 //讀取配置文件 9 //指定配置文件 10 //conf=new Configuration().configure("xxx.cfg.xml"); 11 conf=new Configuration().configure(); 12 //創建sessionfactory 13 factory=conf.buildSessionFactory(); 14 //打開會話 15 session=factory.openSession(); 16 //開啟事務 17 trans=session.beginTransaction(); 18 19 Dept dept=(Dept)session.get(Dept.class, 8); 20 //當設置了gennerator為sequence時,不給參數是以指定sequence填值 21 //dept.setDeptno(10); 22 dept.setDeptname("test測試部"); 23 dept.setLoc("xz"); 24 //持久化 25 //session.save(dept); 26 //session.delete(dept); 27 //Dept dp=(Dept)session.get(Dept.class, 1);//沒有數據,返回空值 28 //System.out.println(dp.getDeptname()); 29 //延遲加載 30 //Dept dp=(Dept)session.load(Dept.class, 5);//沒有數據,報異常 31 //保存或更新 32 session.saveOrUpdate(dept); 33 //合并 34 //session.merge(dept); 35 //提交事務 36 trans.commit(); 37 38 flag=true; 39 } catch (Exception e) { 40 e.printStackTrace(); 41 trans.rollback(); 42 }finally{ 43 if(session!=null){ 44 session.close(); 45 46 } 47 }
補充:
配置文件節點以及屬性總結:
hbm映射配置文件:
1、通常情況下,一個mapping只寫一個class節點,因此一個mapping文件對應一個(類與數據庫表);
class節點:
name屬性:對象的路徑,這里指大路徑、對象名!
也可以在<hibernate-mapping>節點pakage屬性指定包路徑,只寫對象名
table屬性:指定數據庫表名,可以忽略大小寫
dynamic-update屬性:指定是否動態更新,這個屬性在saveOrupdate/merge方法執行時,尤為重要!
id節點:
主鍵配置:oid:object 對象的編號
name:實體類里面屬性的名稱;
column:數據庫表里面的列:不寫表示和實體類屬性名一致!
generator節點:
生成器:
主鍵的生成策略:通過class設定:
assign:由程序指定主鍵值!
foreign:由外鍵生成!
identity:標識列!sqlserver支持!
sequence:序列,oracle,db2,!
increment:自增,mysql!
native:由數據庫自己決定以上哪種方式!
param節點:
指定索引名
property節點:
type:屬性的類型,可以是java類型(要寫完全限定名),也可以是hibernate類型!可以省略
示例:

1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5 <!-- 類和表 屬性和字段的關系 --> 6 <!-- <hibernate-mapping package="cn.cy.Hibernate.entity"> --> 7 <hibernate-mapping> 8 <!-- 與關鍵字沖突 ”~~“解決 --> 9 <!-- 通常一個mapping只寫一個class節點 --> 10 <!-- 類名和表名可以不一樣! --> 11 <class name="cn.cy.Hibernate.entity.Dept" table="dept" dynamic-update="true"> 12 <!-- <class name="Dept" table="dept"> --> 13 <!-- 當數據庫里面的列明與java屬性一致時,我們可以省略colnumn --> 14 <!-- 15 主鍵配置:oid:object 對象的編號 16 name:實體類里面屬性的名稱; 17 column:數據庫表里面的列:不寫表示和實體類屬性名一致! 18 --> 19 <id name="deptno" column="deptno"> 20 <!-- 21 生成器: 22 主鍵的生成策略:通過class設定: 23 assign:由程序指定主鍵值! 24 foreign:由外鍵生成! 25 identity:標識列!sqlserver支持! 26 sequence:序列,oracle,db2,! 27 increment:自增,mysql! 28 native:由數據庫自己決定以上哪種方式! 29 --> 30 <generator class="sequence"> 31 <!-- 指定序列名 --> 32 <param name="sequence">seq_index</param> 33 </generator> 34 </id> 35 <!-- 36 性質: 37 type:屬性的類型,可以是java類型(要寫完全限定名),也可以是hibernate類型!可以省略 38 column:可以單獨寫成子節點! 39 --> 40 <property name="deptname" column="deptname" type="java.lang.String" /> 41 <property name="loc" column="loc" type="java.lang.String"/> 42 </class> 43 </hibernate-mapping>
cfg指定數據庫配置文件:

1 <!DOCTYPE hibernate-configuration PUBLIC 2 "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 4 5 <hibernate-configuration> 6 <session-factory> 7 8 <!-- 指定oracle對應得dialect --> 9 <property name="dialect"> 10 org.hibernate.dialect.Oracle10gDialect 11 </property> 12 <!-- 數據庫jdbc驅動 --> 13 <property name="connection.driver_class"> 14 oracle.jdbc.driver.OracleDriver 15 </property> 16 17 <!-- 數據庫url --> 18 <property name="connection.url"> 19 jdbc:oracle:thin:@localhost:1521:XE 20 </property> 21 22 <!-- 用戶名 --> 23 <property name="connection.username">user_admin</property> 24 <!-- 用戶密碼 --> 25 <property name="connection.password">abc123</property> 26 27 <!-- session范圍和上下文 --> 28 <property name="current_session_context_class">thread</property> 29 <!-- 是否在運行期間生成的SQL輸出到日志以供調試 --> 30 <property name="show_sql">true</property> 31 <!-- 是否格式化sql --> 32 <property name="format_sql">true</property> 33 <!-- 映射 --> 34 <mapping resource="cn/cy/Hibernate/entity/Dept.hbm.xml" /> 35 </session-factory> 36 </hibernate-configuration>
我可以自己命名cfg.xml文件嗎?
答案是可以的:
1 //讀取指定配置 2 conf=new Configuration().configure("xxx.cfg.xml"); 3 //讀取默認配置hibernate.cfg.xml 4 conf=new Configuration().configure();
文章列表