前面的两次,分别给大家介绍了Hibernate开发的基本注解和Hibernate开发的嵌入式注解。今天给大家介绍一下Hibernate注解开发中最重要的一部分:对象关系映射注解的作用和使用方法。还是继承上面的初衷,只给大家介绍对象关系映射在开发中的常用的注解和常用注解的常用属性。接下来我就开始今天的介绍:
今天我要向大家介绍的对象关系映射中的:一对一关系映射、一对多关系映射、多对一关系映射、多对多关系映射(单向&双向)。
一、一对一关系映射
介绍一对一关系映射我会以老公老婆的例给大家举例:
关于老公老婆的这个例子我先给大家申明一下,这个例子只适用于中国的一夫一妻制,如果你是一个歪果仁而你所在的国家不是一夫一妻制,那就直接看下面的关系映射吧(没有任何歧视或诽谤的意思)。
在中国每个家庭都是一夫一妻,那我们来做个游戏:通过老婆找老公,根据老婆所提供的唯一标识来找到每个老婆所对应的老公。我通过面向对象的思想把这个游戏提炼出来j就是:老婆对象中有一个映射老公对象中唯一属性值的关联外键。好了现在既然提炼出来了,我们顺着这个思路进行写代码,在写代码的过程中遇上什么注解就介绍什么注解,下面是我的java代码,一些注解的介绍在代码的注释中会介绍到:
package com.bd.cdw.pojo_t;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
*<p>Title:hibernate注解(一对一注解)</p>
*<p>Description:创建一个老公类</p>
*<p>Company:www.bd.com</p>
*
* @author 陈大伟
* @date 2017年5月10日下午2:49:47
* @version 1.4
*/
@Entity
@Table(name="t_husband")
public class Husband
{
//老公的Id
private Integer h_Id;
//老公的姓名
private String h_Name;
//老公的体重
private String h_weight;
//由于和老公是一对一的关系所以在老公这边表示一下老婆,同样的生成get和set方法
private Wife wife;
/*********关联关系的get和set方法**********/
/**
* @OneToOne注解
* 作用:指明A对象和B对象为一对一关系
* 用法:在需要有外键的私有化对象的get方法上面使用(也就是在数据库中生成表,
* 那个表(t_A)有外键就在那个表所映射的对象(A)上使用,这个对象(A)一定是和这个
* 对象(A)具有一对一关系映射的对象(B)中私有化对象(A)生成get方法上使用。
* 属性:
* targetEntity:Class类型的属性。定义关系类的类型,默认是该成员属性对应的类类型,所以通常不需要提供定义。
* cascade:CascadeType[]类型。该属性定义类和类之间的级联关系。定义的级联关系将被容器视为对当前类对象及其
* 关联类对象采取相同的操作(既一处进行CRUD操作和其有关系的别处也同时进行CRUD操作)而且这种关系是递
* 归调用的。
* cascade的值(value)只能从:
* CascadeType.PERSIST(级联新建)
* CascadeType.REMOVE(级联删除)、
* CascadeType.REFRESH(级联刷新)、
* CascadeType.MERGE(级联更新)中选择一个或多个。
* 还有一个选择是使用CascadeType.ALL,表示选择全部四项。
* fetch:FetchType类型的属性。可选择项包括:FetchType.EAGER 和FetchType.LAZY。
* FetchType.EAGER:表示关系类(本例是OrderItem类)在主类加载的时候同时加载;
* FetchType.LAZY表示关系类在被访问时才加载。默认值是FetchType.LAZY。
* mappedBy:一定是定义在被拥有方(A)的,他指向拥有方(数据库表中有外键的一方,这个表所映射的对象为拥有方,
* B对象拥有A对象的主键所指向B对象的外键,既B对象有个外键关联的是A对象的主键)
* 拥有方能够自动维护跟被拥有方的关系,当然,如果从被拥有方,通过手工强行来维护拥有方的关系也是可以
* 做到的。
*/
@OneToOne(mappedBy="husband")
public Wife getWife() {
return wife;
}
public void setWife(Wife wife) {
this.wife = wife;
}
//无参的构造方法
public Husband() {
super();
}
//有参的构造方法
public Husband(Integer h_Id, String h_Name, String h_weight) {
super();
this.h_Id = h_Id;
this.h_Name = h_Name;
this.h_weight = h_weight;
}
//get和set方法
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getH_Id() {
return h_Id;
}
public void setH_Id(Integer h_Id) {
this.h_Id = h_Id;
}
public String getH_Name() {
return h_Name;
}
public void setH_Name(String h_Name) {
this.h_Name = h_Name;
}
public String getH_weight() {
return h_weight;
}
public void setH_weight(String h_weight) {
this.h_weight = h_weight;
}
//toString方法
@Override
public String toString() {
return "Husband [h_Id=" + h_Id + ", h_Name=" + h_Name + ", h_weight="
+ h_weight + "]";
}
}
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
*
*<p>Title:hibernate注解(一对一注解)</p>
*<p>Description:创建一个老婆类</p>
*<p>Company:www.bd.com</p>
*
* @author 陈大伟
* @date 2017年5月10日下午2:51:06
* @version 1.4
*/
@Entity
@Table(name="t_wife")
public class Wife
{
//老婆的Id
private Integer w_Id;
//老婆的姓名
private String w_Name;
//老婆的体重
private String w_weight;
//由于和老公是一对一的关系所以在老婆这边表示一下老公,同样的生成gat和set方法
private Husband husband;
/*********关联关系的get和set方法**********/
/**
* @JoinColumn
* 作用: @JoinColumn与@Column标记一样,是用于注解表中的字段的,它的属性与@Column属性有很多相同之处,
* 这里就不详细讲述。但要注意:@JoinColumn注解的是保存表与表之间关系的字段,它要标注在实体对象属性上。而
* @Column标注的是表中不包含表关系的字段(也就是表所映射对象的属性),这也是他们的区别
* 属性:
* name:表中外键字段的名称。在不设置这个属性时,默认遵循:关联表的名称+“_”+ 关联表主键的字段名 。
* 如:Wife对象关联Husband对象,而最后生成t_wife表中的外键名称是:husband_h_Id;
* referencedColumnName: 默认情况下,关联的实体的主键一般是用来做外键的。但如果此时不想主键作为外键
* 就要用到这个属性;在使用这个属性的时候我们要在关联对象(Husband)中加入ref_id属性,并生成get和
* set方法。注意:这个属性就是引用进关联对象中特意暴露出的属性。在数据库中生成表后外键字段的名称还是
* 由name属性指定的。
* insertable 可选,该列是否作为生成的insert语句中的一个列(默认值true)
* updatable 可选,该列是否作为生成的update语句中的一个列(默认值true)
* nullable 可选,该列的数据生成的时候是否可以为空(默认为false)
* unique可选,该列的数据是否具有唯一性(默认是false)
*/
@OneToOne(cascade=(CascadeType.ALL))
@JoinColumn(name="h_id",referencedColumnName="ref_id")
public Husband getHusband() {
return husband;
}
public void setHusband(Husband husband) {
this.husband = husband;
}
//无参的构造方法
public Wife() {
super();
}
//有参的构造方法
public Wife(Integer w_Id, String w_Name, String w_weight) {
super();
this.w_Id = w_Id;
this.w_Name = w_Name;
this.w_weight = w_weight;
}
//get和set方法
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getW_Id() {
return w_Id;
}
public void setW_Id(Integer w_Id) {
this.w_Id = w_Id;
}
public String getW_Name() {
return w_Name;
}
public void setW_Name(String w_Name) {
this.w_Name = w_Name;
}
public String getW_weight() {
return w_weight;
}
public void setW_weight(String w_weight) {
this.w_weight = w_weight;
}
//toString方法
@Override
public String toString() {
return "Wife [w_Id=" + w_Id + ", w_Name=" + w_Name + ", w_weight="
+ w_weight + "]";
}
}
数据库中生成表(不加ref_id)的表注意:在不进行非主键指定外键时应当把@JoinColumn的referencedColumnName属性去掉:
老公对象所映射的表(这里ref_id为空的原因是在保存的时候没有用参数里边有ref_id的构造器,所以进行对象保存时就没有数据插入)
老婆对象所映射的表
数据库中生成表(加ref_id)的表:
老公所映射的表:
老婆对象所映射的表:
测试的代码:
session=sessionFactory.openSession();
session.beginTransaction();
/**
* 对于下面的五行代码要注意的是:老公类的实例化对象必须先生成。
* 因为老婆对象的外键指向的是老公对象的主键,老公对象的主键都
* 没有生成,老婆对象的外键就没有办法指向,最后因为是级联保存
* 所以在save老婆对象的时候同时也就把老公对象所映射的表生成了
*/
Husband husband=new Husband(null,"牛郎", "120",UUID.randomUUID().toString());
Wife wife=new Wife(null,"织女", "100");
wife.setHusband(husband);
session.save(wife);
session.getTransaction().commit();
以上就是一对一对象关系映射。
二、一对多关系映射
介绍一对一关系映射我会以公司和公司中的部门为大家举例:
理思路:一个公司(Company)里有很多个部门(Department)。
公司对象代码:
package com.bd.cdw.pojo_t;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
*
*<p>Title:bibernate注解一对多</p>
*<p>Description:创建一个公司的类</p>
*<p>Company:www.bd.com</p>
*
* @author 陈大伟
* @date 2017年5月11日下午2:07:06
* @version 1.4
*/
@Entity
@Table(name="t_company")
public class Company implements Serializable {
private static final long serialVersionUID = 6125105276609947002L;
// 公司的编号
private Integer comId;
// 公司的名称
private String comName;
// 公司的老板
private String comBoss;
/***** 对象关系映射 *****/
//一个公司里有很多部门,所以把公司看成是一个Set容器,容器里面放置的就是很多部门
private Set<Department> deptSet=new HashSet<Department>();
/***** 对象关系映射 get和set方法*****/
/**
* @OneToMany
* 作用:指明A对象和B对象为一对多关系
* 用法:在需要有外键的私有化Set集合泛型为<多的一方的对象>的get方法上面使用(也就是在数据库中生成表,
* 那个表(t_B)有外键就在那个表所映射的私有化Set集合泛型(B)上使用,这个私有化Set集合泛型(B)一定是与这个
* 私有化Set集合泛型(B),具有一对多关系映射的对象(A类)中私有化Set集合泛型(B)生成get方法上使用。
* 属性:
* targetEntity:Class类型的属性。定义关系类的类型,默认是该成员属性对应的类类型,所以通常不需要提供定义。
* cascade:CascadeType[]类型。该属性定义类和类之间的级联关系。定义的级联关系将被容器视为对当前类对象及其
* 关联类对象采取相同的操作(既一处进行CRUD操作和其有关系的别处也同时进行CRUD操作)而且这种关系是递
* 归调用的。
* cascade的值(value)只能从:
* CascadeType.PERSIST(级联新建)
* CascadeType.REMOVE(级联删除)、
* CascadeType.REFRESH(级联刷新)、
* CascadeType.MERGE(级联更新)中选择一个或多个。
* 还有一个选择是使用CascadeType.ALL,表示选择全部四项。
* fetch:FetchType类型的属性。可选择项包括:FetchType.EAGER 和FetchType.LAZY。
* FetchType.EAGER:表示关系类(本例是OrderItem类)在主类加载的时候同时加载;
* FetchType.LAZY表示关系类在被访问时才加载。默认值是FetchType.LAZY。
* mappedBy:一定是定义在被拥有方(A)的,他指向拥有方(数据库表中有外键的一方,这个表所映射的对象为拥有方,
* B对象拥有A对象的主键所指向B对象的外键,既B对象有个外键关联的是A对象的主键)
* 拥有方能够自动维护跟被拥有方的关系,当然,如果从被拥有方,通过手工强行来维护拥有方的关系也是可以
* 做到的。值为在多的类中声明一的对象的引用。
*/
@OneToMany(mappedBy="company")
public Set<Department> getDeptSet() {
return deptSet;
}
public void setDeptSet(Set<Department> deptSet) {
this.deptSet = deptSet;
}
//无参的构造方法
public Company() {
super();
}
//有参的构造方法
public Company(Integer comId, String comName, String comBoss) {
super();
this.comId = comId;
this.comName = comName;
this.comBoss = comBoss;
}
//get和set方法
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getComId() {
return comId;
}
public void setComId(Integer comId) {
this.comId = comId;
}
public String getComName() {
return comName;
}
public void setComName(String comName) {
this.comName = comName;
}
public String getComBoss() {
return comBoss;
}
public void setComBoss(String comBoss) {
this.comBoss = comBoss;
}
//toString方法
@Override
public String toString() {
return "Company [comId=" + comId + ", comName=" + comName
+ ", comBoss=" + comBoss + "]";
}
}
部门对象代码:
package com.bd.cdw.pojo_t;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
*
*<p>Title:hibernate注解一对多</p>
*<p>Description:创建一个公司部门类</p>
*<p>Company:www.bd.com</p>
*
* @author 陈大伟
* @date 2017年5月11日下午2:08:08
* @version 1.4
*/
@Entity
@Table(name="t_department")
public class Department implements Serializable
{
private static final long serialVersionUID = 7197969878969565078L;
//公司部门的Id
private Integer deptId;
//部门的名称
private String deptName;
//部门的负责人
private String deptBoss;
/***** 对象关系映射 *****/
private Company company;
/***** 对象关系映射 get和set方法*****/
@ManyToOne(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
@JoinColumn(name="com_id")
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
//无参的构造器
public Department() {
super();
}
//有参的构造器
public Department(Integer deptId, String deptName, String deptBoss) {
super();
this.deptId = deptId;
this.deptName = deptName;
this.deptBoss = deptBoss;
}
//get和set方法
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getDeptId() {
return deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public String getDeptBoss() {
return deptBoss;
}
public void setDeptBoss(String deptBoss) {
this.deptBoss = deptBoss;
}
//toString方法
@Override
public String toString() {
return "Department [deptId=" + deptId + ", deptName=" + deptName
+ ", deptBoss=" + deptBoss + "]";
}
}
测试代码:
session=sessionFactory.openSession();
session.beginTransaction();
/**
* 对于下面的五行代码要注意的是:公司类的实例化对象必须先生成。
* 因为部门对象的外键指向的是公司对象的主键,公司对象的主键都
* 没有生成,部门对象的外键就没有办法指向,最后因为是级联保存
* 所以在save部门对象的时候同时也就把公司对象所映射的表生成了
*/
Company company=new Company(null,"京东","刘强东");
Department department=new Department(null,"人力资源部","刘总");
Department department1=new Department(null,"市场拓展部","马总");
Department department2=new Department(null,"运营监督部","陈总");
department.setCompany(company);
department1.setCompany(company);
department2.setCompany(company);
Company company1=new Company(null,"百度","李老板");
Department department3=new Department(null,"软件研发部","西门总");
Department department4=new Department(null,"行政监督部","东方总");
Department department5=new Department(null,"财务运行部","欧阳总");
department4.setCompany(company1);
department3.setCompany(company1);
department5.setCompany(company1);
session.save(company);
session.save(department);
session.save(department1);
session.save(department2);
session.save(company1);
session.save(department3);
session.save(department4);
session.save(department5);
session.getTransaction().commit();
数据库中生成的表:
t_comp表:
t_dept表:
三、多对一关系映射
介绍一对一关系映射我会以员工和部门的例子给大家举例:
在多对一中,一方不需要任何关系注解(基本注解还是要的@Entity、@Table等)如下代码:
package com.bd.cdw.pojo_t;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="t_dept")
public class Department1 implements Serializable
{
private static final long serialVersionUID = 6836165301183288015L;
//部门的Id
private Integer dep_Id;
//部门的名称
private String dep_Name;
//无参的构造方法
public Department1() {
super();
}
//有参的构造方法
public Department1(Integer dep_Id, String dep_Name) {
super();
this.dep_Id = dep_Id;
this.dep_Name = dep_Name;
}
//get和set方法
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getDep_Id() {
return dep_Id;
}
public void setDep_Id(Integer dep_Id) {
this.dep_Id = dep_Id;
}
public String getDep_Name() {
return dep_Name;
}
public void setDep_Name(String dep_Name) {
this.dep_Name = dep_Name;
}
//toString方法
@Override
public String toString() {
return "Department1 [dep_Id=" + dep_Id + ", dep_Name=" + dep_Name + "]";
}
}
多的一方只需要配置@ManyToOne和@JoinColumn这两个关系映射的配置和其他的基本注解;如下:
package com.bd.cdw.pojo_t;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
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_emp")
public class Employee implements Serializable
{
private static final long serialVersionUID = -4825087220293807947L;
// 员工的Id
private Integer emp_Id;
// 员工的名称
private String emp_Name;
/***** 对象关系映射 *****/
private Department1 department1;
/***** 对象关系映射 get和set方法*****/
@ManyToOne(cascade={CascadeType.ALL})
@JoinColumn(name="dep_Id")
public Department1 getDepartment1() {
return department1;
}
public void setDepartment1(Department1 department1) {
this.department1 = department1;
}
// 无参的构造方法
public Employee() {
super();
}
// 有参的构造方法
public Employee(Integer emp_Id, String emp_Name) {
super();
this.emp_Id = emp_Id;
this.emp_Name = emp_Name;
}
// get和set方法
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getEmp_Id() {
return emp_Id;
}
public void setEmp_Id(Integer emp_Id) {
this.emp_Id = emp_Id;
}
public String getEmp_Name() {
return emp_Name;
}
public void setEmp_Name(String emp_Name) {
this.emp_Name = emp_Name;
}
// toString方法
@Override
public String toString() {
return "Employee [emp_Id=" + emp_Id + ", emp_Name=" + emp_Name + "]";
}
}
测试代码:
session=sessionFactory.openSession();
session.beginTransaction();
Department1 department1=new Department1(null,"销售部");
Employee employee=new Employee(null,"小明");
Employee employee1=new Employee(null,"小花");
Employee employee2=new Employee(null,"小刘");
employee.setDepartment1(department1);;
employee1.setDepartment1(department1);
employee2.setDepartment1(department1);
session.save(department1);
session.save(employee);
session.save(employee1);
session.save(employee2);
session.getTransaction().commit();
数据库生成的表:
t_dept表:
t_emp表:
四、多对多关系映射
介绍一对一关系映射我会以老师学生的例给大家举例:
理清思路:一个老师可以对应多个学生,一个学生同时也具有很多的老师;
多对多这里通常有两种处理方式,一种是通过建立一张中间表,然后由任一一个多的一方来维护关联关系,另一种就是将多对多拆分成两个一对多的关联关系
通过中间表来维护关联关系:
Teacher对象:
package com.bd.cdw.pojo_t;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
@Entity
@Table(name="t_teacher")
public class Teacher implements Serializable
{
private static final long serialVersionUID = -1073962462508034470L;
//教师的Id
private Integer teac_Id;
//教师的姓名
private String teac_Name;
//关系映射,多对多可以理解为:两个都可以放置对方对象的容器,所以彼此创建一个以对方的对象为泛型的Set集合
private Set<Student> studentSet=new HashSet<Student>();
//关系映射get和set方法
/**
* @ManyToMany注解
* 作用:指明A对象和B对象为多对多的关系
* 用法:对象(A)中,声明以B对象为泛型的私有化Set集合,并生成get和set方法,在生成的get方法上用
* 属性:
* targetEntity:Class类型的属性。定义关系类的类型,默认是该成员属性对应的类类型,所以通常不需要提供定义。
* cascade:CascadeType[]类型。该属性定义类和类之间的级联关系。定义的级联关系将被容器视为对当前类对象及其
* 关联类对象采取相同的操作(既一处进行CRUD操作和其有关系的别处也同时进行CRUD操作)而且这种关系是递
* 归调用的。
* cascade的值(value)只能从:
* CascadeType.PERSIST(级联新建)
* CascadeType.REMOVE(级联删除)、
* CascadeType.REFRESH(级联刷新)、
* CascadeType.MERGE(级联更新)中选择一个或多个。
* 还有一个选择是使用CascadeType.ALL,表示选择全部四项。
* fetch:FetchType类型的属性。可选择项包括:FetchType.EAGER 和FetchType.LAZY。
* FetchType.EAGER:表示关系类(本例是OrderItem类)在主类加载的时候同时加载;
* FetchType.LAZY表示关系类在被访问时才加载。默认值是FetchType.LAZY。
* mappedBy:一定是定义在被拥有方(A)的,他指向拥有方(数据库表中有外键的一方,这个表所映射的对象为拥有方,
* B对象拥有A对象的主键所指向B对象的外键,既B对象有个外键关联的是A对象的主键)
* 拥有方能够自动维护跟被拥有方的关系,当然,如果从被拥有方,通过手工强行来维护拥有方的关系也是可以
* 做到的。
*/
@ManyToMany(mappedBy="teacherSet")
public Set<Student> getStudentSet() {
return studentSet;
}
public void setStudentSet(Set<Student> studentSet) {
this.studentSet = studentSet;
}
//无参的构造器
public Teacher() {
super();
// TODO Auto-generated constructor stub
}
//有参的构造器
public Teacher(Integer teac_Id, String teac_Name) {
super();
this.teac_Id = teac_Id;
this.teac_Name = teac_Name;
}
//get和set方法
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getTeac_Id() {
return teac_Id;
}
public void setTeac_Id(Integer teac_Id) {
this.teac_Id = teac_Id;
}
public String getTeac_Name() {
return teac_Name;
}
public void setTeac_Name(String teac_Name) {
this.teac_Name = teac_Name;
}
//toString方法
@Override
public String toString() {
return "Teacher [teac_Id=" + teac_Id + ", teac_Name=" + teac_Name + "]";
}
}
Student对象:
package com.bd.cdw.pojo_t;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
@Entity
@Table(name="t_student")
public class Student implements Serializable
{
private static final long serialVersionUID = 3190746987442043288L;
//学生的Id
private Integer stud_Id;
//学生的姓名
private String stud_Name;
//关系映射,多对多可以理解为:两个都可以放置对方对象的容器,所以彼此创建一个以对方的对象为泛型的Set集合
private Set<Teacher> teacherSet=new HashSet<Teacher>();
//关系映射get和set方法
/**
* @JoinTable
* 作用:中间关联表,在进行一对多或者多对多的时候要用到
* 用法:在拥有方中用(再具体就是:对象(B)中,声明以A对象为泛型的私有化Set集合,并生成get和set方法,在生成的get方法上用)
* 属性:
* name:(非必须)指定该连接表的表名;
* JoinColumns:(非必须)该属性值可接受多个@JoinColumn,用于配置连接表中外键列的信息,
* 这些外键列参照当前实体对应表的主键列;
* inverseJoinColumns:(非必须)该属性值可接受多个@JoinColumn,用于配置连接表中外
* 键列的信息,这些外键列参照当前实体的关联实体对应表的主键列;
* targetEntity:(非必须)该属性指定关联实体的类名。在默认情况下,Hibernate将通过反射来判断关联实体的类名;
* catalog:(非必须)设置将该连接表放入指定的catalog中。如果没有指定该属性,连接表将放入默认的catalog;
* schema:(非必须)设置将该连接表放入指定的schema中。如果没有指定该属性,连接表将放入默认的schema;
* uniqueConstraints:(非必须)该属性用于为连接表增加唯一约束;
* indexes:(非必须)该属性值为@Index注解数组,用于为该连接表定义多个索引;
*/
@ManyToMany(cascade={CascadeType.ALL})
@JoinTable
(name="t_teacher_student",joinColumns={@JoinColumn(name="stud_Id")},inverseJoinColumns={@JoinColumn(name="teach_Id")})
public Set<Teacher> getTeacherSet() {
return teacherSet;
}
public void setTeacherSet(Set<Teacher> teacherSet) {
this.teacherSet = teacherSet;
}
//无参的构造器
public Student() {
super();
// TODO Auto-generated constructor stub
}
//有参的构造器
public Student(Integer stud_Id, String stud_Name) {
super();
this.stud_Id = stud_Id;
this.stud_Name = stud_Name;
}
//get和set方法
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getStud_Id() {
return stud_Id;
}
public void setStud_Id(Integer stud_Id) {
this.stud_Id = stud_Id;
}
public String getStud_Name() {
return stud_Name;
}
public void setStud_Name(String stud_Name) {
this.stud_Name = stud_Name;
}
//toString方法
@Override
public String toString() {
return "Student [stud_Id=" + stud_Id + ", stud_Name=" + stud_Name + "]";
}
}
hibernate.cfg.xml文件(一到三部分都用的是这个配置文件):<mapping>中的class的值全部为实体类的全限定路径名。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_1</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">1111</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- <mapping class="com.bd.cdw.pojo.HibernateAnnotation"/> -->
<!-- <mapping class="com.bd.cdw.pojo.Address"/> -->
<!-- <mapping class="com.bd.cdw.pojo.Parcel"/> -->
<!-- <mapping class="com.bd.cdw.pojo.User"/> -->
<!-- <mapping class="com.bd.cdw.pojo_t.Wife"/> -->
<!-- <mapping class="com.bd.cdw.pojo_t.Husband"/> -->
<!-- <mapping class="com.bd.cdw.pojo_t.Employee"/> -->
<!-- <mapping class="com.bd.cdw.pojo_t.Department1"/> -->
<mapping class="com.bd.cdw.pojo_t.Teacher"/>
<mapping class="com.bd.cdw.pojo_t.Student"/>
</session-factory>
</hibernate-configuration>
测试代码:
session=sessionFactory.openSession();
session.beginTransaction();
Teacher teacher=new Teacher(null,"俞敏洪");
Teacher teacher1=new Teacher(null,"黄晓明");
Teacher teacher3=new Teacher(null,"邓超");
Student student=new Student(null,"小明");
Student student2=new Student(null,"小花");
student.getTeacherSet().add(teacher);
student2.getTeacherSet().add(teacher1);
student2.getTeacherSet().add(teacher3);
session.save(student);
session.save(student2);
session.getTransaction().commit();
数据库表格生成:
t_teacher表:
中间表:
t_studrnt表:
至此Hibernate注解开发就给大家介绍到这里了,这三部分的注解基本上是我们经常在开发中用到的,当然还有很多其他的注解比如像@Version、@Basic
等等的注解,这些注解不是在开发中不用。下面是我一二部分的地址,读者觉的可以的话可以打开看看:第一部分:http://blog.csdn.net/cdw2328/article
/details/71425184;第二部分:http://blog.csdn.net/cdw2328/article/details/71485130。