Programming     Travel Logs     Life Is Good     Surfing Online     About Me
Pick an industry where you can play long term games with long term people.
-Naval Ravikant
2018-06-10 13:47:04

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

I've learned several techniques that I need to know to create this application, and I also have added the "Birthday of celebrities" information to my "Today in History" application. Now it is time to finish the main part of this application: displaying all kinds of information of today in history.

/Images/20170918/01.jpg

/Images/20170918/02.jpg

/Images/20170918/03.jpg

/Images/20170918/04.jpg

/Images/20170918/05.jpg

/Images/20170918/06.jpg

1. Run the following command to create extra tables (dayDeath, dayEvent, dayFestival), and add columns to the table "day":

mysql> alter table day
    -> add column dayCeleb varchar(60) null;
mysql> alter table day
    -> add column dayCelebImage varchar(100) null;
mysql> alter table day
    -> add column dayCelebDesc varchar(2000) null;
mysql> create table dayDeath (
    -> dayDeathId int(4) primary key not null auto_increment,
    -> dayDeathDayId int(4) not null,
    -> dayDeathCelebName varchar(100) not null,
    -> dayDeathCelebTitle varchar(500) null,
    -> dayDeathYear char(4) not null,
    -> dayDeathCelebAchievement varchar(500) null,
    -> dayDeathCelebImage varchar(60) null
    -> );
mysql> alter table dayDeath
    -> add constraint fk_dayDeathDayId foreign key (dayDeathDayId) references day(dayId);
mysql> create table dayEvent (
    -> dayEventId int(4) primary key not null auto_increment,
    -> dayEventDayId int(4) not null,
    -> dayEventYear char(4) not null,
    -> dayEventDesc varchar(2000) not null,
    -> dayEventImage varchar(100) null,
    -> dayEventImageDesc varchar(60) null
    -> );
mysql> alter table dayEvent
    -> add constraint fk_dayEventDayId foreign key (dayEventDayId) references day(dayId);	
mysql> create table dayFestival (
    -> dayFestivalId int(4) primary key not null auto_increment,
    -> dayFestivalDayId int(4) not null,
    -> dayFestivalName varchar(60) not null,
    -> dayFestivalDesc varchar(2000) not null,
    -> dayFestivalDescShort varchar(200) null,
    -> dayFestivalSortKey char(4) null default '0000'
    -> );	
mysql> alter table dayFestival
    -> add constraint fk_dayFestivalDayId foreign key (dayFestivalDayId) references day(dayId);

FYI: Check the link http://www.casperlee.com/en/l/blog/90 for more information about dealing with MySQL database.

2. To support Chinese, run the following command to change the character set configuration of the tables:

mysql> alter table day convert to character set utf8;
mysql> alter table dayBirth convert to character set utf8;
mysql> alter table dayDeath convert to character set utf8;
mysql> alter table dayEvent convert to character set utf8;
mysql> alter table dayFestival convert to character set utf8;

3. Create a class named "DayEvent" in the package "com.casperlee.today.domain":

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="dayEvent")
public class DayEvent {

	@Id
	@Column(name="dayEventId")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	
	@Column(name="dayEventYear")
	private String year;
	
	@Column(name="dayEventDesc")
	private String eventDescription;
	
	@Column(name="dayEventImage")
	private String eventImage;
	
	@Column(name="dayEventImageDesc")
	private String eventImageDescription;
	
	@ManyToOne(targetEntity=Day.class, fetch = FetchType.LAZY)
	@JoinColumn(name="dayEventDayId", nullable = false, updatable = false)
	private Day day;

	public DayEvent() {
		
	}
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}

	public String getYear() {
		return year;
	}

	public void setYear(String year) {
		this.year = year;
	}

	public String getEventDescription() {
		return eventDescription;
	}

	public void setEventDescription(String eventDescription) {
		this.eventDescription = eventDescription;
	}

	public String getEventImage() {
		return eventImage;
	}

	public void setEventImage(String eventImage) {
		this.eventImage = eventImage;
	}

	public String getEventImageDescription() {
		return eventImageDescription;
	}

	public void setEventImageDescription(String eventImageDescription) {
		this.eventImageDescription = eventImageDescription;
	}

	public Day getDay() {
		return day;
	}

	public void setDay(Day day) {
		this.day = day;
	}

	@Override
	public String toString() {
		
		return this.eventDescription;
	}

}

4. Create a class named "DayDeath" in the package "com.casperlee.today.domain":

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="dayDeath")
public class DayDeath {

	@Id
	@Column(name="dayDeathId")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	
	@Column(name="dayDeathCelebName")
	private String celebrityName;
	
	@Column(name="dayDeathCelebTitle")
	private String celebrityTitle;
	
	@Column(name="dayDeathYear")
	private String year;
	
