Hibernate association mapping: no join table bidirectional 1-N

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
write picture description here
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
write picture description here
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:
write picture description here

write picture description here

(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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325997899&siteId=291194637