快穿系统男神攻略手册txt
0
2025 / 06 / 25
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