????? In the previous article, we mapped a single entity class through the annotation pair, but the entity classes are related to each other in the project, this article is the different relation angle from the entity class, the specific learning how to map their association, the main content is as follows:
- One-way relational mapping
- A one-way, many-to-one correlation relationship mapping
- One-to-many relational mappings
- A one-way, many-to-many association relationship mapping
- Bidirectional one-to-one relational mapping
- Bidirectional one-to-many relational mappings
- Bidirectional many-to-many correlation relation mappings
A one-way, one-on relational mapping
First of all, we need to know what two tables have a one-on correlation.
This is a typical one-way relationship, in which a single record is the only one in the primary table that corresponds to a record from the table. But how do we write to our entity classes? Let's look at a full mapping code and then gradually explain the related annotations.
//定义实体类userinfo@Entity@Table(name = "userinfo")public class UserInfo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int user_id; private String name; private int age; @OneToOne(targetEntity = UserCode.class) @JoinColumn(name = "code",referencedColumnName = "code_id",unique = true) private UserCode userCode; //省略getter,setter方法}
//定义实体类usercode@Entity@Table(name = "code")public class UserCode { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int code_id; private String code; //省略getter,setter方法}
Because it is one-way, so our usercode table does not exist the foreign key column can directly access to the UserInfo table, so its entity class configuration is no special place. While the UserInfo entity class defines a property of type Usercode, when we insert or return data using Hibernate, the corresponding record in the Usercode table is loaded in this attribute, and of course, we also configure the Foreign Key association relationship.
@OneToOne Note Specifies that this is a one-to-two association, targetentity specifies the entity class type being associated. @JoinColumn is used to configure the foreign key column, the Name property specifies the column name of the foreign key column, and Hibernate adds a field in the UserInfo table for the Foreign key column. The Referencedcolumnname property is used to specify the table field that the foreign key column uses for reference, and here we refer to the primary key of the usercode. Because it is one-to-ones, it is required that the foreign key column cannot be duplicated, specifying unique unique constraints.
Compare the fields in the table to see the meanings of the individual values of the attributes in the above annotations again.
Two, one-way, many-to-one correlation relation mapping
Still, before studying in detail, let's look at what two tables make up a many-to-one relationship.
Like this, many different records in the UserInfo table correspond to a record in the Usersex table, which we call a many-to-one association. Many of them have foreign key columns, which control the maintenance of the relationship. Look at the code:
//定义usersex实体类@Entity@Table(name = "userSex")public class UserSex { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int sex_id; private String sex; //省略getter,setter方法}
//定义userinfo实体类@Entity@Table(name = "userinfo")public class UserInfo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int uid; private String name; private int age; @ManyToOne(targetEntity = UserSex.class) @JoinColumn(name = "sex",referencedColumnName = "sex_id") private UserSex userSex; //省略getter,setter方法}
Similarly, @ManyToOne specifies that this is a many-to-one relationship and that the entity type being associated is specified through the Targetentity property. @JoinColumn is still used to configure foreign key columns.
Compare the fields in the table to see the meanings of the individual values of the attributes in the above annotations again.
Three-way one-to-many relational mappings
One-to-many and one-way multiple-to-one is a completely different relationship between the two kinds of tables. Although the two tables seem to be of no great difference, the maintainer of the relationship is indeed diametrically opposed. In this case, the relationship between the two tables is maintained by one party, so at one end of the list you need to define a collection property to map a collection of records at a multiple end, looking at the code:
//定义一的一端的实体类@Entity@Table(name = "userSex")public class UserSex { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int sex_id; private String sex; @OneToMany(targetEntity = UserInfo.class) @JoinColumn(name = "sex",referencedColumnName = "sex_id") private Set users; //省略getter,setter方法}
//定义多的一端的实体类@Entity@Table(name = "userinfo")public class UserInfo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int uid; private String name; private int age; //省略getter,setter方法}
Where @OneToMany specifies a one-to-many association between two tables, the Targetentity property specifies the entity class type being associated. The @joincolumn here is not the same, it generates a foreign key field, but it is not generated in the data table represented by this entity class, but is generated in the associated data table. The Name property specifies the field name of the foreign key field, and the Referencedcolumnname property specifies that the value of the foreign key field depends on the field in the table (we let him rely on Usersex's primary key).
Actually one-to-many is a reverse association of many to one, but the two tables are still maintained by a foreign key column, but the foreign key column is a bit different from who generated it. The specific table structure is no longer posted here, and we can feel the next-to-many relational table by inserting data.
UserInfo user1 = new UserInfo("a",1);UserInfo user2 = new UserInfo("b",55);UserInfo user3 = new UserInfo("c",4);UserInfo user4 = new UserInfo("d",3);Set<UserInfo> sets = new HashSet<UserInfo>();sets.add(user1);sets.add(user2);sets.add(user3);sets.add(user4);UserSex userSex = new UserSex();userSex.setSex("男");userSex.setUsers(sets);session.save(user1);session.save(user2);session.save(user3);session.save(user4);session.save(userSex);
When we execute the above procedure, hibernate first inserts four UserInfo records into the UserInfo table (where the foreign key word blank), and then inserts a record into the Usersex table, after which Hibernate executes such an SQL statement sequentially based on the elements in the Set collection:
update userinfo set sex=? where uid=?
Obviously, the UserInfo table is positioned based on the ID value of each element in the collection, and the foreign key field of those elements is assigned the same value as the primary key value of the current Usersex instance. So the two tables formed the corresponding relationship. Of course, when we want to take out a Usersex instance, Hibernate also takes the instance's primary key value to search for the UserInfo table and loads the matching records into the set collection.
However, it is a bit counter-conventional logic to manage relationships at one end, so it is not recommended to use one end to manage the entire association relationship.
Four, one-way, many-to-many correlation relation mappings
For a one-way, many-to-many association relationship, we cannot use foreign key columns for management. Therefore, a supplementary table is usually added to maintain the relationship between the two tables, for example: a person can have more than one hobby, a hobby can also correspond to many people, I can get to a person all interests, also can get the same interests of all people. If you use only two tables to describe the relationship, you can't describe it at all, and you can try it, even if you can, the table structure is extremely complex and redundant. The best strategy now is to introduce a third-party table to maintain a many-to-many association between the two tables.
This table structure is clear and easy to maintain. Here's a look at the code implementation:
//定义hobby实体类@Entity@Table(name = "hobby")public class Hobby { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int hobby_id; private String hobby; //省略getter,setter方法}
//定义实体类userinfo@Entity@Table(name = "userinfo")public class UserInfo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int user_id; private String name; private int age; @ManyToMany(targetEntity = Hobby.class) @JoinTable(name = "connectTable", joinColumns = @JoinColumn(name = "user_id",referencedColumnName = "user_id"), inverseJoinColumns = @JoinColumn(name = "hobbyid",referencedColumnName = "hobbyid") ) private Set sets; //省略getter,setter方法}
Many-to-many association mappings require the use of an annotation @jointable, which is used to specify information about the newly generated connection table. The Name property specifies the table name, Joincolumns configures the foreign key column and its Dependent property fields, and here we specify a column named user_id in the new table and a value that depends on the primary key field of the UserInfo entity Inversejoincolumns Used to specify the foreign key column of the associated entity class, where we will generate a column name Hobbyid in the new table and rely on the primary key value of the hobby entity class.
When we insert the data, we first insert the records of the two tables separately, and then insert them into the join table based on the elements in the collection properties in the UserInfo table. The return data is similar.
Five, two-way one-to-one relational mapping
In fact, the difference between one-way association and two-way correlation is that one-way relationship, only a party exists on the other side of the reference, that is, the foreign key column can point to the other party, and the referenced party does not have a foreign key column pointing to others, so the whole relationship is only one side of the maintenance. The two-way relationship is that both sides have the ability to maintain relationship and can access each other. Let's look at the mapping of entity classes:
//定义userinfo实体类@Entity@Table(name = "userinfo")public class UserInfo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int user_id; private String name; private int age; @OneToOne(targetEntity = UserCode.class) @JoinColumn(name = "code",referencedColumnName = "code_id",unique = true) private UserCode userCode; //省略getter,setter方法}
//定义usercode实体类@Entity@Table(name = "code")public class UserCode { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int code_id; private String code; @OneToOne(targetEntity = UserInfo.class,mappedBy = "userCode") private UserInfo userInfo; //省略getter,setter方法}
When mapping bi-directional one-to-two relationships, you need to use the @onetoone modifier on both ends, and we add a foreign key column to the UserInfo side and point to Usercode's primary key. Often two tables as long as one side to maintain the relationship on the line, do not recommend the two sides at the same time maintain the relationship, that will cause loss of performance, we specify the value of the Mappedby property to tell the Hibernate,usercode side does not intend to maintain the relationship. When we specify a two-way relationship, both sides have a reference to each other, to achieve the ability to exchange visits.
Some people may have doubts, usercode one end of the management of the relationship does not set the foreign key column, then how do we get the UserInfo reference by Usercode? The answer is:
//从usercode查到userinfo表的引用UserCode userCode = (UserCode) session.get(UserCode.class,1);
Hibernate connects two tables based on the value of the foreign key column and the primary key value of the Usercode table, so we can check the records of the two tables at once by Usercode's primary key, and return the corresponding instance for us.
It is relatively easy to find a reference to the Usercode table through the UserInfo table, because a foreign key column is available in the UserInfo table. Check the table two times.
Six, two-way, one-to-many relational mappings
In fact, two-way multi-and two-way multi-to-one is the same kind of association, but the dominant relationship is not the same person. Look at the code:
//定义userinfo实体类@Entity@Table(name = "userinfo")public class UserInfo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int uid; private String name; private int age; @ManyToOne(targetEntity = UserSex.class) @JoinColumn(name = "sex_id",referencedColumnName = "sex_id",nullable = false) private UserSex userSex; //省略getter,setter方法}
//定义usersex实体类@Entity@Table(name = "userSex")public class UserSex { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int sex_id; private String sex; @OneToMany(targetEntity = UserInfo.class,mappedBy = "userSex") private Set users; //省略getter,setter方法}
One end uses the @onetomany adornment and discards the maintenance of the relationship, the many end uses the @manytoone adornment, and increases the foreign key column to point to the Usersex table's primary key column. In fact, and we introduced the one-way many-to-one basic, but here at one end of the addition of a one-to-many mappings, adding a reference to the UserInfo table.
For us to access the foreign key columns directly from one end of the access to the other, from one end to the other, the following two SQL statements are generated:
First check the Usersex table based on the primary key value of the Usersex, then check the UserInfo table by Usersex's primary key value, and all the UserInfo records will be injected into the Usersex collection properties.
Seven, two-way multi-to-many correlation relation mapping
A bidirectional multi-to-many relationship mapping still needs to be connected through the third secondary table. Still use our userinfo and hobby for example:
//定义实体类userinfo@Entity@Table(name = "userinfo")public class UserInfo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int user_id; private String name; private int age; @ManyToMany(targetEntity = Hobby.class) @JoinTable(name = "connectTable", joinColumns = @JoinColumn(name = "user_id",referencedColumnName = "user_id"), inverseJoinColumns = @JoinColumn(name = "hobby_id",referencedColumnName = "hobby_id") ) private Set sets = new HashSet(); //省略getter,setter方法}
//定义实体类hobby@Entity@Table(name = "hobby")public class Hobby { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int hobby_id; private String hobby; @ManyToMany(targetEntity = UserInfo.class) @JoinTable(name = "connectTable", joinColumns = @JoinColumn(name = "hobby_id",referencedColumnName = "hobby_id"), inverseJoinColumns = @JoinColumn(name = "user_id",referencedColumnName = "user_id") ) private Set sets = new HashSet(); //省略getter,setter方法}
Many-to-many ends need to specify the connection table information, but the configuration is the same table information, basically no change. We have also introduced these annotations, and we will not repeat them here. For example, if we want to get a userinfo instance, hibernate will first check the UserInfo table based on the specified primary key value, and then when it needs to use the relevant information of the Usersex table, Hibernate takes UserInfo's primary key value again to check the Connect connection table, and injects the found Usersex instance set into the UserInfo collection properties.
In summary, we introduce some common relationships in relational database, and introduce how Hibernate uses annotations to map entity classes. In general, one-way relationship and two-way correlation have one of the most essential differences, and there is a bidirectional correlation between the tables, each has a reference to each other, that is, can access each other. The one-way association is always only accessible to the other party.
When the reader is using these relationships in the actual project development, the mapping operation of hibernate will be more deeply understood. Summary of the place, hope to point out!
Hibernate Framework Learning Annotation Configuration Relationship Mapping