一对多映射(重点)
编写JavaBean
1的一方
- 保存n的一方对象的Set集合
- hibernate框架默认的集合是set集合,集合必须要手动初始化
- 案例:12345678910111213141516171819public class Customer {private Long cust_id; //客户编号(主键)private String cust_name; //客户名称(公司名称)private Long cust_user_id; //负责人idprivate Long cust_create_id; //创建人idprivate String cust_source; //客户信息来源private String cust_industry; //客户所属行业private String cust_level; //客户级别private String cust_linkman; //联系人private String cust_phone; //固定电话private String cust_mobile; //移动电话//1的一方//hibernate框架默认的集合是set集合,集合必须要手动初始化private Set<LinkMan> LinkMans = new HashSet<LinkMan>();set&get...}
n的一方
- 保存1的一方的对象
- 这个对象千万不要自己new,配置文件提供该类的全路径,hibernate框架会自己new
- 案例:123456789101112131415161718public class LinkMan {private long lkm_id;private String lkm_name;private String lkm_gender;private String lkm_phone;private String lkm_mobile;private String lkm_email;private String lkm_qq;private String lkm_position;private String lkm_memo;//n的一方//编写一个对象,千万不要自己new,配置文件提供类的全路径,hibernate框架会自己newprivate Customer customer;set&get...}
编写一对多的配置文件
1的一方
1234567891011121314151617181920212223242526272829303132333435<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping><!-- 配置类和表结构的映射 --><class name="com.lousen.domain.Customer" table="cst_customer"><!-- 配置id,name:JavaBean,column:表结构的字段 --><id name="cust_id" column="cust_id"><!-- 主键生成策略 --><generator class="native"></generator></id><!-- 配置其他属性 --><property name="cust_name" column="cust_name"/><property name="cust_user_id" column="cust_user_id"/><property name="cust_create_id" column="cust_create_id"/><property name="cust_source" column="cust_source"/><property name="cust_industry" column="cust_industry"/><property name="cust_level" column="cust_level"/><property name="cust_linkman" column="cust_linkman"/><property name="cust_phone" column="cust_phone"/><property name="cust_mobile" column="cust_mobile"/><!-- 配置一的一方,name:表示集合属性的名称,cascade:级联 --><set name="LinkMans" inverse="true"><!-- column:外键字段 --><!-- class:集合属性的全路径 --><key column="lkm_cust_id"></key><one-to-many class="com.lousen.domain.LinkMan"/></set></class></hibernate-mapping>n的一方
1234567891011121314151617181920212223242526272829303132333435<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping><!-- 配置类和表结构的映射 --><class name="com.lousen.domain.LinkMan" table="cst_linkman"><!-- 配置id,name:JavaBean,column:表结构的字段 --><id name="lkm_id" column="lkm_id"><!-- 主键生成策略 --><generator class="native"></generator></id><!-- 配置其他属性 --><property name="lkm_name" column="lkm_name"/><property name="lkm_gender" column="lkm_gender"/><property name="lkm_phone" column="lkm_phone"/><property name="lkm_mobile" column="lkm_mobile"/><property name="lkm_email" column="lkm_email"/><property name="lkm_qq" column="lkm_qq"/><property name="lkm_position" column="lkm_position"/><property name="lkm_memo" column="lkm_memo"/><!--先配置多的一方name: 当前JavaBean中的属性class:该属性的全路径column:外键字段cascade: 级联--><many-to-one name="customer" class="com.lousen.domain.Customer" column="lkm_cust_id" cascade="save-update"></many-to-one></class></hibernate-mapping>
双向关联数据
- 简介
顾客关联联系人,联系人同时也要关联顾客,两者的对象都需要保存。 - 双向关联数据保存 123456789101112131415161718192021222324252627282930313233/*** 双向关联保存数据(最麻烦的)*/@Testpublic void run1(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//创建一个顾客Customer c1 = new Customer();c1.setCust_name("张三");//创建两个联系人LinkMan l1 = new LinkMan();l1.setLkm_name("老大");LinkMan l2 = new LinkMan();l2.setLkm_name("老二");//演示双向关联c1.getLinkMans().add(l1);c1.getLinkMans().add(l2);l1.setCustomer(c1);l2.setCustomer(c1);//保存数据session.save(c1);session.save(l1);session.save(l2);tr.commit();}
级联保存
- 简介
保存一方的同时可以把关联的对象也保存到数据库中,具有方向性,可以修改顾客的配置文件使顾客级联联系人,也可以修改联系人的配置文件使联系人级联顾客。 - 配置文件
在配置文件添加属性cascade="save-update"
即可 - 级联保存案例 123456789101112131415161718192021222324252627282930/*** 级联保存(单向关联)* 顾客级联联系人*/@Testpublic void run2(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//创建一个顾客Customer c1 = new Customer();c1.setCust_name("张三");//创建两个联系人LinkMan l1 = new LinkMan();l1.setLkm_name("老大");LinkMan l2 = new LinkMan();l2.setLkm_name("老二");//演示级联c1.getLinkMans().add(l1);c1.getLinkMans().add(l2);//保存数据session.save(c1);tr.commit();}
级联删除(谨慎使用,很少使用)
- 简介
- 普通的直接删除
删除顾客以后,该顾客对应的联系人的外键那一列的值变为null - 级联删除
删除顾客以后,该顾客对应的联系人的所有数据被删除
- 普通的直接删除
- 配置文件
在配置文件添加属性cascade="delete"
即可 - 级联删除案例 123456789101112131415161718/*** 级联删除* 同样具有方向性,也可两边都级联(很危险,相关数据全删)* 在联系人和顾客两边都加上级联删除* 删除联系人时联系人级联删除顾客,删除顾客时顾客又级联删除联系人*/@Testpublic void run4(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//删除主键为3的联系人LinkMan linkman = session.get(LinkMan.class,3L);session.delete(linkman);tr.commit();}
孤儿删除
- 简介
- 只存在于一对多
- 在一对多的关系中,可以将一的一方认为是父方。将多的一方认为是子方。孤儿删除:在解除了父子关系的时候。将子方整条记录直接删除。
- 配置文件
在配置文件<set>
标签上添加属性cascade="delete-orphan"
即可
3.孤儿删除案例1234567891011121314151617/*** 孤儿删除(在解除关系的基础上修改了配置文件,cascade="delete-orphan")* 删除整条记录*/@Testpublic void run6(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();LinkMan linkman = session.get(LinkMan.class,9L);Customer customer = session.get(Customer.class,9L);//解除关系customer.getLinkMans().remove(linkman);tr.commit();}
放弃外键的维护
- 简介
- 双方都维护外键的时候,会产生多余的SQL语句
- 产生的原因:session的一级缓存中的快照机制,会让双方都更新数据库,产生了多余的SQL语句。
- 如果不想产生多余的SQL语句,那么需要一方来放弃外键的维护
- 配置文件
在<set>
标签上配置一个inverse="true"
。默认值是false。
cascade和inverse
- cascade用来级联操作(保存、修改和删除)
- inverse用来维护外键的
- 两者一般不能同时存在同一个配置文件
- inverse在一对多中必须放在1的一方,在多对多时放在少的一方
- cascade放在inverse的另一方
- 如果同时存在同一个配置文件,将无法对该方的外键进行保存等操作,因为这一方已经放弃了对外键的维护。
多对多映射(重点)
编写JavaBean
同(一对多)中多的一方
案例:12345678910public class User { private Long uid; private String username; private String password; private Set<Role> roles = new HashSet<Role>(); set&get...}
|
|
编写多对多的配置文件
多-用户
1234567891011121314151617181920212223242526272829303132333435<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping><!-- 配置类和表结构的映射 --><class name="com.lousen.domain.User" table="sys_user"><!-- 配置id,name:JavaBean,column:表结构的字段 --><id name="uid" column="uid"><!-- 主键生成策略 --><generator class="native"></generator></id><!-- 配置其他属性 --><property name="username" column="username"/><property name="password" column="password"/><!--配置多对多name:集合的名称table:中间表的名称--><set name="roles" table="sys_user_role" cascade="save-update"><!-- 当前对象在中间表外键的名称 --><key column="uid" /><!--class:集合中所存对象的全路径column:集合中所存对象在中间表的外键名称--><many-to-many class="com.lousen.domain.Role" column="rid"></many-to-many></set></class></hibernate-mapping>多-角色
12345678910111213141516171819202122232425262728293031323334<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping><!-- 配置类和表结构的映射 --><class name="com.lousen.domain.Role" table="sys_role"><!-- 配置id,name:JavaBean,column:表结构的字段 --><id name="rid" column="rid"><!-- 主键生成策略 --><generator class="native"></generator></id><!-- 配置其他属性 --><property name="rname" column="rname"/><!--配置多对多name:集合的名称table:中间表的名称--><set name="users" table="sys_user_role" inverse="true"><!-- 当前对象在中间表外键的名称 --><key column="rid" /><!--class:集合中所存对象的全路径column:集合中所存对象在中间表的外键名称--><many-to-many class="com.lousen.domain.User" column="uid"></many-to-many></set></class></hibernate-mapping>中间表
在多对多中,只要正确配置了文件,Hibernate框架会自动生成中间表
双向关联
多对多进行双向关联的时候:必须有一方放弃外键维护权,否则会报错!!!
级联操作
- 简介
同一对多 - 案例 1234567891011121314151617181920212223242526272829/*** 多对多* role放弃外键维护* 保存user时级联保存role*/@Testpublic void run1(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//创建用户User u1 = new User();u1.setUsername("张三");User u2 = new User();u2.setUsername("李四");//创建角色Role r1 = new Role();r1.setRname("上校");Role r2 = new Role();r2.setRname("下士");//级联保存u1.getRoles().add(r1);u1.getRoles().add(r2);u2.getRoles().add(r1);session.save(u1);session.save(u2);tr.commit();}
维护中间表
- 简介
- 在多对多中,只要正确配置了文件,Hibernate框架会自动生成中间表
- 通过操作对应集合来操作对应的外键
- 案例: 123456789101112131415161718/*** 维护中间表* 通过操作集合*/@Testpublic void run2(){Session session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();//查询李四用户User u = session.get(User.class, 2L);//查询角色Role r = session.get(Role.class, 2L);//从中间表移除该条数据u.getRoles().remove(r);tr.commit();}
最后更新: 2020年07月27日 03:38
原始链接: https://www.lousenjay.top/2018/07/03/Hibernate框架入门学习(三)/