Hibernate级联操作
Posted fjk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate级联操作相关的知识,希望对你有一定的参考价值。
hibernate级联操作
po类
order订单类
//订单-----多的一方 public class Order { private Integer id; private Double money; private String receiverInfo; // 收货地址 // 订单与客户关联 private Customer c; // 描述订单属于某一个客户 public Customer getC() { return c; } public void setC(Customer c) { this.c = c; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } public String getReceiverInfo() { return receiverInfo; } public void setReceiverInfo(String receiverInfo) { this.receiverInfo = receiverInfo; } }
customer用户类
//客户 ------一的一方 public class Customer { private Integer id; // 主键 private String name; // 姓名 // 描述客户可以有多个订单 private Set<Order> orders = new HashSet<Order>(); public Set<Order> getOrders() { return orders; } public void setOrders(Set<Order> orders) { this.orders = orders; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
xxx.hbm.xml配置文件
Order.hbm.xml
<?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> <!-- name表示类的全路径 catalog表示数据库名 默认为cfg配置文件的数据库名 table需要创建的表名 --> <class name="com.baidu.test.Order" catalog="test" table="o_order"> <!-- private Integer id; private Double money; private String receiverInfo; // 收货地址 private Customer c; // 描述订单属于某一个客户--> <!-- name表示po类中的对应主键字段 column表示数据库表里面的字段 --> <id name="id" column="o_id"> <generator class="identity"></generator> </id> <property name="money" column="o_money"></property> <property name="receiverInfo" length="100" column="o_receiverInfo"></property> <!-- 多对一 多个订单属于一个用户的 class表示类的全路径 --> <many-to-one name="c" class="com.baidu.test.Customer" column="o_customer_id" ></many-to-one> </class> </hibernate-mapping>
Customer.hbm.xml
<?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.baidu.test.Customer" catalog="test" table="c_customer"> <!-- private Integer id; // 主键 private String name; // 姓名 // 描述客户可以有多个订单 private Set<Order> orders = new HashSet<Order>(); --> <id name="id" column="c_id"> <generator class="identity"></generator> </id> <property name="name" length="30"></property> <!-- 用来描述多在一的一方关联多的一方 name 表示订单变量 --> <set name="orders" cascade="save-update"> <!-- key 用来描述多的一方产生的外键名称 --> <key column="o_customer_id"></key> <!-- 关联的类 --> <one-to-many class="com.baidu.test.Order"/> </set> </class> </hibernate-mapping>
级联保存
简单的存储
@Test public void test01(){ //获取连接 Session session = HibernateUtils.getSession(); //开启事务 Transaction ts = session.beginTransaction(); //处于游离态 没有oid 与session无关 Order o=new Order(); o.setMoney(123.0); o.setReceiverInfo("123333"); HashSet<Order> hashSet = new HashSet<Order>(); hashSet.add(o); Customer c=new Customer(); c.setName("123556"); c.setOrders(hashSet); session.save(o);//处于持久态 与session有关 有oid session.save(c); ts.commit(); session.close(); }
使用单项的关联的保存
在配置文件中添加属性cascade="true"
在一得那一方添加该属性/获取在两端都设置该属性(设置翻转为false)
@Test //测试单项级联 public void test02(){ Session session = HibernateUtils.getSession(); Transaction bt = session.beginTransaction(); //操作 Order o=new Order(); o.setMoney(123.0); o.setReceiverInfo("123333"); HashSet<Order> hashSet = new HashSet<Order>(); hashSet.add(o); Customer c=new Customer(); c.setName("123556"); c.setOrders(hashSet); session.save(c);//处于持久态 与session有关 有oid bt.commit(); session.close(); }
只需要保存一个customer对象 会自动保存Order对象 在那边设置cascade="save-update" 可以自动保存级联表
使用双向的关联的保存
我们在开发中要配置双向关联配置。---------可以通过任意一方来操作对方 在操作代码,尽量来要进行单向关联。------可以尽量资源浪费。 在双向关联中,会存在多余的update语句。 我们可以使用inverse属性来设置,双向关联时由哪一方来维护表与表之间的关系。 Inverse它的值如果为true代表,由对方来维护外键。 Inverse它的值如果为false代表,由本方来维护外键。 关于inverse的取值: 外键在哪一个表中,我们就让哪一方来维护外键。
对象导航
对象导航:就是使用对象调取成员(成员方法和成员变量)
使用注解开发级联保存 (一对多)
Order po类
package com.baidu.test1; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; //订单-----多的一方 @Entity @Table(name="t_order") public class Order { /* @Id @GenericGenerator(name="myuuid",strategy="uuid") @GeneratedValue(generator="myuuid")*/ @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Integer id; @Column(name="t_money") private Double money; private String receiverInfo; // 收货地址 // 订单与客户关联 @ManyToOne(targetEntity=Customer.class) @JoinColumn(name="c_customer_id")//添加外键 private Customer c; // 描述订单属于某一个客户 public Customer getC() { return c; } public void setC(Customer c) { this.c = c; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } public String getReceiverInfo() { return receiverInfo; } public void setReceiverInfo(String receiverInfo) { this.receiverInfo = receiverInfo; } }
Customer po类
package com.baidu.test1; import java.util.HashSet; import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; import org.hibernate.annotations.Cascade; import org.hibernate.annotations.CascadeType; //客户 ------一的一方 @Entity//表示po类 声明一个实类 @Table(name="t_customer") public class Customer { @Id @GeneratedValue(strategy=GenerationType.IDENTITY)//设置主键的模式为自增长 private Integer id; // 主键 @Column(name="t_name",length=50) private String name; // 姓名 //mappedBy相当于inverse="true" // 描述客户可以有多个订单 表示一对多 @OneToMany(targetEntity=Order.class,mappedBy="c",cascade=javax.persistence.CascadeType.ALL) //@Cascade(CascadeType.SAVE_UPDATE) private Set<Order> orders = new HashSet<Order>(); public Set<Order> getOrders() { return orders; } public void setOrders(Set<Order> orders) { this.orders = orders; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
hibernate.cfg.xml
<mapping class="com.baidu.test1.Order"/> <mapping class="com.baidu.test1.Customer"/>
测试类:
@Test //测试单项级联 public void test02(){ Session session = HibernateUtils.getSession(); Transaction bt = session.beginTransaction(); //操作 Order o=new Order(); o.setMoney(123.0); o.setReceiverInfo("123333"); HashSet<Order> hashSet = new HashSet<Order>(); hashSet.add(o); Customer c=new Customer(); c.setName("123556"); c.setOrders(hashSet); o.setC(c); //使用注解开发 必须在这里添加映射关系 否则会在customer中的外键不会产生之值 session.save(c);//处于持久态 与session有关 有oid bt.commit(); session.close(); }
多对多保存
Student类
package com.baidu.annotest02; import java.util.HashSet; import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; import org.hibernate.annotations.Cascade; import org.hibernate.annotations.CascadeType; import org.hibernate.annotations.GenericGenerator; @Entity//定义实体类 @Table(name="t_student")//设置表名 public class Student { //学生编号 @Id//定义主键 @GenericGenerator(name="myuuid",strategy="uuid") @GeneratedValue(generator="myuuid") private String pid; private String name; @ManyToMany(targetEntity=Teacher.class) @JoinTable(name="aaa",joinColumns={@JoinColumn(name="t_student_id")},inverseJoinColumns={@JoinColumn(name="t_teacher_id")}) @Cascade(CascadeType.SAVE_UPDATE) private Set<Teacher> teachers=new HashSet<Teacher>(); public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPid() { return pid; } public void setPid(String pid) { this.pid = pid; } public Set<Teacher> getTeachers() { return teachers; } public void setTeachers(Set<Teacher> teachers) { this.teachers = teachers; } }
Teacher类
package com.baidu.annotest02; import java.util.HashSet; import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.Table; import org.hibernate.annotations.Cascade; import org.hibernate.annotations.CascadeType; import org.hibernate.annotations.GenericGenerator; @Entity @Table(name="t_teacher") public class Teacher { @Id //定义主键 @GenericGenerator(name="myUuid",strategy="uuid") @GeneratedValue(generator="myUuid") private String id; private String name; @ManyToMany(targetEntity=Student.class,mappedBy="teachers") @Cascade(CascadeType.SAVE_UPDATE) private Set<Student> list=new HashSet<>() ; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public Set<Student> getList() { return list; } public void setList(Set<Student> list) { this.list = list; } }
配置文件
<mapping class="com.baidu.annotest02.Student"/> <mapping class="com.baidu.annotest02.Teacher"/>
测试方法
@Test public void test01(){ //获取连接 Session session = HibernateUtils.getSession(); //开启事务 Transaction ts = session.beginTransaction(); Teacher t=new Teacher(); t.setName("123"); Student s=new Student(); s.setName("321"); Set<Teacher> lt=new HashSet<Teacher>(); lt.add(t); Set<Student> ls=new HashSet<Student>(); ls.add(s); t.setList(ls); s.setTeachers(lt); session.save(s); ts.commit(); session.close(); }
级联保存一对一
外键关联
以上是关于Hibernate级联操作的主要内容,如果未能解决你的问题,请参考以下文章