<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [Nhibernate] Inverse

      什么是inverse?

       

      通過inverse的設置來決定是由哪端來維護對象之間的關系的 

       

      雙向many-to-one

      Employee.hbm.xml

      <?xml version="1.0" encoding="utf-8" ?>
      <hibernate-mapping
        
      xmlns="urn:nhibernate-mapping-2.2"
        namespace
      ="ZiyeNhi.Entities"
        assembly
      ="ZiyeNhi.Entities">

        <class name="Employee" table="Emp">
          <id name="EmpId" column="EmpId" type="int">
            <generator class="identity">
            </generator>
          </id>

          <property name="EmpName" column="EmpName" type="string" length="50"></property>

          <many-to-one name="Department" class="Department" column="DepId" lazy="proxy"></many-to-one>
        </class>

      </hibernate-mapping>

       

       Department.hbm.xml

      <?xml version="1.0" encoding="utf-8" ?>
      <hibernate-mapping
        
      xmlns="urn:nhibernate-mapping-2.2"
        namespace
      ="ZiyeNhi.Entities"
        assembly
      ="ZiyeNhi.Entities">

        <class name="Department" table="Dep">
          <id name="DepId" column="DepId" type="int">
            <generator class="identity">
            </generator>
          </id>
          <property name="DepName" column="DepName" type="string" length="50"></property>

          <!--<one-to-many>-->
          <set name="Employees" table="Emp" inverse="true" lazy="true" ><!--cascade-->
            <key column="DepId" ></key>
            <one-to-many class="Employee"/>
          </set>
        </class>

      </hibernate-mapping>

       

       

      一般來說我們都習慣

      one端(department) inverse="true";(對應上面的department.hbm.xml)

      many端(Employee) inverse="false";(對應上面的employee.hbm.xml)

      這樣我們就可以用department屬性來維護二者的關系

       

      [Test]
              public void SaveDepartment()
              {
                  using (ISession session = this.sessionFactory.OpenSession())
                  {
                      var emp1 = new Employee() { EmpName = "xr" };
                      var emp2 = new Employee() { EmpName = "wxr" };
                      var department = new Department() { DepName = "QQ" };
                      emp1.Department = department;
                      emp2.Department = department;
                      ITransaction transaction = session.BeginTransaction();
                      try
                      {
                          session.Save(department);
                          session.Save(emp1);
                          session.Save(emp2); 
                          transaction.Commit(); 
                      }
                      catch (Exception ex)
                      {
                          transaction.Rollback();
                          throw ex;
                      }
                  }
              }

       

      測試結果 

       

       

       生成了3條insert語句一條是插入department,另外兩條是插入Employee的 他們二者的關系是由Employee對象的department屬性來維護的

       為什么我們一般都要這么做呢

       第一:如果我們通過Department.Employee.add(emp對象) 這種關系來維護的話,那么當前部門下有N個employee lazy=“true”的時候 是不是很浪費資源?

       第二:數據模型中 一般情況下 對象關系都是由子表體現出來(看department表中 只有DepId,DepName,而在employee表中可以看到外鍵depId).那么我們在對象模型中也推薦子對象來維護關系.

       第三:期待補充.

       

       Inverse屬性在many-to-one中的應用

       1.經測試。如果兩端都設置為inverse="true"那么兩端都不會維護關系

       2.兩端都為inverse="false"的情況下

       3.one端為false,many端為true

       4.one端為true,many端為false

       

       圍繞2 3 4 來說

       兩端都為false

       

      [Test]
              public void SaveDepartment()
              {
                  using (ISession session = this.sessionFactory.OpenSession())
                  {
                      var emp1 = new Employee() { EmpName = "xr" };
                      var emp2 = new Employee() { EmpName = "wxr" };
                      var department = new Department() { DepName = "QQ" };
                      //以下兩句為A組合 Employee對象來維護關系
                      emp1.Department = department;
                      emp2.Department = department;
                      //以下兩句為B組合 Department對象來維護關系
                      
      //department.Employees.Add(emp1);
                      
      //department.Employees.Add(emp2);
                      ITransaction transaction = session.BeginTransaction();
                      try
                      {
                          session.Save(department);
                          session.Save(emp1);
                          session.Save(emp2);
                          transaction.Commit(); 
                      }
                      catch (Exception ex)
                      {
                          transaction.Rollback();
                          throw ex;
                      }
                  }
              }

       測試結果

       


      代碼中維持關系的是employee對象 或者說是employee對象下的Department屬性

      生成了3條語句 (3條insert 先插入department 然后通過插入department返回的ID 來插入2條employee)

       

      將A組合切換B組合

      [Test]
              public void SaveDepartment()
              {
                  using (ISession session = this.sessionFactory.OpenSession())
                  {
                      var emp1 = new Employee() { EmpName = "xr" };
                      var emp2 = new Employee() { EmpName = "wxr" };
                      var department = new Department() { DepName = "QQ" };
                      //以下兩句為A組合 Employee對象來維護關系
                      
      //emp1.Department = department;
                      
      //emp2.Department = department;
                      
      //以下兩句為B組合 Department對象來維護關系
                      department.Employees.Add(emp1);
                      department.Employees.Add(emp2);
                      ITransaction transaction = session.BeginTransaction();
                      try
                      {
                          session.Save(department);
                          session.Save(emp1);
                          session.Save(emp2); 
                          transaction.Commit(); 
                      }
                      catch (Exception ex)
                      {
                          transaction.Rollback();
                          throw ex;
                      }
                  }
              }

       

      測試結果


       

       

      代碼中維持關系的是Department對象 或者說是Department對象下的Employee屬性

       

      生成了5條語句 (三條insert語句 然后在把后來插入的兩條insertEmp給update) [暫且不考慮效率]

       

      上面2個測試的例子說明 兩端都為false的情況下 隨意一端來維持關系都是可以的。

      但是用department對象來關聯要生成5條語句效率不敢恭維,而且department.employees.add 在lazy="true"的時候也很嚇人(上面有提到過)

      結論1:盡量不要用department對象 也就是帶有集合屬性的一端去維持關系。

       

       

       

       

      one端為false,many端為true

      one端

       

      <set name="Employees" table="Emp" inverse="false" lazy="true" >
            <key column="DepId" ></key>
            <one-to-many class="Employee"/>
          </set>

       

       many端

       

      <many-to-one name="Department" class="Department" column="DepId" lazy="proxy"></many-to-one>

       大家知道many端默認為inverse="false",怎么才能模擬出inverse="true".

      <many-to-one name="Department" class="Department" column="DepId" insert="false" update="false" lazy="proxy"></many-to-one>

       

      <many-to-one/>和<one-to-one/>沒有inverse屬性,可以用insert和update屬性模擬出inverse="true",

       

      加上insert="false" ,update="false" 兩個默認都為true。

      這樣就模擬出了inverse="true"了

      就是說 many端 不參與 關系維護,而one端參與關系維護

      測試代碼利用A組合

      [Test]
              public void SaveDepartment()
              {
                  using (ISession session = this.sessionFactory.OpenSession())
                  {
                      var emp1 = new Employee() { EmpName = "xr" };
                      var emp2 = new Employee() { EmpName = "wxr" };
                      var department = new Department() { DepName = "QQ" };
                      //以下兩句為A組合 Employee對象來維護關系
                      emp1.Department = department;
                      emp2.Department = department;
                      //以下兩句為B組合 Department對象來維護關系
                      
      //department.Employees.Add(emp1);
                      
      //department.Employees.Add(emp2);
                      ITransaction transaction = session.BeginTransaction();
                      try
                      {
                          session.Save(department);
                          session.Save(emp1);
                          session.Save(emp2); 
                          transaction.Commit(); 
                      }
                      catch (Exception ex)
                      {
                          transaction.Rollback();
                          throw ex;
                      }
                  }
              }

       測試結果


       

       

       

      細心的同學會發現 這里的2 3條insert語句它們的Department外鍵并沒有插入

      說明他們的關系沒有維護成功。


       

      在來A組合換成B組合

       [Test]
              public void SaveDepartment()
              {
                  using (ISession session = this.sessionFactory.OpenSession())
                  {
                      var emp1 = new Employee() { EmpName = "xr" };
                      var emp2 = new Employee() { EmpName = "wxr" };
                      var department = new Department() { DepName = "QQ" };
                      //以下兩句為A組合 Employee對象來維護關系
                      
      //emp1.Department = department;
                      
      //emp2.Department = department;
                      
      //以下兩句為B組合 Department對象來維護關系
                      department.Employees.Add(emp1);
                      department.Employees.Add(emp2);
                      ITransaction transaction = session.BeginTransaction();
                      try
                      {
                          session.Save(department);
                          session.Save(emp1);
                          session.Save(emp2); 
                          transaction.Commit(); 
                      }
                      catch (Exception ex)
                      {
                          transaction.Rollback();
                          throw ex;
                      }
                  }
              }

      測試結果

      同樣生成了5條SQL 與上面兩端為 false的B組測試情況一樣

       

      也就驗證了 上面的話

      就是說 many(Employee)端 不參與 關系維護,而one(Department)端參與關系維護

       

       

      one端為true,many端為false

      這個不用測了吧?跟開篇的例子一樣的。如果有興趣的同學們可以自己測試一下另一種情況。

       

      到底在哪端設置inverse呢?

      大部分我們都在沒有集合的那一端設置inverse="false",如果用集合那端來維持關系。比如department.employees.add(上面提到過 lazy="true")

      怎么去記這個東西。其實我也被這個東西困擾了20多個小時了。

      總結一下:

       

      <!-- 第一種從“對象”的角度去記
          當前xml文件里的class是employee對象,設置當前employee對象里的department屬性inverse="false"
          那么當前employee就要參與關系維護
          那么我們save的時候 就需要用Employee對象去維護關系 所有就有了
             var emp1 = new Employee() { EmpName = "xr" };
             var department = new Department() { DepName = "QQ" };
             emp1.Department = department;    ->employee的對象emp1來維護關系.
             ....
             session.Save(department);
             session.Save(emp1);
          
               第二種從“屬性”的角度去記
          inverse="false" 這個是在Employee對象里Department的屬性中標示的
          那么Department屬性就要參與關系維護
          那么我們save的時候就需要用employee對象的Department屬性去維護關系 所有就有以下代碼
             var emp1 = new Employee() { EmpName = "xr" };
             var department = new Department() { DepName = "QQ" };
             emp1.Department = department;    ->employee的對象emp1中的department屬性維護關系.
             ....
             session.Save(department);
             session.Save(emp1);
             
             PS:綜上兩點所述:如果在employee的配置文件里設置Department屬性為false
                那么要么就是employee對象去維護,要么就是employee對象下的Department屬性去維護。
             
               第三種也是從第二種延伸的
           inverse="false" 字面理解就是"鏡像"為false
           那么這個對象就是真實的對象.那么我們設置它的屬性是有效的
           維護關系的時候就設置department屬性即可
             emp1.Department = department; 這里就設置了department屬性 因為這個屬性是沒有鏡像 那么他就是真實的
              
             PS:因為當前employee 也就是many端的inverse="false" 
                那么department就是one端的inverse="true"
                用第三種來理解就是department端里的employee屬性是有鏡像的
                鏡像是什么意思呢?
                department 下面有N個Employee對象(這里的employee對象是真實的)
                如果設置inverse="true"那么這個employee對象就不是真實的了
                既然不真實 設置它的屬性 就是沒用的.
                那么就不能用department.employee 來維護關系(當前employee對象是鏡像)
                那就得用department屬性來維護關系了 
          
      -->

       


      對于雙向one-to-many或者many-to-one
      inverse="true"被指定于集合端(one-to-many/many-to-many),很少被指定于引用端(many-to-one/one-to-one/any)(默認為inverse="false")。

      如果集合端為<list>或<map>,并且子表中的index或key字段沒有被作為普通屬性映射,則必須讓集合有效而在引用端使用inverse,其余一切情況,均強烈建議在集合上使用inverse

      對于兩端都是集合的雙向many-to-many
      有一端的集合可以任意地使用<set>, <bag>, <idbag>, <list>, <map>元素,而另外一段的集合則只能使用<set>或<bag>
      如果有一段是<idbag>, <list>或<map>,則inverse屬性必須加載另外一端的<set>或<bag>上
      如果兩端都為<set>或<bag>,則任意。但出于優化目的,盡量加在概率上長度比較大的集合端上

      (比如,一個用戶的角色可能只有幾種,但是一種角色可能被授予很多用戶,請在Role對象的Users集合上添加inverse="true")

       

      全文完。希望看完的同學能夠掌握inverse這個怪物.


       

       

       

       

       

       

       

      posted @ 2012-02-15 00:18  子夜.  Views(2791)  Comments(2)    收藏  舉報
      主站蜘蛛池模板: 国产精品美女乱子伦高| 欧洲美女黑人粗性暴交视频| 激情综合色区网激情五月| 波多野结衣美乳人妻hd电影欧美| 国产精品一区二区不卡91| 亚洲国产欧美一区二区好看电影| 日夜啪啪一区二区三区| 久久青青草原精品国产app| 影音先锋大黄瓜视频| 国产永久免费高清在线观看| 亚洲欧洲av一区二区久久| 国产欧美另类久久久精品丝瓜| 一亚洲一区二区中文字幕| 国产在线永久视频| 亚洲高清国产成人精品久久| 日韩精品中文字幕人妻| 国产精品自在拍首页视频8| 精品一区精品二区制服| 国产精品福利自产拍久久| 国产一区二区av天堂热| 四虎永久在线精品免费播放| 久久国内精品一国内精品| 国产成人亚洲综合图区| 亚洲精品国产免费av| 国产精品小视频一区二页| 熟女一区| 久久久精品94久久精品| 开阳县| 国产精品天干天干综合网| 国产又色又爽又黄的视频在线| 日韩不卡1卡2卡三卡网站| 四川丰满少妇无套内谢| 无码人妻精品一区二区三区蜜桃| 国产精品老熟女露脸视频| 国产亚洲一区二区三区成人| 麻豆人妻| 日韩中文字幕v亚洲中文字幕 | 日本韩无专砖码高清观看| 欧美国产日产一区二区| 国产精品自拍中文字幕| 婷婷丁香五月亚洲中文字幕|