1. Introduction
Bidirectional 1-N associations should try not to let one end of the 1 control the association, but use the N end to control the relationship. Bidirectional 1-N associations are exactly the same as N-1 associations. Both ends need to increase access to the association attributes. One end of N adds attributes that refer to the associated entity, and the end of 1 adds collection attributes and collection elements. for the associated entity.
For most 1-N associations, a join-less table strategy is sufficient.
2. Example demonstration:
(1) Create two tables: classroom table and person table (MySQL)
Table name: person
Create table statement:
CREATE TABLE `person` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`age` int(11) DEFAULT NULL,
`class_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `class_id` (`class_id`),
CONSTRAINT `person_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `classroom` (`classroom_id`) ON DELETE SET NULL ON UPDATE CASCADE
);
Table name: classroom
Create table statement:
CREATE TABLE `classroom` (
`classroom_id` int(11) NOT NULL AUTO_INCREMENT,
`classroom_name` varchar(50) NOT NULL,
PRIMARY KEY (`classroom_id`)
);
(2) Create two classes: ClassRoom class and Person class
ClassRoom.java
@Entity
@Table(name="classroom")
public class ClassRoom
{
@Id @Column(name="classroom_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@Column(name="classroom_name")
private String classRoomName;
//定义该ClassRoom实体所有关联的Person实体
//mappedBy用来表面该ClassRoom实体不控制关联关系
@OneToMany(targetEntity=Person.class,mappedBy="classRoom")
private Set<Person> personSet = new HashSet<>();
public ClassRoom() {}
public ClassRoom(String classRoomName)
{
this.classRoomName = classRoomName;
}
public Set<Person> getPersonSet()
{
return personSet;
}
public void setPersonSet(Set<Person> personSet)
{
this.personSet = personSet;
}
public String getClassRoomName()
{
return classRoomName;
}
public void setClassRoomName(String classRoomName)
{
this.classRoomName = classRoomName;
}
}
The above ClassRoom class adds a set collection attribute to record a series of Person entities associated with it, and uses @OneToMany to modify the collection attribute, indicating that this is a 1-N association. In addition, the Person side only needs to add a ClassRoom attribute, indicating that there is a 1-N relationship between the ClassRoom and the Person attribute.
Person.java
@Entity
@Table(name="person")
public class Person
{
@Id @Column(name="id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private String name;
private Integer age;
@ManyToOne(targetEntity=ClassRoom.class)
//定义名为class_id外键列,该外键列引用classroom表的classroom_id列
@JoinColumn(name="class_id",referencedColumnName="classroom_id",nullable=false)
private ClassRoom classRoom;
public Person() {}
public Person(String name,Integer age)
{
this.name = name;
this.age = age;
}
public Person(String name,Integer age,ClassRoom classRoom)
{
this.name = name;
this.age = age;
this.classRoom = classRoom;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Integer getAge()
{
return age;
}
public void setAge(Integer age)
{
this.age = age;
}
public void setClassRoom(ClassRoom classRoom)
{
this.classRoom = classRoom;
}
public ClassRoom getClassRoom()
{
return classRoom;
}
}
The above annotation uses @ManyToOne to represent the attribute of the associated entity, and also uses @JoinColumn to map the foreign key column. This annotation will control the addition of a foreign key column named class_id to the person table, which means that the person table will be used as a slave table.
(3) Add data
Run the following program:
public class Main
{
public static void main(String[] args)
{
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
Person p1 = new Person("Li",19);
Person p2 = new Person("Zhang",20);
ClassRoom classRoom = new ClassRoom("东阶教室");
session.persist(classRoom);
p1.setClassRoom(classRoom);
session.persist(p1);
p2.setClassRoom(classRoom);
session.persist(p2);
tx.commit();
HibernateUtil.closeSession();
}
}
HibernateUtil reference: https://blog.csdn.net/vipmao/article/details/51340525
After running, the data in the table is:
(4) Find examples
public class Main
{
public static void main(String[] args)
{
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
//获取所有ClassRoom对象
List list = session.createQuery("from ClassRoom as a").list();
for(Object o1 : list)
{
ClassRoom cr = (ClassRoom)o1;
//获取这个ClassRoom存储有对应person的set属性
Set set = cr.getPersonSet();
//输出Person的Name属性
for(Object o2 : set)
{
Person p = (Person)o2;
System.out.println(p.getName());
}
}
tx.commit();
HibernateUtil.closeSession();
}
}
The console will output:
Li
Zhang