在mysql里建立2個表
          CREATE TABLE `customers` (
            `id` int(11) NOT NULL auto_increment,
            `name` char(20) character set latin1 default NULL,
            PRIMARY KEY  (`id`)
          ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

          CREATE TABLE `orders` (
            `id` int(11) NOT NULL auto_increment,
            `customer_id` int(50) NOT NULL default '0',
            `order_number` int(50) default NULL,
            PRIMARY KEY  (`id`),
            KEY `fk_customer_id` (`customer_id`),
            CONSTRAINT `fk_customer_id` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`id`)
          ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

          然后自動生成持久化類,在customers.hbm.xml一方設(shè)置與orders的外鍵customer_id的一對多關(guān)聯(lián),其中聯(lián)級操作為save-update,inverse="true"為表示hibernate不由customers對象的狀態(tài)變化來更新數(shù)據(jù)庫,僅按照Orders對象狀態(tài)變化來更新數(shù)據(jù)庫。由此來優(yōu)化hibernate的性能。
           <set name="orderses" inverse="true" cascade="save-update">
                      <key>
                          <column name="customer_id" unique="true" />
                      </key>
                      <one-to-many class="com.yourcompany.model.Orders" />
                  </set>

          在orders.hbm.xml設(shè)置多對一關(guān)聯(lián),其中業(yè)務(wù)邏輯決定了order是由customer來下決定的,所以必須not-null="true" ,聯(lián)級操作根據(jù)實際情況而定,本例子的邏輯關(guān)系里面,應(yīng)該不需要在many-to-one一方設(shè)置save-update聯(lián)級操作,因為增加orders并不需要增加customer。在目前的情況里如果設(shè)置了save-update,增加orders記錄的時候hibernate就會把原來已存在的customers記錄設(shè)置為null。這是不對的。
                  <many-to-one name="customers" class="com.yourcompany.model.Customers" fetch="select" >
                      <column name="customer_id" not-null="true" unique="true" />
                  </many-to-one>

          在AddCustomerAction里保存一個customers,之后可以看到當(dāng)保存一個customers的同時,orders也同時保存了該customers的id。
            String strname = addCustomerForm.getString("name");
            Customers customers = new  Customers();
            customers.setName(strname);
            Orders orders=new Orders();
            orders.setCustomers(customers);
            customers.getOrderses().add(orders);
            customersDAO.save(customers);

          其中
            orders.setCustomers(customers);
            customers.getOrderses().add(orders);
          在建立兩個對象的雙向關(guān)聯(lián)時,應(yīng)該同時修改關(guān)聯(lián)兩端的對象的相應(yīng)屬性,這樣可提高業(yè)務(wù)邏輯的獨立性。
          比如:解除雙向關(guān)聯(lián)時:
            customers.getOrderses().remove(orders);
            orders.setCustomers(null);

          在AddOrdersAction里,由表單傳入customers的ID值和新增加的order_number值。ordersDAO.attachDirty(orders);為Myeclipse里生成的DAO,其調(diào)用的是HibernateTemplate的getHibernateTemplate().saveOrUpdate(instance);方法。
            Integer strcustomers= Integer.valueOf(addOrdersForm.getString("customers"));
            Integer strorder_number= Integer.valueOf(addOrdersForm.getString("order_number"));
            Orders orders = new  Orders(); 
            Customers customers = new  Customers();
            customers.setId(strcustomers);
            orders.setCustomers(customers);
            orders.setOrderNumber(strorder_number);
            ordersDAO.attachDirty(orders);

          在這里的持久化對象的生命周期里,當(dāng)Customers customers = new  Customers();時,Customers還屬于臨時狀態(tài),而到了sessionv.save(customers);的時候Customers由臨時狀態(tài)轉(zhuǎn)變?yōu)槌志没癄顟B(tài)。臨時狀態(tài)時不處于Session緩存中,轉(zhuǎn)化為持久化狀態(tài)后Customers就加入到了Session緩存中,在此Customers customers 2=(Customers)session.load(Customer.class,id);、Customers customers 3=(Customers)session.load(Customer.class,id);、均是在持久化狀態(tài)。而直到session.close();就表明Customers退出了Session緩存,由持久化狀態(tài)轉(zhuǎn)變?yōu)橛坞x狀態(tài)。System.out.println(customers 3.getname());也是處于游離狀態(tài)。到最后c2=null;c3=null;Customers生命周期結(jié)束。

          Session有三種檢索方法:load()、get()、find(),檢索策略有類級別的:立即檢索、延遲檢索,關(guān)聯(lián)級別的立即檢索、延遲檢索、迫切左外連接檢索。在類級別中應(yīng)該有線考慮使用立即檢索。不管hbm文件里lazy屬性是true還是false,Session的get()、find()方法總是使用立即檢索策略。

          在一對多關(guān)聯(lián)級別中,對于<set>元素不能隨意使用立即檢索策略,盡量使用延遲檢索策略。應(yīng)用程序如果新聞訪問游離狀態(tài)的代理類實例,必須保證它在持久化狀態(tài)時已經(jīng)被初始化,不然會拋出異常

          對于多對一或一對一關(guān)聯(lián),應(yīng)該優(yōu)先考慮使用外連接檢索策略,因為它比立即檢索策略使用的select語句數(shù)目少。在默認(rèn)情況下<many-to-one>元素的outer-join屬性為auto,<class>元素的lazy屬性為false,因此默認(rèn)使用迫切外連接檢索策略。迫切外連接檢索策略受數(shù)據(jù)庫表的大小和連接影響,如果select語句中的外連接表的數(shù)目太多,會影響檢索性能,可以通過Hibernate配置文件中的hibernate.max_fetch_depth來達(dá)到優(yōu)化。hibernate.max_fetch_depth取決數(shù)據(jù)庫連接性能及表大小。

          posted on 2007-08-27 10:15 lzj520 閱讀(735) 評論(0)  編輯  收藏 所屬分類: 個人學(xué)習(xí)日記Hibernate
          主站蜘蛛池模板: 临澧县| 东阿县| 合水县| 丰城市| 普兰县| 阿尔山市| 霍邱县| 东源县| 灵宝市| 美姑县| 临澧县| 东港市| 常州市| 浦东新区| 霸州市| 桃源县| 讷河市| 巩留县| 榆林市| 克山县| 静宁县| 莒南县| 个旧市| 丹东市| 宜丰县| 井研县| 阿瓦提县| 五河县| 三亚市| 绥德县| 灵石县| 新昌县| 济南市| 韶关市| 郴州市| 洪湖市| 沁阳市| 乐清市| 武川县| 平凉市| 内江市|