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级联操作的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate级联操作

2018.11.4 Hibernate中多对多的关系

Hibernate级联操作

Hibernate-级联操作

hibernate第三天

关联映射级联操作关系维护 ---- Hibernate之一对多|多对一关系