文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Hibernate中怎么实现多对一和一对多操作

2023-06-17 15:16

关注

这期内容当中小编将会给大家带来有关Hibernate中怎么实现多对一和一对多操作,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

1、多对一和一对多概念

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

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

2、数据库层

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

CREATETABLE[dbo].[CUSTOMER](  [id][numeric](18,0)NOTNULL,  [name][varchar](50)NULL,  [age][int]NULL,  CONSTRAINT[PK_CUSTOMER]PRIMARYKEY)

订单表单

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

CREATETABLE[dbo].[ORDERS](  [id][numeric](18,0)NULLPRIMARYKEY,  [CUSTOMER_id][numeric](18,0)NOTNULL,  [ORDER_NUMBER][varchar](50)NULL,  [PRICE][numeric](18,3)NULL  )

3、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/HibernateMappingDTD3.0//EN"  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!--  MappingfileautogeneratedbyMyEclipsePersistenceTools  --> <hibernate-mapping> <classnameclassname="onetomany.Customer"table="CUSTOMER"schema="dbo"catalog="DBTEST"> <idnameidname="id"type="java.lang.Long"> <columnnamecolumnname="id"precision="18"scale="0"/> <generatorclassgeneratorclass="increment"/> </id> <propertynamepropertyname="name"type="java.lang.String"> <columnnamecolumnname="name"length="50"/> </property> <propertynamepropertyname="age"type="java.lang.Integer"> <columnnamecolumnname="age"/> </property> <setnamesetname="orderses"inverse="true"lazy="true"cascade="all"> <key> <columnnamecolumnname="CUSTOMER_id"precision="18"scale="0"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="18"scale="0"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="1.0"encoding="utf-8"?> <!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/HibernateMappingDTD3.0//EN"  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!--  MappingfileautogeneratedbyMyEclipsePersistenceTools  --> <hibernate-mapping> <classcatalogclasscatalog="DBTEST"name="onetomany.Orders"schema="dbo"table="ORDERS"> <idnameidname="id"type="java.lang.Long"> <columnnamecolumnname="id"precision="18"scale="0"/> <generatorclassgeneratorclass="increment"/> </id> <many-to-oneclassmany-to-oneclass="onetomany.Customer"fetch="select"name="customer"> <columnnamecolumnname="CUSTOMER_id"precision="18"scale="0"/> </many-to-one> <propertygeneratedpropertygenerated="never"lazy="false"name="orderNumber"type="java.lang.String"> <columnlengthcolumnlength="50"name="ORDER_NUMBER"/> </property> <propertygeneratedpropertygenerated="never"lazy="false"name="price"type="java.lang.Double"> <columnnamecolumnname="PRICE"precision="18"scale="3"/> </property> </class> </hibernate-mapping> <many-to-oneclassmany-to-oneclass="onetomany.Customer"fetch="select"name="customer"> <columnnamecolumnname="CUSTOMER_id"precision="18"scale="0"/> </many-to-one>

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

Sessionse=getSession();  Transactiontx=se.beginTransaction();  se.delete(persistentInstance);  //se.save(instance);  tx.commit();

4、验证效果

新增用户

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

CustomerDAOcd=newCustomerDAO();  Customerxd=newCustomer("王小虎",20,null);  Ordersord1=newOrders();  ord1.setCustomer(xd);  ord1.setOrderNumber("王小虎的买单1");  Ordersord2=newOrders();  ord2.setCustomer(xd);  ord2.setOrderNumber("王小虎的买单2");  Setrderses=newHashSet();  orderses.add(ord1);  orderses.add(ord2);  xd.setOrderses(orderses);  cd.save(xd);

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

王小虎  =================================  王小虎的买单1  王小虎的买单2

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

删除操作

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

上述就是小编为大家分享的Hibernate中怎么实现多对一和一对多操作了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