一、概述
接上一篇:Hibernate简单示例,进行研究实体关系映射。单边的一对多关系、单边的多对一关系、双边的多对一和一对多关系。
二、数据表结构
一个House有多个Cat。House与Cat是一对多的关系。
tb_cat表中有列:id、name、house_id
tb_house表中有列:id、name
三、单边的一对多关系---@OneToMany
@OneToMany用在少的一方,即用在House实体中。用@OneToMany注解表明一对多关系,@JoinColumn指定数据表对应的列。会在多的一方数据表中生成对应的列,即在tb_cat中有house_id列。
House和Cat实体类代码如下:
@Entity
@Table(name="tb_house")
public class House {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id; //主键、自增
private String name;
@OneToMany
@JoinColumn(name = "house_id")
private List<Cat> cats = new ArrayList<Cat>();
//set、get方法
}
@Entity
@Table(name="tb_cat")
public class Cat {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id; //主键、自增
private String name; //指定对应数据库的列为name
//set、get方法
}
四、单边的多对一关系---@ManyToOne
@ManyToOne用在多的一方,即用在Cat实体中。用@ManyToOne注解表明多对一关系,@JoinColumn指定数据表对应的列。会在多的一方数据表中生成对应的列,即在tb_cat中有house_id列。
House和Cat实体类代码如下:
@Entity
@Table(name="tb_house")
public class House {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id; //主键、自增
private String name;
//set、get方法
}
@Entity
@Table(name="tb_cat")
public class Cat {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id; //主键、自增
private String name; //指定对应数据库的列为name
@ManyToOne
@JoinColumn(name="house_id")
private House house;
//set、get方法
}
五、双边的多对一和一对多关系
如果同时需要使用@OneToMany和@ManyToOne,需要在@OneToMany用mappedBy属性,其值为多的一方实体类的属性。
如果不用mappedBy属性,在少的一个配置@OneToMany和@ManyToOne在其下面配置@JoinColumn(name="house_id"),会在Cat数据表中生成两个house_id列,在控制台会出现Error信息。所以此时用mappedBy属性配置会解决此冲突。
@Entity
@Table(name="tb_house")
public class House {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id; //主键、自增
private String name;
@OneToMany(mappedBy="house")
private List<Cat> cats = new ArrayList<Cat>();
//set、get方法
}
@Entity
@Table(name="tb_cat")
public class Cat {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id; //主键、自增
private String name; //指定对应数据库的列为name
@ManyToOne
@JoinColumn(name="houser_id")
private House house;
//set、get方法
}
六、用第三张表表明两个表的关系
前面通过外键的形式建立两个表的关系,还可以通过第三张表建立两个表的关系。
使用@JoinTable注解可以自动创建第三张关系表。
第三张表结构
tb_cat_house表中有列:cat_id、house_id
@Entity
@Table(name="tb_house")
public class House {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id; //主键、自增
private String name;
@OneToMany
@JoinTable(
name="tb_cat_house",
joinColumns=@JoinColumn(name="house_id",referencedColumnName="id"),
inverseJoinColumns=@JoinColumn(name="cat_id",referencedColumnName="id"))
private List<Cat> cats = new ArrayList<Cat>();
//set、get方法
}
@Entity
@Table(name="tb_cat")
public class Cat {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id; //主键、自增
private String name; //指定对应数据库的列为name
//set、get方法
}
七、测试
public class MyMain {
public static void main(String[] args) {
House houseOne = new House();
houseOne.setName("HouseOne");
House houseTwo = new House();
houseTwo.setName("HouseTwo");
Cat catOne = new Cat();
catOne.setName("CatOne");
Cat catTwo = new Cat();
catTwo.setName("CatTwo");
List<Cat> catList = new ArrayList<Cat>();
catList.add(catOne);
catList.add(catTwo);
houseOne.setCats(catList);
//开启一个Hibernate对话
Session session = HibernateUtil.getSessionfactory().openSession();
//开启事务
Transaction trans = session.beginTransaction();
//将catOne、catTwo保存进数据库
session.persist(houseOne);
session.persist(houseTwo);
//将catOne、catTwo保存进数据库
session.persist(catOne);
session.persist(catTwo);
//查询数据库,打印cat
List<Cat> cats = session.createQuery("select c from Cat c").list();
for (Cat cat : cats) {
System.out.println("cat: id=" + cat.getId() + " name:"+cat.getName());
}
//提交事务
trans.commit();
//关闭Hibernate对话
session.close();
}
}