1. 程式人生 > >hibernate三種物件狀態以及載入策略和併發控制

hibernate三種物件狀態以及載入策略和併發控制

對於物件狀態大家先看這張圖

當你的session會話去資料庫中get一個物件也就代表去資料庫裡面查了一次,獲得到的物件也就是資料庫中的資料,當你用get獲取的物件狀態為持久態,也就是你對這個物件進行刪除或者修改的話資料庫中對應的資料也會相應的改變
持久狀態的物件也會根據不同的操作變成臨時狀態和遊離狀態,臨時狀態的物件當你對它進行操作是不會影響到資料庫中的資料,
遊離狀態的物件也能通過update變成持久狀態,而遊離狀態情況下的物件你對它進行操作,它可能會影響到資料庫中的資料,也有可能不會影響

 

 稍微列舉個程式碼幫助大家理解

  public static void main(String[] args) {
/**
 * 使用幫助類來獲取session 會話
 */
        Session session = SessionFactoryUtils.openSession();
        Transaction transaction = session.beginTransaction();
        //持久態物件
       Student  student=session.get(Student.class,1);
       session.close();
       //現在的student就是遊離態物件
        session=SessionFactoryUtils.openSession();
        student.setSname("花花");
        session.update(student);
        //現在的student又成為了持久態物件
        student.setSname("花花2");

        session.delete(student);
        //臨時態物件
        student.setSname("花花2");
        //然後由變為持久態物件
        session.save(student);

        transaction.commit();
        /**
         * 使用幫助類來關閉會話
         */
        SessionFactoryUtils.closeSession();


    }

  1、hibernate是通過管理物件來操作資料,這裡物件指的是持久化物件。
  2、hibernate中的三種狀態的物件是可以相互轉換的,通常編碼時只關注持久
  化物件。關注get、save、update方法所操作後的物件

 

Hibernate物件的載入機制
這個理論相對簡單,也就是當你用session.get獲取的物件載入機制為立即載入,也就是說當你用了這個方法它就會立馬載入這個物件    而你用session.load載入獲取到的物件為延遲物件,這個物件只有當你要使用它的時候它才會載入,當你只用load這個方法載入的物件一個代理物件,並不是一個能直接使用的物件

 

 

hibernate的併發控制就是多個使用者同時獲取到某一條資料,進行不同的處理,當a修改的時候成功了,但是b修改的時候將a修改的內容覆蓋了,這個時候資料就沒有了資料的準確性,這是不行的所以面對這種問題hibernate有對應的解決辦法,接下來貼程式碼

 

首先在資料庫加一個欄位型別為int  然後在實體類中加上 再在實體類對映檔案中加這一句、

<version name="version" type="java.lang.Integer" column="version"></version>
<!--name是實體類的全路徑限定名   table 是資料庫名字-->
	<class name="com.zking.two.Student" table="t_hibernate_student">
		<!--name為實體類屬性   type為實體類的資料型別   column 資料庫列名-->
		<id name="sid" type="java.lang.Integer" column="sid">
			<generator class="increment" />
		</id>
		<version name="version" type="java.lang.Integer" column="version"></version>
        <!--屬性-->
		<property name="sname" type="java.lang.String"
			column="sname">
		</property>
	</class>

這裡用main方法來模擬了一下這個兩個使用者同時獲取到同一條資料的情況 

 public static void main(String[] args) {
Student student=new Student();
student.setSid(1);
student.setSname("名字");
student.setVersion(1);
edit(student);
    }


    public static void  edit(Student s){
        //幫助類獲取session會話
        Session session = SessionFactoryUtils.openSession();
        Transaction transaction = session.beginTransaction();
          session.update(s);
        transaction.commit();
        SessionFactoryUtils.closeSession();
    }

資料庫的變成了這個 

然後再執行這個模擬又一個使用者的修改

    public static void main(String[] args) {
Student student=new Student();
student.setSid(1);
student.setSname("名字dad");
student.setVersion(1);
edit(student);
    }

然後控制檯會報錯Error during managed flush [Row was updated or deleted by another transaction這就 保證了資料的準確性