基於MyEclipse的Hibernate的多對一和一對多操作簡單示例

張國平發表於2010-04-06

 

     Hibernate的一對多和多對一操作真的很方便,如果系統採用Hibernate作為持久層,完全可以把對應的一對多和多對一邏輯關係放在Hibernate裡面控制,減少資料庫的負擔,而且也更清晰。

  1、多對一和一對多概念

   其實這個概念上來說很簡單,比如一個客戶可以有多個訂單,多個訂單屬於同一個客戶。就是最基本的一對多,和多對一。資料庫使用中,感覺多對一和一對多算是比較常見的邏輯關係了。

 我曾經做過一些資料庫,比如某些政府部門的,其表單很設計的很簡單粗糙,甚至連主鍵都沒有,完全靠在事務層補全這些關係。其實透過Hibernate持久層來實現邏輯關係也是很不錯的方法。

 下面的例子,就是資料庫邏輯上基本沒有定義,主要放在持久層裡面。這個也主要是我對資料庫操作屬於半通水的原因。

2、資料庫層

這裡面有兩個表單,一個CUSTOMER,客戶表單,一個是ORDERS,訂單表單。

生成客戶表單,這個是在SQL Server裡面做的,其實其他都一樣,因為邏輯關係在Hibernate上面,id是主鍵非空,其他可以為空,

CREATE TABLE [dbo].[CUSTOMER](
 [id] [numeric](18, 0) NOT NULL,
 [name] [varchar](50) NULL,
 [age] [int] NULL,
 CONSTRAINT [PK_CUSTOMER] PRIMARY KEY  )

訂單表單

 id為主鍵非空,CUSTOMER_id是對應客戶主鍵,也非空,這裡不做外來鍵設定。

CREATE TABLE [dbo].[ORDERS](
 [id] [numeric](18, 0)  NULL PRIMARY KEY,
 [CUSTOMER_id] [numeric](18, 0) NOT NULL,
 [ORDER_NUMBER] [varchar](50) NULL,
 [PRICE] [numeric](18, 3) NULL
)

3、Hibernate設定

HIbernate裡面,一對多的物件體現,是客戶有一個集合set,set裡面放著對應訂單

而多對一體現,是訂單裡面有一個CUSTOMER物件,表明該訂單所屬的客戶。

其中,CUSTOMER類為

public class Customer implements java.io.Serializable {

 private Long id;
 private String name;
 private Integer age;
 private Set rderses = new HashSet();


後面的getXXX和setXXX方法就省去了

同樣訂單類就是

public class Orders implements java.io.Serializable {

 private Long id;
 private Customer customer;
 private String orderNumber;
 private Double price;

而對應hbm文件,就是map文件如下

CUSTOMER.hbm.xml

BR>"">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
--&gt

   
       
           
           
       

       
           
       

       
           
       

       
           
               
           

           
       

   

這個裡面,其他都很簡答了,其中表示主鍵值自動增加,這個主要針對字串對應的,主要體現多對以的是

       
           
               
           

           
       

其中,set表示,對應集合;fetch 和 lazy 主要是用來級聯查詢的,   而 cascade 和 inverse 主要是用來級聯插入和修改的。

這幾個主要包括對集合的控制,具體可以參考

http://www.cnblogs.com/tongzhiyong/archive/2009/05/06/1451021.html

表示對應類,即set裡面包含的類,

而key主要是用於確定set裡面對應表單列。

ORDERS的hbm


BR>                                   "">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
--&gt

 
 
  
  
 

 
  
 

 
  
 

 
  
 

 


這裡面, 


  
 

表示CUSTOMER熟悉對應的類,和其作為key 的列名

上面這些都可以在MyEclipse裡面自動生成。

另外注意的一點是,在生成的DAO裡面

涉及表單操作的save()和delete()方法,必須要事件提交,資料庫才有反映。

可以就該Hibernate.xml,或者用下面這樣程式碼來實現。

Session se=getSession();
   Transaction tx=se.beginTransaction();
  
   se.delete(persistentInstance);

//se.save(instance);
   tx.commit();

4、驗證效果

1、新增使用者,

如果新增一個使用者,該使用者裡面包含有兩個表單,那麼,由於持久層已經實現了邏輯關係,只要使用者類裡面的set包含了表單,則表單可以自動增加。

實現程式碼

   CustomerDAO cd=new CustomerDAO();
   
   Customer xd=new Customer("王小虎",20, null);
  
   Orders ord1=new Orders();
   
   ord1.setCustomer(xd);
   ord1.setOrderNumber("王小虎的買單1");
   Orders ord2=new Orders();
   ord2.setCustomer(xd);
   ord2.setOrderNumber("王小虎的買單2");
   
   Set rderses = new HashSet();
   orderses.add(ord1);
   orderses.add(ord2);
   
   xd.setOrderses(orderses);
   cd.save(xd);

程式碼裡面,加入一個王小虎使用者。兩個訂單,透過setOrderses加入,只使用cd.save這一個對持久層操作。

完成後查詢

王小虎
=================================
王小虎的買單1
王小虎的買單2

顯示,CUSTOMER裡面加入了王小虎,ORDERS裡面也加入他的訂單。

2、刪除操作

 List csList=cd.findByProperty("name","王小虎");
   for(Customer cs:csList){
   cd.delete(cs);
   }

這個很簡單了,透過其中findByProperty("name","王小虎");
對應SQL為delete from table CUSTOMER where name=''王小虎';

刪除了王小虎,而ORDERS裡面,王小虎對應的表單也同時被刪除。

 

 

5、小小總結

Hibernate的多對一和一對多處理,還是挺方便的,如果在減少資料庫複雜度的原則來說,把一些邏輯處理放在持久層是一個常見的方法。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22259926/viewspace-631423/,如需轉載,請註明出處,否則將追究法律責任。

相關文章