In the actual blog site, the amount of data on the content of the article is very much, it will affect the time we retrieve the other data of the article, such as query publication time, title, category and so on.
At this time, we can try to present the article content in a table, and then build up the article------one-to-one mapping of article content
There are two ways to relate one-to-a-foreign key associations. There is also a composite primary key association.
FOREIGN Key Association
Let's take a look at one-to-one unidirectional association example
/************* associated relationship maintainer party ************/@Table(name ="T_article")@Entity Public class article { @Id @GeneratedValue(strategy = Generationtype.auto)PrivateInteger ID;PrivateString title;@OneToOne(cascade = Cascadetype.all,fetch = Fetchtype.lazy,orphanremoval =true, targetentity = Articlecontent.class)@JoinColumn(name ="article_content_id")PrivateArticlecontent articlecontent;//Ignore Get and set methods}
Here is our article content class
@Table"t_article_content")@Entitypublicclass ArticleContent { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @Lob private String content; //忽略get和set方法}
Here's our test class.
Public class Test3 { PrivateApplicationContext AC;PrivateSessionfactory sessionfactory;PrivateSession session;PrivateTransaction Transaction;@BeforeClass//Call this method on test class initialization, complete initialization of static object Public Static void before(){ }@Before//Each annotated test method calls this method once before it is called Public void Setup(){//Establish sessions and transactions for our current test methodsAC =NewClasspathxmlapplicationcontext ("Spring-datasource.xml"); Sessionfactory = (sessionfactory) Ac.getbean ("Sessionfactory"); Session = Sessionfactory.opensession (); Transaction = Session.begintransaction (); }//test cascade Relationship Map Annotation configuration: one-to-one unidirectional association @Test Public void test1(){//test cascade joinArticle Article =NewArticle (); Article.settitle ("title"); Articlecontent articlecontent =NewArticlecontent (); Articlecontent.setcontent ("Content"); Article.setarticlecontent (articlecontent);//Establish mapping relationshipSession.save (articlecontent); Session.save (article);//test cascade Delete//Article Article = (article) session.get (article.class,1);//Session.delete (article); @After//Each annotated test method calls this method once after it has been called Public void teardown(){if(Transaction.isactive ()) {//Assuming the current transaction has not been committed, theTransaction.commit ();//Commit a transaction, mainly to prevent the transaction from being committed in the test, and submit it repeatedly} session.close ();}
Call our test method test1.
Console printing:
Hibernate:insert into t_article_content values (?)
Hibernate:insert into T_article (article_content_id, title) VALUES (?,?)
Now look at the database:
Mysql> Show tables; ———————————— Hibernate help us create a new form
+ ——————— +
| Tables_in_hibernate |
+ ——————— +
| t_article |
| t_article_content |
+ ——————— +
2 rows in Set (0.00 sec)
mysql> desc t_article; ———————————— maintain the mapping relationship, through article_content_id maintenance
+ —————— –+ ———— –+--+-–+ ——— + —————-+
| Field | Type | Null | Key | Default | Extra |
+ —————— –+ ———— –+--+-–+ ——— + —————-+
| ID | Int (11) | NO | PRI | NULL | auto_increment |
| Title | varchar (255) | YES | | NULL | |
| article_content_id | Int (11) | YES | MUL | NULL | |
+ —————— –+ ———— –+--+-–+ ——— + —————-+
3 Rows in Set (0.00 sec)
mysql> desc t_article_content;
+ ——— + ———-+--+-–+ ——— + —————-+
| Field | Type | Null | Key | Default | Extra |
+ ——— + ———-+--+-–+ ——— + —————-+
| ID | Int (11) | NO | PRI | NULL | auto_increment |
| Content | Longtext | YES | | NULL | |
+ ——— + ———-+--+-–+ ——— + —————-+
2 rows in Set (0.00 sec)
Mysql> select * from T_article;
+--+ ——-+ —————— –+
| ID | Title | article_content_id |
+--+ ——-+ —————— –+
| 1 | Title | 1 |
+--+ ——-+ —————— –+
1 row in Set (0.00 sec)
Mysql> select * from T_article_content;
+--+ ——— +
| ID | Content |
+--+ ——— +
| 1 | Content |
+--+ ——— +
1 row in Set (0.00 sec)
Gaze out the Cascade join section of the test code and perform the Cascade delete section:
Hibernate:delete from T_article where id=?
Hibernate:delete from T_article_content where id=?
Here, we observe that it is the first to delete the article (maintain the Relationship party). Then delete the t_article_content, recalling our previous one-to-many correlation test. is to delete the maintenance relationship first. This is actually very good understanding, we must clear out the corresponding correlation (the body is now the foreign key of the database) ability to complete the deletion of the associated content
One-to-one bidirectional association is very easy to add directly to the articlecontent:
@OneToOne"articleContent")private Article article;//忽略getter/setter
Use the same test code as above. Hibernate will help us generate tables and insert data:
Mysql> select * from T_article_content;
+--+ ——— +
| ID | Content |
+--+ ——— +
| 1 | Content |
+--+ ——— +
1 row in Set (0.00 sec)
Mysql> select * from T_article;
+--+ ——-+ —————— –+
| ID | Title | article_content_id |
+--+ ——-+ —————— –+
| 1 | Title | 1 |
+--+ ——-+ —————— –+
1 row in Set (0.00 sec)
It is assumed that we are attempting to cascade join on the articlecontent side of the Abort maintenance:
//測试articleContent级联加入new Article();article.setTitle("title"new ArticleContent();articleContent.setContent("content");articleContent.setArticle(article);session.save(articleContent);
Our article objects can be saved successfully. But. The relationship between the two has failed to establish:
Mysql> select * from T_article_content;
+--+ ——— +
| ID | Content |
+--+ ——— +
| 1 | Content |
| 2 | Content |
+--+ ——— +
2 rows in Set (0.00 sec)
Mysql> select * from T_article;
+--+ ——-+ —————— –+
| ID | Title | article_content_id |
+--+ ——-+ —————— –+
| 1 | Title | 1 |
| 2 | Title | NULL |
+--+ ——-+ —————— –+
2 rows in Set (0.00 sec)
At this point we try to remove from the Abort maintenance side:
//这次删除是有级联关系的1);//注意这里id为1session.delete(articleContent);
Mysql> select * from T_article_content;
+--+ ——— +
| ID | Content |
+--+ ——— +
| 5 | Content |
+--+ ——— +
1 row in Set (0.00 sec)
Mysql> select * from T_article;
+--+ ——-+ —————— –+
| ID | Title | article_content_id |
+--+ ——-+ —————— –+
| 6 | Title | NULL |
+--+ ——-+ —————— –+
1 row in Set (0.00 sec)
will see our corresponding article objects have also been deleted! Therefore, we need to understand that the abandonment of the relationship does not mean that the relationship is abandoned , from the articlecontent side, we can be associated with the relationship between the Cascade join, delete operations . Just not correct the relationship between the two to maintain. Thus the foreign key attribute of the article side at the time of the join Article_content_id=null
We discard the association using the Mappedby property. However, cascading operations are still valid, so there is a need to differentiate between maintenance-related relationships and cascading operations .
The special attention here is. In such a one-to-one mapping. We'd better choose a passive side and set the Mapperby property. That is, let one side abandon the maintenance of relationship, otherwise, we will see the following phenomenon:
mysql> desc t_article;
+ —————— –+ ———— –+--+-–+ ——— + —————-+
| Field | Type | Null | Key | Default | Extra |
+ —————— –+ ———— –+--+-–+ ——— + —————-+
| ID | Int (11) | NO | PRI | NULL | auto_increment |
| Title | varchar (255) | YES | | NULL | |
| article_content_id | Int (11) | YES | MUL | NULL | |
+ —————— –+ ———— –+--+-–+ ——— + —————-+
3 Rows in Set (0.00 sec)
mysql> desc t_article_content;
+ ———— + ———-+--+-–+ ——— + —————-+
| Field | Type | Null | Key | Default | Extra |
+ ———— + ———-+--+-–+ ——— + —————-+
| ID | Int (11) | NO | PRI | NULL | auto_increment |
| Content | Longtext | YES | | NULL | |
| article_id | Int (11) | YES | MUL | NULL | |
+ ———— + ———-+--+-–+ ——— + —————-+
3 Rows in Set (0.00 sec)
The associated mappings for each other are established in two tables.
This is completely unnecessary, and this will cause more serious consequences, let's test cascade join
First call for example the following test code:
//測试article级联加入new Article();article.setTitle("title"new ArticleContent();articleContent.setContent("content");article.setArticleContent(articleContent);session.save(article);
Then call for example the following test code:
//測试articleContent级联加入new Article();article.setTitle("title"new ArticleContent();articleContent.setContent("content");articleContent.setArticle(article);session.save(articleContent);
We will see the database corresponding records:
Mysql> select * from T_article;
+--+ ——-+ —————— –+
| ID | Title | article_content_id |
+--+ ——-+ —————— –+
| 1 | Title | 1 |
| 2 | Title | NULL |
+--+ ——-+ —————— –+
2 rows in Set (0.00 sec)
Mysql> select * from T_article_content;
+--+ ——— + ———— +
| ID | Content | article_id |
+--+ ——— + ———— +
| 1 | Content | NULL |
| 2 | Content | 2 |
+--+ ——— + ———— +
2 rows in Set (0.00 sec)
That is, the relationship between the two sides of each maintenance. Let's say we try to exchange test cascade deletions at this time:
Article article = (Article) session.get(Article.class,2);session.delete(article);
You will see results such as the following:
Mysql> select * from T_article;
+--+ ——-+ —————— –+
| ID | Title | article_content_id |
+--+ ——-+ —————— –+
| 1 | Title | 1 |
+--+ ——-+ —————— –+
1 row in Set (0.00 sec)
Mysql> select * from T_article_content;
+--+ ——— + ———— +
| ID | Content | article_id |
+--+ ——— + ———— +
| 1 | Content | NULL |
| 2 | Content | 2 |
+--+ ——— + ———— +
2 rows in Set (0.00 sec)
Cascade Delete failed, which is obvious. Because of the article with ID 2, the corresponding article_content_id property is null, and in the article's view, neither of them establishes an association. This is certainly not an error is the cascade delete failure, and the error is due to the assumption that the database set in T_article_content the article_id of the Foreign Key Association, due to the existence of records article_id= 2, when we try to delete the record with ID 2 in the article table, the error will be due to the foreign key relationship constraint failure .
Hibernate5 (12) annotation map [4] One-to-one foreign key association