I'm skilling in the bunch of Spring boot with Thymeleaf and MySQL DB at localhost. I know how retrieve data from table via th:each tag, but how retrieve data from 2 tables? They linked one to one so I want to get results from both tables to one html page(f.e. for each instructor his own details), but i dunno how to release it or what to google. Anyone can help me or advice a book or article?
tables schema sql
set foreign_key_checks = 0;
DROP TABLE IF EXISTS instructor;
DROP TABLE IF EXISTS insturctor_detail;
CREATE TABLE IF NOT EXISTS instructor(
id INT(20) AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(20) DEFAULT NULL,
second_name VARCHAR(20) DEFAULT NULL,
email VARCHAR(20) DEFAULT NULL,
instructor_detail_id INT(20),
CONSTRAINT FK_INSTRUCTOR_DETAIL_ID
FOREIGN KEY (instructor_detail_id)
REFERENCES instructor (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
);
CREATE TABLE IF NOT EXISTS instructor_detail(
id INT(20) AUTO_INCREMENT PRIMARY KEY,
hobby VARCHAR(50) DEFAULT NULL,
youtube_channel VARCHAR(100) DEFAULT NULL
);
set foreign_key_checks = 1;
Controller:
@Controller
public class MyController {
@Autowired
InstructorRepository instructorRepository;
@GetMapping("/index")
public String mainController(){
return "index";
}
@GetMapping("/add")
public String addInstructorForm(Model model){
model.addAttribute("instructor", new Instructor());
model.addAttribute("detail", new InstructorDetail());
return "addInstructor";
}
@PostMapping("/add")
public String submitForm(@ModelAttribute Instructor instructor, @ModelAttribute InstructorDetail instructorDetail){
instructor.setInstructorDetail(instructorDetail);
instructorRepository.save(instructor);
return "redirect:/instructorsList";
}
@GetMapping("/instructorsList")
public String getList(Model model){
model.addAttribute("instructors",instructorRepository.findAll());
return "instructorsList";
}
}
Entities: Instructor.class
@Entity
@Table(name = "instructor")
public class Instructor {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column(name = "first_name")
private String firstName;
@Column(name = "second_name")
private String secondName;
@Column(name = "email")
private String email;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "instructor_detail_id")
private InstructorDetail instructorDetail;
public Instructor() {
}
public Instructor(String firstName, String secondName, String email) {
this.firstName = firstName;
this.secondName = secondName;
this.email = email;
}
public Instructor(String firstName, String secondName, String email, InstructorDetail instructorDetail) {
this.firstName = firstName;
this.secondName = secondName;
this.email = email;
this.instructorDetail = instructorDetail;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getSecondName() {
return secondName;
}
public void setSecondName(String secondName) {
this.secondName = secondName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public InstructorDetail getInstructorDetail() {
return instructorDetail;
}
public void setInstructorDetail(InstructorDetail instructorDetail) {
this.instructorDetail = instructorDetail;
}
}
Instructor detail class
@Entity
@Table(name = "instructor_detail")
public class InstructorDetail {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column(name = "hobby")
private String hobby;
@Column(name = "youtube_channel")
private String youtubeChannel;
public InstructorDetail() {
}
public InstructorDetail(String hobby, String youtubeChannel) {
this.hobby = hobby;
this.youtubeChannel = youtubeChannel;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public String getYoutubeChannel() {
return youtubeChannel;
}
public void setYoutubeChannel(String youtubeChannel) {
this.youtubeChannel = youtubeChannel;
}
}
html list of instructors
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
<div class="container">
<table>
<thead>
<th>First name</th>
<th>Last name</th>
<th>Email</th>
</thead>
<tbody>
<tr data-th-each="instructor : ${instructors}">
<td data-th-text="${instructor.firstName}"></td>
<td data-th-text="${instructor.secondName}"></td>
<td data-th-text="${instructor.email}"></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
add instructor form
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous"/>
</head>
<body>
<div class="container">
<h1>form</h1>
<form action="#" data-th-action="@{/add}" data-th-object="${instructor}" method="post">
<div class="form-group">
<label for="1">name</label>
<input class="form-control" id="1" type="text" data-th-field="${instructor.firstName}" placeholder="first name"/>
</div>
<div class="form-group">
<label for="2">second name</label>
<input class="form-control" id="2" type="text" data-th-field="${instructor.secondName}" placeholder="second name"/>
</div>
<button class="btn btn-primary">add</button>
</form>
</div>
</body>
</html>
UPDATE FIXED
I've just fix it using next way:
First: create buffer class for storing fields of 2 entities Next: Add this class to list and pass list via MVC to thymeleaf template
@GetMapping("/instructorsList")
public String getList(Model model){
Map map = new HashMap<>();
List list = new ArrayList<Instructor>();
list = instructorRepository.findAll();
List resultList = new ArrayList();
for (int i = 0; i < list.size(); i++) {
Instructor instructor = (Instructor)list.get(i);
InstructorDetail detail = detailRepository.getInstructorDetailById(instructor.getId());
InstructorAndDetail iid = new InstructorAndDetail(instructor, detail);
resultList.add(iid);
}
model.addAttribute("instructors", resultList);
return "instructorsList";
}
and the class:
public class InstructorAndDetail {
private String fname;
private String lname;
private String email;
private String hobby;
private String channel;
public InstructorAndDetail() {
}
public InstructorAndDetail(Instructor instructor, InstructorDetail detail) {
fname = instructor.getFirstName();
lname = instructor.getSecondName();
email = instructor.getEmail();
hobby = detail.getHobby();
channel = detail.getYoutubeChannel();
}
public String getFname() {
return fname;
}