歡迎您光臨本站 註冊首頁

Hibernate的多對一和一對多操作實例

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0

  Hibernate <http://developer.51cto.com/art/200611/34245.htm>的一對多和多對一操作真的很方便,如果系統採用Hibernate作為持久層,完全可以把對應的一對多和多對一邏輯關係放在Hibernate裡面控制,減少資料庫的負擔,而且也更清晰.

  1、多對一和一對多概念

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

  我曾經做過一些資料庫,比如某些政府部門的,其表單很設計的很簡單粗糙,甚至連主鍵都沒有,完全靠在事務層補全這些關係.其實通過Hibernate持久層來實現邏輯關係也是很不錯的方法.下面的例子,就是資料庫邏輯上基本沒有定義,主要放在持久層裡面.這個也主要是我對資料庫操作屬於半通水的原因.

  2、資料庫層

  這裡面有兩個表單,一個CUSTOMER,客戶表單,一個是ORDERS,訂單表單.生成客戶表單,這個是在SQLServer裡面做的,其實其他都一樣,邏輯關係在Hibernate上面,id是主鍵非空,其他可以為空:

  1.CREATETABLE[dbo].[CUSTOMER](

  2.[id][numeric](18,0)NOTNULL,

  3.[name][varchar](50)NULL,

  4.[age][int]NULL,

  5.CONSTRAINT[PK_CUSTOMER]PRIMARYKEY)

  訂單表單

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

  6.CREATETABLE[dbo].[ORDERS](

  7.[id][numeric](18,0)NULLPRIMARYKEY,

  8.[CUSTOMER_id][numeric](18,0)NOTNULL,

  9.[ORDER_NUMBER][varchar](50)NULL,

  10.[PRICE][numeric](18,3)NULL

  11.)

  3、Hibernate設定

  HIbernate裡面,一對多的對象體現,是客戶有一個集合set,set裡面放著對應訂單,而多對一體現,是訂單裡面有一個CUSTOMER對象,表明該訂單所屬的客戶.其中,CUSTOMER類為:

  12.publicclassCustomerimplementsjava.io.Serializable{

  13.privateLongid;

  14.privateStringname;

  15.privateIntegerage;

  16.privateSetrderses=newHashSet();

  17.

  18.}

  後面的getXXX和setXXX方法就省去了,同樣訂單類就是:

  19.publicclassOrdersimplementsjava.io.Serializable{

  20.privateLongid;

  21.privateCustomercustomer;

  22.privateStringorderNumber;

  23.privateDoubleprice;

  24.

  25.}

  而對應hbm文檔,就是map文檔如下:

  26.CUSTOMER.hbm.xml

  27.<!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/HibernateMappingDTD3.0//EN"

  28."http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

  29.<!--

  30.MappingfileautogeneratedbyMyEclipsePersistenceTools

  31.-->

  32.<hibernate-mapping>

  33.<classnameclassname="onetomany.Customer"table="CUSTOMER"schema="dbo"catalog="DBTEST">

  34.<idnameidname="id"type="java.lang.Long">

  35.<columnnamecolumnname="id"precision="18"scale="0"/>

  36.<generatorclassgeneratorclass="increment"/>

  37.</id>

  38.<propertynamepropertyname="name"type="java.lang.String">

  39.<columnnamecolumnname="name"length="50"/>

  40.</property>

  41.<propertynamepropertyname="age"type="java.lang.Integer">

  42.<columnnamecolumnname="age"/>

  43.</property>

  44.<setnamesetname="orderses"inverse="true"lazy="true"cascade="all">

  45.<key>

  46.<columnnamecolumnname="CUSTOMER_id"precision="18"scale="0"not-null="true"/>

  47.</key>

  48.<one-to-manyclassone-to-manyclass="onetomany.Orders"/>

  49.</set>

  50.</class>

  51.</hibernate-mapping>

  這個裡面,其他都很簡答了,其中<generatorclass="increment"/>表示主鍵值自動增加,這個主要針對字元串對應的,主要體現多對以的是:

  1.<setnamesetname="orderses"inverse="true"lazy="true"cascade="all">

  2.<key>

  3.<columnnamecolumnname="CUSTOMER_id"precision="18"scale="0"not-null="true"/>

  4.</key>

  5.<one-to-manyclassone-to-manyclass="onetomany.Orders"/>

  6.</set>

  其中,set表示,對應集合;fetch和lazy主要是用來級聯查詢的,而cascade和inverse主要是用來級聯插入和修改的,這幾個主要包括對集合的控制.<one-to-manyclass="onetomany.Orders"/>表示對應類,即set裡面包含的類,而key主要是用於確定set裡面對應表單列.

  7.ORDERS的hbm

  8.<?xmlversionxmlversion="1.0"encoding="utf-8"?>

  9.<!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/HibernateMappingDTD3.0//EN"

  10."http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

  11.<!--

  12.MappingfileautogeneratedbyMyEclipsePersistenceTools

  13.-->

  14.<hibernate-mapping>

  15.<classcatalogclasscatalog="DBTEST"name="onetomany.Orders"schema="dbo"table="ORDERS">

  16.<idnameidname="id"type="java.lang.Long">

  17.<columnnamecolumnname="id"precision="18"scale="0"/>

  18.<generatorclassgeneratorclass="increment"/>

  19.</id>

  20.<many-to-oneclassmany-to-oneclass="onetomany.Customer"fetch="select"name="customer">

  21.<columnnamecolumnname="CUSTOMER_id"precision="18"scale="0"/>

  22.</many-to-one>

  23.<propertygeneratedpropertygenerated="never"lazy="false"name="orderNumber"type="java.lang.String">

  24.<columnlengthcolumnlength="50"name="ORDER_NUMBER"/>

  25.</property>

  26.<propertygeneratedpropertygenerated="never"lazy="false"name="price"type="java.lang.Double">

  27.<columnnamecolumnname="PRICE"precision="18"scale="3"/>

  28.</property>

  29.</class>

  30.</hibernate-mapping>

  31.<many-to-oneclassmany-to-oneclass="onetomany.Customer"fetch="select"name="customer">

  32.<columnnamecolumnname="CUSTOMER_id"precision="18"scale="0"/>

  33.</many-to-one>

  表示CUSTOMER熟悉對應的類,和其作為key的列名,上面這些都可以在MyEclipse裡面自動生成.另外注意的一點是,在生成的DAO裡面,涉及表單操作的save()和delete()方法,必須要事件提交,資料庫才有反映.可以就該Hibernate.xml,或者用下面這樣代碼來實現:

  34.Sessionse=getSession();

  35.Transactiontx=se.beginTransaction();

  36.se.delete(persistentInstance);

  37.//se.save(instance);

  38.tx.commit();

  4、驗證效果

  1、新增用戶

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

  39.CustomerDAOcd=newCustomerDAO();

  40.Customerxd=newCustomer("王小虎",20,null);

  41.Ordersord1=newOrders();

  42.ord1.setCustomer(xd);

  43.ord1.setOrderNumber("王小虎的買單1");

  44.Ordersord2=newOrders();

  45.ord2.setCustomer(xd);

  46.ord2.setOrderNumber("王小虎的買單2");

  47.Setrderses=newHashSet();

  48.orderses.add(ord1);

  49.orderses.add(ord2);

  50.xd.setOrderses(orderses);

  51.cd.save(xd);

  代碼裡面,加入一個王小虎用戶.兩個訂單,通過setOrderses加入,只使用cd.save這一個對持久層操作.完成後查詢:

  52.王小虎

  53.=================================

  54.王小虎的買單1

  55.王小虎的買單2

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

  2、刪除操作

  56.List<Customer>csList=cd.findByProperty("name","王小虎");

  57.for(Customercs:csList){

  58.cd.delete(cs);

  59.}

  這個很簡單了,通過其中findByProperty("name","王小虎");對應SQL為deletefromtableCUSTOMERwherename=''王小虎';刪除了王小虎,而ORDERS裡面,王小虎對應的表單也同時被刪除.

  5、小小總結

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


[火星人 ] Hibernate的多對一和一對多操作實例已經有982次圍觀

http://coctec.com/docs/java/show-post-60334.html