一、概述
接上一篇: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(); } }