	@Column(name="dayDeathCelebAchievement")
	private String celebrityAchievement;
	
	@Column(name="dayDeathCelebImage")
	private String celebrityImage;
	
	@ManyToOne(targetEntity=Day.class, fetch = FetchType.LAZY)
	@JoinColumn(name="dayDeathDayId", nullable = false, updatable = false)
	private Day day;

	public DayDeath() {
		
	}
	
	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;
	}
}

5. Create a class named "DayFestival" in the package "com.casperlee.today.domain":

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="dayFestival")
public class DayFestival {
	
	@Id
	@Column(name="dayFestivalId")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	
	@Column(name="dayFestivalName")
	private String festivalName;
	
	@Column(name="dayFestivalDesc")
	private String festivalDescription;
	
	@Column(name="dayFestivalDescShort")
	private String festivalDescriptionShort;
	
	@Column(name="dayFestivalSortKey")
	private String sortKey;
	
	@ManyToOne(targetEntity=Day.class, fetch = FetchType.LAZY)
	@JoinColumn(name="dayFestivalDayId", nullable = false, updatable = false)
	private Day day;

	public DayFestival() {
		
	}
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}

	public String getFestivalName() {
		return festivalName;
	}

	public void setFestivalName(String festivalName) {
		this.festivalName = festivalName;
	}

	public String getFestivalDescription() {
		return festivalDescription;
	}

	public void setFestivalDescription(String festivalDescription) {
		this.festivalDescription = festivalDescription;
	}

	public String getFestivalDescriptionShort() {
		return festivalDescriptionShort;
	}

	public void setFestivalDescriptionShort(String festivalDescriptionShort) {
		this.festivalDescriptionShort = festivalDescriptionShort;
	}

	public String getSortKey() {
		return sortKey;
	}

	public void setSortKey(String sortKey) {
		this.sortKey = sortKey;
	}

	public Day getDay() {
		return day;
	}

	public void setDay(Day day) {
		this.day = day;
	}

	@Override
	public String toString() {
		
		return this.festivalName;
	}
}

6. Modify the configuration file "WebContent\WEB-INF\config\springmvc-config.xml" to include the classes that have been just created:

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

7. Modify the class "com.casperlee.today.domain.Day" to include the columns and sub-level tables that have been just added:

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.OrderBy;
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;
	
	@Column(name="dayCeleb")
	private String celebrityOfToday;

	@Column(name="dayCelebImage")
    private String celebrityImagePath;
    
	@Column(name="dayCelebDesc")
	private String celebrityDescription;
	
	@OneToMany(targetEntity=DayEvent.class, cascade = CascadeType.ALL, 
			mappedBy = "day", fetch = FetchType.LAZY)
	@OrderBy("year ASC")
	private List<DayEvent> historicalEvents;
	
	@OneToMany(targetEntity=DayBirth.class, cascade = CascadeType.ALL, 
			mappedBy = "day", fetch = FetchType.LAZY)
	@OrderBy("year ASC")
	private List<DayBirth> celebrityBirthdays;
	
	@OneToMany(targetEntity=DayDeath.class, cascade = CascadeType.ALL, 
			mappedBy = "day", fetch = FetchType.LAZY)
	@OrderBy("year ASC")
	private List<DayDeath> celebrityDeaths;
	
	@OneToMany(targetEntity=DayFestival.class, cascade = CascadeType.ALL, 
			mappedBy = "day", fetch = FetchType.LAZY)
	@OrderBy("sortKey ASC")
	private List<DayFestival> festivals;

	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 String getCelebrityOfToday() {
		return celebrityOfToday;
	}

	public void setCelebrityOfToday(String celebrityOfToday) {
		this.celebrityOfToday = celebrityOfToday;
	}

	public String getCelebrityImagePath() {
		return celebrityImagePath;
	}

	public void setCelebrityImagePath(String celebrityImagePath) {
		this.celebrityImagePath = celebrityImagePath;
	}

	public String getCelebrityDescription() {
		return celebrityDescription;
	}

	public void setCelebrityDescription(String celebrityDescription) {
		this.celebrityDescription = celebrityDescription;
	}

	public List<DayEvent> getHistoricalEvents() {
		return historicalEvents;
	}

	public void setHistoricalEvents(List<DayEvent> historicalEvents) {
		this.historicalEvents = historicalEvents;
	}

	public List<DayBirth> getCelebrityBirthdays() {
		return celebrityBirthdays;
	}

	public void setCelebrityBirthdays(List<DayBirth> celebrityBirthdays) {
		this.celebrityBirthdays = celebrityBirthdays;
	}

	public List<DayDeath> getCelebrityDeaths() {
		return celebrityDeaths;
	}

	public void setCelebrityDeaths(List<DayDeath> celebrityDeaths) {
		this.celebrityDeaths = celebrityDeaths;
	}

	public List<DayFestival> getFestivals() {
		return festivals;
	}

	public void setFestivals(List<DayFestival> festivals) {
		this.festivals = festivals;
	}

	@Override
	public String toString () {
		
		return this.name;
	}
}

