Programming     Travel Logs     Life Is Good     Surfing Online     About Me
Nutrition books in the world. There is no book in life, there is no sunlight; wisdom without books, as if the birds do not have wings.
-Shakespeare
2018-06-10 13:28:14

Copy this link when reproducing:
http://www.casperlee.com/en/y/blog/179

There is no doubt that a single table is not enough. In my application, besides the table "day" which stores the general information of a day, I need other tables to store more information, such as the birthdays of famous celebrities. And these tables surely have relations. So I'm gonna learn how to handle these relations of tables in Spring MVC and Hibernate.

/Images/20170915/01.jpg

/Images/20170915/02.jpg

/Images/20170915/03.jpg

/Images/20170915/04.jpg

/Images/20170915/05.jpg

/Images/20170915/06.jpg

1. Create tables and relations between them in MySQL.

    I. Create the table "dayBirth":

mysql> use DayDB;
 Database changed
 mysql> create table dayBirth (
     -> dayBirthId int(4) primary key not null auto_increment,
     -> dayBirthDayId int(4) not null,
     -> dayBirthCelebName varchar(100) not null,
     -> dayBirthCelebTitle varchar(500) null,
     -> dayBirthYear char(4) not null,
     -> dayBirthCelebAchievement varchar(500) null,
     -> dayBirthCelebImage varchar(60) null
     -> );
 Query OK, 0 rows affected (0.62 sec)
 
 mysql> show tables;
 +-----------------+
 | Tables_in_daydb |
 +-----------------+
 | day             |
 | daybirth        |
 +-----------------+
 2 rows in set (0.03 sec)
 
 mysql>

    FYI: Referring to this page for the detail steps of handling with MySQL databases: http://www.casperlee.com/en/l/blog/90

    II. Create a relation between table "day" and table "dayBirth":

mysql> alter table dayBirth
     -> add constraint fk_dayBirthDayId foreign key (dayBirthDayId) references day(dayId);
 Query OK, 0 rows affected (1.06 sec)
 Records: 0  Duplicates: 0  Warnings: 0

   III. Input some example data into the table "dayBirth" for test purpose:

mysql> select * from day where dayKey = '0915';
 +-------+--------+---------+--------------------------------------------------------------------------------------------+
 | dayId | dayKey | dayName | dayDescription                                                                             |
 +-------+--------+---------+--------------------------------------------------------------------------------------------+
 |     2 | 0915   | Sep. 15 | September 15 is the 258th day of the year (259th in leap years) in the Gregorian calendar. |
 +-------+--------+---------+--------------------------------------------------------------------------------------------+
 1 row in set (0.06 sec)
 
 mysql> insert into dayBirth(dayBirthDayId, dayBirthCelebName, dayBirthCelebTitle, dayBirthYear, dayBirthCelebAchievement)
     -> values (2, 'Jolin Tsai', 'Taiwanese singer, songwriter, dancer, actress, and businesswoman',1980, '');
 Query OK, 1 row affected (0.06 sec)
 
 mysql> insert into dayBirth(dayBirthDayId, dayBirthCelebName, dayBirthCelebTitle, dayBirthYear, dayBirthCelebAchievement)
     -> values (2, 'Nana Owada', 'Japanese idol, singer, and actress',1999, '');
 Query OK, 1 row affected (0.05 sec)
 
 mysql> select * from dayBirth;
 +------------+---------------+-------------------+------------------------------------------------------------------+--------------+--------------------------+--------------------+
 | dayBirthId | dayBirthDayId | dayBirthCelebName | dayBirthCelebTitle                                               | dayBirthYear | dayBirthCelebAchievement | dayBirthCelebImage |
 +------------+---------------+-------------------+------------------------------------------------------------------+--------------+--------------------------+--------------------+
 |          1 |             2 | Jolin Tsai        | Taiwanese singer, songwriter, dancer, actress, and businesswoman | 1980         |                          | NULL               |
 |          2 |             2 | Nana Owada        | Japanese idol, singer, and actress                               | 1999         |                          | NULL               |
 +------------+---------------+-------------------+------------------------------------------------------------------+--------------+--------------------------+--------------------+
 2 rows in set (0.00 sec)

2. Create a class named "DayBirth" in the package "com.casperlee.today.domain", and put the following code in:

