Hibernate的多对一和一对多操作实例
Hibernate的一对多和多对一操作是非常方便的,如果在减少数据库复杂度的原则来说,把一些逻辑处理放在持久层,还是一个比较常见的方法。
Hibernate的一对多和多对一操作真的很方便,如果系统采用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>?
这个里面,其他都很简答了,其中<generatorstyle="">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-manystyle="">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"/>;