一、一对多:
一个客户可以有多个联系人,一个联系人只能属于一个客户。
1、一对多映射配置:
(1)创建实体类
//客户类:一个客户可以有多个联系人,一个联系人只能属于一个客户
public class Customer {
private Integer cid;
private String custName;
private String custLevel;
private String custSource;//客户来源
private String custPhone;
private String custMobile;
//一个客户可以有多个联系人
//hibernate要求使用集合表示多的数据,使用set集合
private Set<LinkMan> setLinkMan=new HashSet<LinkMan>();
public Set<LinkMan> getSetLinkMan() {
return setLinkMan;
}
public void setSetLinkMan(Set<LinkMan> setLinkMan) {
this.setLinkMan = setLinkMan;
}
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public String getCustName() {
return custName;
}
public void setCustName(String custName) {
this.custName = custName;
}
public String getCustLevel() {
return custLevel;
}
public void setCustLevel(String custLevel) {
this.custLevel = custLevel;
}
public String getCustSource() {
return custSource;
}
public void setCustSource(String custSource) {
this.custSource = custSource;
}
public String getCustPhone() {
return custPhone;
}
public void setCustPhone(String custPhone) {
this.custPhone = custPhone;
}
public String getCustMobile() {
return custMobile;
}
public void setCustMobile(String custMobile) {
this.custMobile = custMobile;
}
}
//联系人类:一个联系人只能属于一个客户
public class LinkMan {
private Integer lkm_id;
private String lkm_name;
private String lkm_gender;//性别
private String lkm_phone;
//一个联系人只能属于一个客户
private Customer customer;
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public Integer getLkm_id() {
return lkm_id;
}
public void setLkm_id(Integer lkm_id) {
this.lkm_id = lkm_id;
}
public String getLkm_name() {
return lkm_name;
}
public void setLkm_name(String lkm_name) {
this.lkm_name = lkm_name;
}
public String getLkm_gender() {
return lkm_gender;
}
public void setLkm_gender(String lkm_gender) {
this.lkm_gender = lkm_gender;
}
public String getLkm_phone() {
return lkm_phone;
}
public void setLkm_phone(String lkm_phone) {
this.lkm_phone = lkm_phone;
}
}
(2)在xxx.hbm.xml配置文件进行配置:
Customer.hbm.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 创建客户端的映射配置文件 -->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.zwp.onetomany.Customer" table="t_customer">
<id name="cid" column="cid">
<generator class="native"></generator>
</id>
<property name="custName" column="custName"></property>
<property name="custLevel" column="custLevel"></property>
<property name="custSource" column="custSource"></property>
<property name="custPhone" column="custPhone"></property>
<property name="custMobile" column="custMobile"></property>
<!-- 在客户映射文件中,表示所有联系人
使用set标签表示所有的联系人,set标签里面有name属性
name属性值写在客户实体类里面表示联系人的set集合名称-->
<set name="setLinkMan">
<!-- 一对多建表,有外键
hibernate机制,双向维护外键,在一和多的哪一方都需要配置外键
column属性值,外键名称-->
<key column="clid"></key>
<!-- 客户所有的联系人,class里面写联系人实体全路径 -->
<one-to-many class="com.zwp.onetomany.LinkMan"/>
</set>
</class>
</hibernate-mapping>
LinkMan.hbm.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 创建联系人的映射配置文件 -->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.zwp.onetomany.LinkMan" table="t_linkman">
<id name="lkm_id" column="lkm_id">
<generator class="native"></generator>
</id>
<property name="lkm_name" column="lkm_name"></property>
<property name="lkm_gender" column="lkm_gender"></property>
<property name="lkm_phone" column="lkm_phone"></property>
<!--表示联系人所属客户
name属性:因为在联系人实体类使用customer对象表示,写customer名称
class属性:customer全路径
column属性:外键名称
-->
<many-to-one name="customer" class="com.zwp.onetomany.Customer" column="clid"></many-to-one>
</class>
</hibernate-mapping>
(3) 在核心配置文件hibernate.cfg.xml配置文件进行配置:
<!-- 把映射文件放到核心配置文件中 -->
<mapping resource="com/zwp/onetomany/Customer.hbm.xml" />
<mapping resource="com/zwp/onetomany/LinkMan.hbm.xml" />
(4)测试代码:
//一对多测试类
public class OTMtest {
//演示 OID查询,对象导航查询
//OID查询:根据id查询,返回一个对象
//对象导航查询:根据id查询客户,在根据这个客户查询所有的联系人
@Test
public void TextSelect1(){
SessionFactory sessionfactory=null;
Session session=null;
Transaction tx=null;
try{
sessionfactory=HibernateUtil.getSessionFactory();
session=sessionfactory.openSession();
tx=session.beginTransaction();
Customer customer=session.get(Customer.class, 1);
Set<LinkMan> linkman=customer.getSetLinkMan();
System.out.println(linkman.size());
tx.commit();
}catch(Exception e)
{
e.printStackTrace();
tx.rollback();
}
finally{
session.close();
sessionfactory.close();
}
}
}
2、一对多级联操作:
(1)级联保存:
需求:添加客户,为这个客户添加一个联系人。
//一对多级联保存
@Test
public void TestAdd(){
SessionFactory sessionfactory=null;
Session session=null;
Transaction tx=null;
try{
sessionfactory=HibernateUtil.getSessionFactory();
session=sessionfactory.openSession();
tx=session.beginTransaction();
//1、创建客户和联系人对象
Customer customer=new Customer();
customer.setCustLevel("vip");
customer.setCustName("谷歌");
customer.setCustMobile("1321515");
customer.setCustPhone("1165666");
customer.setCustSource("网络");
LinkMan linkMan=new LinkMan();
linkMan.setLkm_name("mike");
linkMan.setLkm_gender("男");
linkMan.setLkm_phone("1351565");
//2、建立客户对象和联系人对象的关系
customer.getSetLinkMan().add(linkMan);
linkMan.setCustomer(customer);
//3、保存到数据库中
session.save(customer);
session.save(linkMan);
tx.commit();
}catch(Exception e){
e.printStackTrace();
tx.rollback();
}
finally{
session.close();
sessionfactory.close();
}
}
以下是上边代码的简化写法:
第一步:在客户的映射文件Customer.hbm.xml中的set标签中配置cascade进行级联保存;
第二步:创建客户和联系人对象,只需要把联系人放到客户中,保存客户就可以了。
<!-- 在客户映射文件中,set标签表示所有的联系人
cascade="save-update,delete":级联保存,级联删除 -->
<set name="setLinkMan" cascade="save-update,delete">
<key column="clid"></key>
<!-- 客户所有的联系人,class里面写联系人实体全路径 -->
<one-to-many class="com.zwp.onetomany.LinkMan"/>
</set>
//一对多级联保存,简化方式
@Test
public void TestAdd(){
SessionFactory sessionfactory=null;
Session session=null;
Transaction tx=null;
try{
sessionfactory=HibernateUtil.getSessionFactory();
session=sessionfactory.openSession();
tx=session.beginTransaction();
//1、创建客户和联系人对象
Customer customer=new Customer();
customer.setCustLevel("vip");
customer.setCustName("YY欢聚时代");
customer.setCustMobile("1321515");
customer.setCustPhone("1165666");
customer.setCustSource("网络");
LinkMan linkMan=new LinkMan();
linkMan.setLkm_name("John");
linkMan.setLkm_gender("男");
linkMan.setLkm_phone("1351565");
//2、建立客户对象和联系人对象的关系
customer.getSetLinkMan().add(linkMan);
//linkMan.setCustomer(customer);
//3、保存到数据库中
session.save(customer);
//session.save(linkMan);
tx.commit();
}catch(Exception e){
e.printStackTrace();
tx.rollback();
}
finally{
session.close();
sessionfactory.close();
}
}
(2)级联删除:
第一步:在客户的映射文件Customer.hbm.xml中的set标签中配置cascade进行级联删除;
第二步:在代码中直接删除客户。
//一对多级联删除
@Test
public void TestDel(){
SessionFactory sessionfactory=null;
Session session=null;
Transaction tx=null;
try{
sessionfactory=HibernateUtil.getSessionFactory();
session=sessionfactory.openSession();
tx=session.beginTransaction();
//1、根据id查询客户对象
Customer customer = session.get(Customer.class, 4);
//2、调用方法删除
session.delete(customer);
tx.commit();
}catch(Exception e){
e.printStackTrace();
tx.rollback();
}
finally{
session.close();
sessionfactory.close();
}
}
(3)inverse属性:
①问题:hibernate是使用双向维护外键,会造成性能下降。
②解决方案:让其中一方放弃外键维护。在一对多里面,让一的那方放弃维护。
③在客户的映射文件Customer.hbm.xml中的set标签中配置inverse;
inverse属性默认值,false不放弃关系的维护,true 表示放弃关系维护。
<!-- 在客户映射文件中,表示所有联系人。
inverse属性默认值,false不放弃关系的维护,true 表示放弃关系维护-->
<set name="setLinkMan" cascade="save-update,delete" inverse="true">
<!-- 一对多建表,有外键
hibernate机制,双向维护外键,在一和多的哪一方都需要配置外键
column属性值,外键名称 -->
<key column="clid"></key>
<!-- 客户所有的联系人,class里面写联系人实体全路径 -->
<one-to-many class="com.zwp.onetomany.LinkMan"/>
</set>
二、多对多:
1、多对多映射配置:
以用户和角色为例子
第一步:创建实体类,用户和角色:
第二步:让两个实体类之间互相表示:
①一个用户里面表示所有角色,使用set集合
②一个角色有多个用户,使用set集合
//用户实体类:一个用户有多个角色
public class User {
private Integer user_id;
private String user_name;
private String user_passsword;
//角色的set集合
private Set<Role> setRole=new HashSet<Role>();
public Set<Role> getSetRole() {
return setRole;
}
public void setSetRole(Set<Role> setRole) {
this.setRole = setRole;
}
public Integer getUser_id() {
return user_id;
}
public void setUser_id(Integer user_id) {
this.user_id = user_id;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String getUser_passsword() {
return user_passsword;
}
public void setUser_passsword(String user_passsword) {
this.user_passsword = user_passsword;
}
}
//角色实体类:一个角色有多个用户
public class Role {
private Integer role_id;
private String role_name;
private String role_memo;//角色描述
//用户的set集合
private Set<User> setUser=new HashSet<User>();
public Set<User> getSetUser() {
return setUser;
}
public void setSetUser(Set<User> setUser) {
this.setUser = setUser;
}
public Integer getRole_id() {
return role_id;
}
public void setRole_id(Integer role_id) {
this.role_id = role_id;
}
public String getRole_name() {
return role_name;
}
public void setRole_name(String role_name) {
this.role_name = role_name;
}
public String getRole_memo() {
return role_memo;
}
public void setRole_memo(String role_memo) {
this.role_memo = role_memo;
}
}
第三步:配置映射关系:
①基本配置
②配置多对多关系
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 创建用户的映射配置文件User.hbm.xml -->
<hibernate-mapping>
<class name="com.zwp.manytomany.User" table="t_user">
<id name="user_id" column="user_id">
<generator class="native"></generator>
</id>
<property name="user_name" column="user_name"></property>
<property name="user_passsword" column="user_passsword"></property>
<!-- 在用户里面表示所有角色,使用set标签;name属性:角色属性set集合名称;table:第三张表名称; -->
<set name="setRole" table="user_role">
<!-- key标签里面配置,配置当前映射文件第三张表外键名称 -->
<key column="userid"></key>
<!-- class:角色实体类全路径;column:角色在第三张表外键名称 -->
<many-to-many class="com.zwp.manytomany.Role" column="roleid"></many-to-many>
</set>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 创建角色的映射配置文件Role.hbm.xml -->
<hibernate-mapping>
<class name="com.zwp.manytomany.Role" table="t_role">
<id name="role_id" column="role_id">
<generator class="native"></generator>
</id>
<property name="role_name" column="role_name"></property>
<property name="role_memo" column="role_memo"></property>
<set name="setUser" table="user_role">
<key column="roleid"></key>
<many-to-many class="com.zwp.manytomany.User" column="userid"></many-to-many>
</set>
</class>
</hibernate-mapping>
第四步:在核心配置文件hibernate.cfg.xml中引入映射文件:
<!-- 把映射文件放到核心配置文件中 -->
<mapping resource="com/zwp/manytomany/Role.hbm.xml" />
<mapping resource="com/zwp/manytomany/User.hbm.xml" />
至此,hibernate多对多映射的配置已经完成。
2、多对多级联保存:
第一步:在用户的映射文件User.hbm.xml中的set标签中配置cascade进行级联保存;
第二步:创建用户和角色对象,只需要把角色放到用户中,保存用户就可以了。
<set name="setRole" table="user_role" cascade="save-update">
<!-- key标签里面配置,配置当前映射文件第三张表外键名称 -->
<key column="userid"></key>
<!-- class:角色实体类全路径;column:角色在第三张表外键名称 -->
<many-to-many class="com.zwp.manytomany.Role" column="roleid"></many-to-many>
</set>
@Test
public void Sava(){
//多对多级联保存
//<set name="setRole" table="user_role" cascade="save-update">
SessionFactory sessionfactory = null;
Session session = null;
Transaction tx=null;
try{
sessionfactory=HibernateUtil.getSessionFactory();
session=sessionfactory.openSession();
tx=session.beginTransaction();
//创建用户和角色
User user1=new User();
user1.setUser_name("小张");
user1.setUser_passsword("213456");
User user2=new User();
user2.setUser_name("小王");
user2.setUser_passsword("354656");
Role role1=new Role();
role1.setRole_name("总经理");
role1.setRole_memo("总经理");
Role role2=new Role();
role2.setRole_name("秘书");
role2.setRole_memo("秘书");
Role role3=new Role();
role3.setRole_name("保安");
role3.setRole_memo("保安");
user1.getSetRole().add(role1);
user1.getSetRole().add(role2);
user2.getSetRole().add(role2);
user2.getSetRole().add(role3);
session.save(user1);
session.save(user2);
tx.commit();
}catch(Exception e){
e.printStackTrace();
tx.rollback();
}
finally{
session.close();
sessionfactory.close();
}
}
3、多对多级联删除
在用户的映射文件User.hbm.xml中的set标签中配置cascade进行级联删除;
<!-- 在用户里面表示所有角色,使用set标签;name属性:角色属性set集合名称;table:第三张表名称; -->
<set name="setRole" table="user_role" cascade="delete">
<!-- key标签里面配置,配置当前映射文件第三张表外键名称 -->
<key column="userid"></key>
<!-- class:角色实体类全路径;column:角色在第三张表外键名称 -->
<many-to-many class="com.zwp.manytomany.Role" column="roleid"></many-to-many>
</set>
@Test
public void DelTest(){
//多对多级联删除
//<set name="setRole" table="user_role" cascade="delete">
SessionFactory sessionfactory = null;
Session session = null;
Transaction tx=null;
try{
sessionfactory=HibernateUtil.getSessionFactory();
session=sessionfactory.openSession();
tx=session.beginTransaction();
User user=session.get(User.class, 1);
session.delete(user);
tx.commit();
}catch(Exception e){
e.printStackTrace();
tx.rollback();
}
finally{
session.close();
sessionfactory.close();
}
}
4、维护第三张表关系:
用户和角色的多对多关系,维护关系通过第三张表维护。
(1)让某个用户有某个角色:
第一步:根据id查询用户和角色;
第二步:把角色放到用户里面:即,把角色对象放到用户set集合。
(2)让某个用户没有某个角色:
第一步:根据id查询用户和角色;
第二步:从用户里面把角色去掉:即,从set集合里面把角色移除。
@Test
public void TextTbable(){
//多对多维护第三张表
SessionFactory sessionfactory = null;
Session session = null;
Transaction tx=null;
try{
sessionfactory=HibernateUtil.getSessionFactory();
session=sessionfactory.openSession();
tx=session.beginTransaction();
User user=session.get(User.class, 2);
Role role=session.get(Role.class, 4);
//让用户4拥有角色2:
user.getSetRole().add(role);
//让用户4失去角色2:
user.getSetRole().remove(role);
tx.commit();
}catch(Exception e){
e.printStackTrace();
tx.rollback();
}
finally{
session.close();
sessionfactory.close();
}
}
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/114722.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...