package com.casperlee.today.domain;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
 
 @Entity
 @Table(name="dayBirth")
 public class DayBirth {
 
 	@Id
 	@Column(name="dayBirthId")
 	@GeneratedValue(strategy=GenerationType.IDENTITY)
 	private int id;
 	
 	@Column(name="dayBirthCelebName")
 	private String celebrityName;
 	
 	@Column(name="dayBirthCelebTitle")
 	private String celebrityTitle;
 	
 	@Column(name="dayBirthYear")
 	private String year;
 	
 	@Column(name="dayBirthCelebAchievement")
 	private String celebrityAchievement;
 	
 	@Column(name="dayBirthCelebImage")
 	private String celebrityImage;
 	
 	@ManyToOne(targetEntity=Day.class, fetch = FetchType.LAZY)
 	@JoinColumn(name="dayBirthDayId", nullable = false, updatable = false)
 	private Day day;
 
 	public DayBirth() {
 		
 	}
 	
 	public int getId() {
 		return id;
 	}
 	public void setId(int id) {
 		this.id = id;
 	}
 
 	public String getCelebrityName() {
 		return celebrityName;
 	}
 
 	public void setCelebrityName(String celebrityName) {
 		this.celebrityName = celebrityName;
 	}
 
 	public String getCelebrityTitle() {
 		return celebrityTitle;
 	}
 
 	public void setCelebrityTitle(String celebrityTitle) {
 		this.celebrityTitle = celebrityTitle;
 	}
 
 	public String getYear() {
 		return year;
 	}
 
 	public void setYear(String year) {
 		this.year = year;
 	}
 
 	public String getCelebrityAchievement() {
 		return celebrityAchievement;
 	}
 
 	public void setCelebrityAchievement(String celebrityAchievement) {
 		this.celebrityAchievement = celebrityAchievement;
 	}
 
 	public String getCelebrityImage() {
 		return celebrityImage;
 	}
 
 	public void setCelebrityImage(String celebrityImage) {
 		this.celebrityImage = celebrityImage;
 	}
 	
 	public Day getDay() {
 		return day;
 	}
 
 	public void setDay(Day day) {
 		this.day = day;
 	}
 
 	@Override
 	public String toString() {
 		
 		return this.celebrityName;
 	}
 }

Note: The Annotation "@ManyToOne" is used to define a single-valued association to another entity class that has many-to-one multiplicity. Referring to this page for the detail: http://www.objectdb.com/api/java/jpa/ManyToOne

3. Modify the class "com.casperlee.today.domain.Day" to add a property "celebrityBirthdays".

package com.casperlee.today.domain;
 
 import java.util.List;
 
 import javax.persistence.CascadeType;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.OneToMany;
 import javax.persistence.Table;
 
 @Entity
 @Table(name="day")
 public class Day {
 
 	@Id
 	@Column(name="dayId")
 	@GeneratedValue(strategy=GenerationType.IDENTITY)
 	private int id;
 	
 	@Column(name="dayKey")
 	private String key;
 	
 	@Column(name="dayName")
 	private String name;
 	
 	@Column(name="dayDescription")
 	private String description;
 	
 	@OneToMany(targetEntity=DayBirth.class, cascade = CascadeType.ALL, 
 			mappedBy = "day", fetch = FetchType.EAGER)
 	private List<DayBirth> celebrityBirthdays;
 
 	public Day() {
 		
 	}
 	
 	public int getId() {
 		return id;
 	}
 	public void setId(int id) {
 		this.id = id;
 	}
 	public String getKey() {
 		return key;
 	}
 	public void setKey(String key) {
 		this.key = key;
 	}
 	public String getName() {
 		return name;
 	}
 	public void setName(String name) {
 		this.name = name;
 	}
 	public String getDescription() {
 		return description;
 	}
 	public void setDescription(String description) {
 		this.description = description;
 	}
 	
 	public List<DayBirth> getCelebrityBirthdays() {
 		return celebrityBirthdays;
 	}
 
 	public void setCelebrityBirthdays(List<DayBirth> celebrityBirthdays) {
 		this.celebrityBirthdays = celebrityBirthdays;
 	}
 
 	@Override
 	public String toString () {
 		
 		return this.name;
 	}
 }

Note: The Annotation "@OneToMany" is used to define a many-valued association with one-to-many multiplicity. Referring to this page for the detail: http://www.objectdb.com/api/java/jpa/OneToMany

4. Modify the configuration file "WebContent\WEB-INF\config\springmvc-config.xml" to include the class "com.casperlee.today.domain.DayBirth":

<bean id="hibernateAnnotatedSessionFactory"
       class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
       ...
       <property name="annotatedClasses">
         <list>
           ...
           <value>com.casperlee.today.domain.DayBirth</value>
         </list>
       </property>
       ...
     </bean>

5. Modify the .jsp file "WebContent\WEB-INF\jsp\DayForm.jsp" to display the celebrity birthdays.

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 <!DOCTYPE HTML>
 <html>
 <head>
 <title>Today in History</title>
 </head>
 <body>
 
 <div>
 ${day.id}
 </div>
 <div>
 ${day.name}
 </div>
 <div>
 ${day.description}
 </div>
 
 <div>------------------------</div>
 
 <c:forEach items="${day.celebrityBirthdays}" var="dayBirth">
 <div>
       ${dayBirth.year}  ${dayBirth.celebrityName}  ${dayBirth.celebrityTitle}
 </div>
 </c:forEach>
   
 </body>
 </html>

6. Right click on the "today" project, select "Run As -> Run on Server" on the popped menu to test if it works now.

/Images/20170915/101.jpg

7. Done! It works.