8. Create a folder named "Images" in the "WebContent" directory, so that we can store images here and refer to them in the application.

Note: we need to add the following text into configuration file "WebContent\WEB-INF\config\springmvc-config.xml" to indicate the "Images" folder contains static resources:

<mvc:resources mapping="/Images/**" location="/Images/"/>

9. Create a folder named "css" in the "WebContent" directory, and create a file named "main.css" in the "css" folder. Here is the content of the file "main.css":

#divCatalog {
    text-align: left;
    margin: 48px auto 0px 48px;
}

#divCelebOfToday {
    text-align: left;
    margin: 48px auto;
}
#divEvents {
    text-align: left;
    margin: 48px auto;
}
#divCelebBorn {
    text-align: left;
    margin: 48px auto;
}
#divCelebPassed {
    text-align: left;
    margin: 48px auto;
}
#divFestivals {
    text-align: left;
    margin: 48px auto;
}

10. Modify the .jsp file "WebContent\WEB-INF\jsp\DayForm.jsp" to display more information:

<%@ page contentType="text/html; charset=gb2312"%>
<%@ 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>历史上的今天</title>
    <style type="text/css">@import url("<c:url value="/css/main.css"/>");</style>
  </head>
<body>

<div>
  <h1>${day.name}</h1>
</div>

<div>
  <p>
    ${day.description}
  </p>
</div>

<div id="divCatalog">
  <h3>目录</h3>
  <c:if test="${day.celebrityOfToday != null && day.celebrityOfToday != ''}">
    <a href="#divCelebOfToday">今日人物</a><br />
  </c:if>
  <a href="#divEvents">重大事件</a><br />
  <a href="#divCelebBorn">出生名人</a><br />
  <a href="#divCelebPassed">逝世名人</a><br />
  <a href="#divFestivals">节日风俗</a>
</div>

<c:if test="${day.celebrityOfToday != null && day.celebrityOfToday != ''}">
<div id="divCelebOfToday">
  <div>
    <h2>今日人物</h2>
  </div>
  <div>
    <img alt="${day.celebrityOfToday}" src="${day.celebrityImagePath}" width="600px" height="100%">
  </div>
  <div>
    <p>
      ${day.celebrityDescription}
    </p>
  </div>
</div>
</c:if>

<div id="divEvents">
  <h2>重大事件</h2>
  <p>
  <c:forEach items="${day.historicalEvents}" var="dayEvent">
    <div>
      ${dayEvent.year}, ${dayEvent.eventDescription}
    </div>
  </c:forEach>
  </p>
</div>

<div id="divCelebBorn">
  <h2>出生名人</h2>
  <p>
  <c:forEach items="${day.celebrityBirthdays}" var="dayBirth">
    <div>
      ${dayBirth.year}, ${dayBirth.celebrityName}, ${dayBirth.celebrityTitle}
      <c:if test="${dayBirth.celebrityAchievement != null && dayBirth.celebrityAchievement != ''}">
              (主要成就:${dayBirth.celebrityAchievement})
      </c:if>
    </div>
  </c:forEach>
  </p>
</div>

<div id="divCelebPassed">
  <h2>逝世名人</h2>
  <p>
  <c:forEach items="${day.celebrityDeaths}" var="dayDeath">
    <div>
      ${dayDeath.year}, ${dayDeath.celebrityName}, ${dayDeath.celebrityTitle}
      <c:if test="${dayDeath.celebrityAchievement != null && dayDeath.celebrityAchievement != ''}">
              (主要成就:${dayDeath.celebrityAchievement})
      </c:if>
    </div>
  </c:forEach>
  </p>
</div>

<div id="divFestivals">
  <h2>节日风俗</h2>
  <p>
  <c:forEach items="${day.festivals}" var="dayFestival">
    <div>
      <h3>${dayFestival.festivalName}</h3>
    </div>
    <div>
    <p>
      ${dayFestival.festivalDescriptionShort}
    </p>
    </div>
    <div>
    <p>
      ${dayFestival.festivalDescription}
    </p>
    </div>
  </c:forEach>
  </p>
</div>

</body>
</html>

11. Here is the complete structure of the application:

/Images/20170918/101.jpg

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

/Images/20170918/102.jpg

/Images/20170918/103.jpg

/Images/20170918/104.jpg

/Images/20170918/105.jpg

13. Yeah! Finished!

If you are interested, welcome to download the source code for your own purpose:

com.casperlee.today.zip

ScriptToCreateMySQLDB.txt