Hibernate的多对一和一对多操作实例

 我来答
清宁时光17
2022-10-18 · TA获得超过1.4万个赞
知道大有可为答主
回答量:6697
采纳率:100%
帮助的人:37万
展开全部

  Hibernate <>的一对多和多对一操作真的很方便 如果系统采用Hibernate作为持久层 完全可以把对应的一对多和多对一逻辑关系放在Hibernate里面控制 减少数据库的负担 而且也更清晰

   多对一和一对多概念

  其实这个概念上来说很简单 比如一个客户可以有多个订单 多个订单属于同一个客户 就是最基本的一对多 和多对一 数据库使用中 感觉多对一和一对多算是比较常见的逻辑关系了

  我曾经做过一些数据库 比如某些 *** 部门的 其表单很设计的很简单粗糙 甚至连主键都没有 完全靠在事务层补全这些关系 其实通过Hibernate持久层来实现逻辑关系也是很不错的方法 下面的例子 就是数据库逻辑上基本没有定义 主要放在持久层里面 这个也主要是我对数据库操作属于半通水的原因

   数据库层

  这里面有两个表单 一个CUSTOMER 客户表单 一个是ORDERS 订单表单 生成客户表单 这个是在SQLServer里面做的 其实其他都一样 因为逻辑关系在Hibernate上面 id是主键非空 其他可以为空

   CREATETABLE[dbo] [CUSTOMER](

   [id][numeric]( )NOTNULL

   [name][varchar]( )NULL

   [age][int]NULL

   CONSTRAINT[PK_CUSTOMER]PRIMARYKEY)

  订单表单

  id为主键非空 CUSTOMER_id是对应客户主键 也非空 这里不做外键设置

   CREATETABLE[dbo] [ORDERS](

   [id][numeric]( )NULLPRIMARYKEY

   [CUSTOMER_id][numeric]( )NOTNULL

   [ORDER_NUMBER][varchar]( )NULL

   [PRICE][numeric]( )NULL

   )

   Hibernate设定

  HIbernate里面 一对多的对象体现 是客户有一个集合set set里面放著对应订单 而多对一体现 是订单里面有一个CUSTOMER对象 表明该订单所属的客户 其中 CUSTOMER类为

   publicclassCustomerimplementsjava io Serializable{

   privateLongid;

   privateStringname;

   privateIntegerage;

   privateSetrderses=newHashSet();

  

   }

  后面的getXXX和setXXX方法就省去了 同样订单类就是

   publicclassOrdersimplementsjava io Serializable{

   privateLongid;

   privateCustomercustomer;

   privateStringorderNumber;

   privateDoubleprice;

  

   }

  而对应hbm文档 就是map文档如下

   CUSTOMER hbm xml

   <!DOCTYPEhibernate mappingPUBLIC //Hibernate/HibernateMappingDTD //EN

   mapping dtd >

   <!

   MappingfileautogeneratedbyMyEclipsePersistenceTools

   >

   <hibernate mapping>

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

   <idnameidname= id type= java lang Long >

   <columnnamecolumnname= id precision= scale= />

   <generatorclassgeneratorclass= increment />

   </id>

   <propertynamepropertyname= name type= java lang String >

   <columnnamecolumnname= name length= />

   </property>

   <propertynamepropertyname= age type= java lang Integer >

   <columnnamecolumnname= age />

   </property>

   <setnamesetname= orderses inverse= true lazy= true cascade= all >

   <key>

   <columnnamecolumnname= CUSTOMER_id precision= scale= not null= true />

   </key>

   <one to manyclassone to manyclass= onetomany Orders />

   </set>

   </class>

   </hibernate mapping>

  这个里面 其他都很简答了 其中<generatorclass= increment />表示主键值自动增加 这个主要针对字符串对应的 主要体现多对以的是

   <setnamesetname= orderses inverse= true lazy= true cascade= all >

   <key>

   <columnnamecolumnname= CUSTOMER_id precision= scale= not null= true />

   </key>

   <one to manyclassone to manyclass= onetomany Orders />

   </set>

  其中 set表示 对应集合 fetch和lazy主要是用来级联查询的 而cascade和inverse主要是用来级联插入和修改的 这几个主要包括对集合的控制 <one to manyclass= onetomany Orders />表示对应类 即set里面包含的类 而key主要是用于确定set里面对应表单列

   ORDERS的hbm

   <?xmlversionxmlversion= encoding= utf ?>

   <!DOCTYPEhibernate mappingPUBLIC //Hibernate/HibernateMappingDTD //EN

   mapping dtd >

   <!

   MappingfileautogeneratedbyMyEclipsePersistenceTools

   >

   <hibernate mapping>

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

   <idnameidname= id type= java lang Long >

   <columnnamecolumnname= id precision= scale= />

   <generatorclassgeneratorclass= increment />

   </id>

   <many to oneclas *** any to oneclass= onetomany Customer fetch= select name= customer >

   <columnnamecolumnname= CUSTOMER_id precision= scale= />

   </many to one>

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

   <columnlengthcolumnlength= name= ORDER_NUMBER />

   </property>

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

   <columnnamecolumnname= PRICE precision= scale= />

   </property>

   </class>

   </hibernate mapping>

   <many to oneclas *** any to oneclass= onetomany Customer fetch= select name= customer >

   <columnnamecolumnname= CUSTOMER_id precision= scale= />

   </many to one>

  表示CUSTOMER熟悉对应的类 和其作为key的列名 上面这些都可以在MyEclipse里面自动生成 另外注意的一点是 在生成的DAO里面 涉及表单操作的save()和delete()方法 必须要事件提交 数据库才有反映 可以就该Hibernate xml 或者用下面这样代码来实现

   Sessionse=getSession();

   Transactiontx=se beginTransaction();

   se delete(persistentInstance);

   //se save(instance);

  mit();

   验证效果

   新增用户

  如果新增一个用户 该用户里面包含有两个表单 那么 由于持久层已经实现了逻辑关系 只要用户类里面的set包含了表单 则表单可以自动增加 实现代码

   CustomerDAOcd=newCustomerDAO();

   Customerxd=newCustomer( 王小虎 null);

   Ordersord =newOrders();

   ord setCustomer(xd);

   ord setOrderNumber( 王小虎的买单 );

   Ordersord =newOrders();

   ord setCustomer(xd);

   ord setOrderNumber( 王小虎的买单 );

   Setrderses=newHashSet();

   orderses add(ord );

   orderses add(ord );

   xd setOrderses(orderses);

   cd save(xd);

  代码里面 加入一个王小虎用户 两个订单 通过setOrderses加入 只使用cd save这一个对持久层操作 完成后查询

   王小虎

   =================================

   王小虎的买单

   王小虎的买单

  显示 CUSTOMER里面加入了王小虎 ORDERS里面也加入他的订单

   删除操作

   List<Customer>csList=cd findByProperty( name 王小虎 );

   for(Customercs:csList){

   cd delete(cs);

   }

  这个很简单了 通过其中findByProperty( name 王小虎 );对应SQL为deletefromtableCUSTOMERwherename= 王小虎 ;删除了王小虎 而ORDERS里面 王小虎对应的表单也同时被删除

   小小总结

lishixinzhi/Article/program/Java/ky/201311/28543

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式