Hibernate là một framework cung cấp API cho phép ứng dụng có thể thao tác với dữ liệu trong database. Bài viết này sẽ hướng dẫn cách sử dụng Hibernate trong Spring MVC. Giống như loạt rất nhiều bài viết trước đây, bài viết này sẽ có một ví dụ để minh họa. Để đơn giản hóa, ví dụ chỉ thao tác với database gồm có hai bảng có quan hệ một – nhiều (one-to-many) với nhau.
Đầu tiên dùng Eclipse IDE tạo ra một web project có cấu trúc như dưới đây (chú ý thư mục hibernate
và resources
là các source folder, để tạo một source folder trong Eclipse IDE chọn New -> Other -> source folder):
Trong ví dụ này ta cần sử dụng các thư viện như hình dưới đây:
Trong ví dụ này ta thao tác với database trên hệ quản trị cơ sở dữ liệu MySQL. Dưới đây là đoạn mã tạo ra database sẽ dùng trong ví dụ và một tài khoản để sử dụng trong việc truy cập vào database này.
Tạo database
CREATE USER 'codertiensinh'@'localhost' IDENTIFIED BY 'codersontrang';
GRANT ALL PRIVILEGES ON *.* TO 'codertiensinh'@'localhost'
WITH GRANT OPTION;
FLUSH PRIVILEGES;
CREATE DATABASE SpringHibernateDemoDB;
USE SpringHibernateDemoDB;
CREATE TABLE STUDENT(
STUDENT_ID NVARCHAR(6) NOT NULL,
STUDENT_NAME NVARCHAR(20),
BATCH_ID INT,
PRIMARY KEY(STUDENT_ID)
);
CREATE TABLE BATCH(
BATCH_ID INT NOT NULL AUTO_INCREMENT,
BATCH_NAME NVARCHAR(20),
PRIMARY KEY(BATCH_ID)
);
Như vậy database trên có hai bảng là STUDENT
và BATCH
, hai bảng này có quan hệ nhiều-một (many-to-one) với nhau (một batch sẽ có nhiều student) thông qua khóa ngoại là BATCH_ID
trong bảng STUDENT
. Tiếp theo là đoạn mã để chèn dữ liệu vào database vừa tạo ở trên.
Chèn dữ liệu vào database
INSERT INTO `springhibernatedemodb`.`batch` (`BATCH_NAME`)
VALUES ('Batch 1');
INSERT INTO `springhibernatedemodb`.`batch` (`BATCH_NAME`)
VALUES ('Batch 2');
INSERT INTO `springhibernatedemodb`.`student`
(`STUDENT_ID`,`STUDENT_NAME`,`BATCH_ID`)
VALUES('S001','Student1',1);
INSERT INTO `springhibernatedemodb`.`student`
(`STUDENT_ID`,`STUDENT_NAME`,`BATCH_ID`)
VALUES('S002','Student2',1);
INSERT INTO `springhibernatedemodb`.`student`
(`STUDENT_ID`,`STUDENT_NAME`,`BATCH_ID`)
VALUES('S003','Student3',2);
INSERT INTO `springhibernatedemodb`.`student`
(`STUDENT_ID`,`STUDENT_NAME`,`BATCH_ID`)
VALUES('S004','Student4',2);
Sau khi thực thi đoạn mã trên, ta sẽ có dữ liệu của hai lớp học là Batch 1
và Batch 2
, trong đó, lớp Batch 1
sẽ có hai sinh viên là Student1
và Student2
, lớp Batch 2
có hai sinh viên là Student3
, Student4
. Trong ví dụ này sẽ hiển thị một trang mà ở đó người dùng có thể chọn lớp học, sau đó hiển thị sinh viên tương ứng trong lớp học đó.
Bên trong java code, ta tạo hai thực thể (entity) là Batch
(.java) và Student
(.java) tương ứng với hai bảng trong database như sau:
Batch.java
package springmvchibernatedemo.entity;
import java.util.Set;
public class Batch {
private Integer id;
private String name;
private Set<Student> students;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}
Student.java
package springmvchibernatedemo.entity;
public class Student {
private String id;
private String name;
private Batch batch;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Batch getBatch() {
return batch;
}
public void setBatch(Batch batch) {
this.batch = batch;
}
}
Nhìn hai thực thể bên trên, qua các thuộc tính bên trong chúng, một lần nữa ta lại thấy mối quan hệ giữa sinh viên và lớp học. Thực thể Batch
sẽ chứa một tập hợp của thực thể Student
, và mỗi thực thể Student
sẽ có chứa một tham chiếu đến thực thể Batch
mà nó thuộc về.
Tiêp theo, ta có file cấu hình web.xml
như sau:
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>Spring MVC - Hibernate Demo</display-name>
<servlet>
<servlet-name>springmvchibernatedemo</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-config-*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvchibernatedemo</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Trong file cấu hình web.xml
, ta chỉ ra giá trị của tham số contextConfigLocation
là /WEB-INF/spring-config-*.xml
. Điều này có nghĩa là khi startup, Spring container sẽ lướt qua một lượt thư mục WEB-INF
, bất kì một file xml nào có tên bắt đầu với sprin-config-
sẽ được Spring container coi là một file cấu hình và đọc thông tin cấu hình từ đó. Đây là cách mà chúng ta xé nhỏ thông tin cấu hình trong Spring ra làm nhiều file cho việc dễ dàng quản lý hơn.
File cấu hình spring-config-main.xml
sẽ chỉ ra vị trí của các controller trong ứng dụng
spring-config-main.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="springmvchibernatedemo.controller" />
<mvc:annotation-driven/>
</beans>
File cấu hình spring-config-view.xml
sẽ là nơi lưu các thông tin cấu hình để định nghĩa ra các view trong ứng dụng.
spring-config-view.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
<property name="order" value="1" />
</bean>
</beans>
Trong bài viết “Spring MVC và template framework Apache Tiles“, viewClass
của chúng ta là TilesView
. Trong ví dụ này, để đơn giản, ta sử dụng JstlView
. Với thông tin cấu hình như trên, khi controller trả về một view có tên là “abc
” thì ứng dụng sẽ tìm, trả về phía client và hiển thị trang /WEB-INF/jsp/abc.jsp
.
File cấu hình spring-config-datasource.xml
là nơi cấu hình các thông tin liên quan đến việc kết nối vào database.
spring-config-datasource.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:database.properties</value>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
</beans>
Ở đây thông tin cấu hình cho việc kết nối vào database sẽ được lưu ở file database.properties
. Để spring có thể nhận biết điều này, ta file khởi tạo một bean thuộc lớp PropertyPlaceholderConfigurer
, sau đó chỉ ra giá trị của thuộc tính location
như trên.
Tiếp đó là khởi tạo một bean thuộc lớp DriverManagerDataSource
để nhận lấy các thông tin kết nối bao gồm driverClassName
, url
, username
, password
từ việc đọc trong database.properties
. Để đọc thông tin trong database.properties
, ta chỉ cần chỉ ra key của chúng bên trong ${}
.
Dưới đây là file database.properties
có các thông tin cho việc kết nối. Nội dung sẽ gồm các cặp key, value như dưới đây:
database.properties
jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/springhibernatedemodb
jdbc.username = codertiensinh
jdbc.password = codersontrang
Lưu ý ở đây chúng ta sử dụng hệ quản trị cơ sở dữ liệu MySQL, nếu như một hệ quản trị cơ sở dữ liệu khác được sử dụng thì giá trị của driverClassName
và url
sẽ khác so với ví dụ này.
File cấu hình spring-config-hibernate.xml
chứa các thông tin liên quan đến cấu hình hibernate.
spring-config-hibernate.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>Student.hbm.xml</value>
<value>Batch.hbm.xml</value>
</list>
</property>
</bean>
</beans>
Trong file cấu hình trên, ta tạo một sessionFactory
làm nhiệm vụ quản lý connection đến database đối với mỗi phiên (session) kết nối từ client. Trong sessionFactory
vừa tạo này, ta chỉ ra datasource
cho nó là cái vừa được cấu hình trong spring-config-datasource.xml
.
Tiếp theo đó là chỉ ra giá trị cho thuộc tính hibernate.dialect
. Cái này giúp cho hibernate hiểu ta đang dùng hệ quản trị cơ sở dữ liệu gì, từ đó có thể dịch câu query của Hibernate ra câu query của hệ quản trị cơ sỏ dữ liệu tương ứng. Trong trường hợp này ta dùng MySQL, nên giá trị của thuộc tính hibẻnate.dialect
sẽ là org.hibernate.dialect.MySQLDialect
.
Cuối cùng là chỉ ra giá trị của thuộc tính mappingResources
, là một danh sách các file .hbm.xml
. Mỗi file như vậy có nhiệm vụ ánh xạ (mapping) thông tin của một thực thể tới các thông tin tương ứng trong database. Với sự mapping này, khi truy vấn dữ liệu, ta chỉ cần quan tâm đến các thực thể như thế nào để lấy dữ liệu phù hợp mà không cần quan tâm đến dữ liệu ấy đang được lưu trong bảng này, cột nào. Đây là lý do vì sao ta vẫn nói Hibernate làm “trong suốt” database đối với ứng dụng, hay đơn thuần là ứng dụng không cần quan tâm đến cấu trúc cụ thể như thế nào.
Trong ví dụ này ta có hai thực thể là Student.java
và Batch.java
. Hai thực thể này được mapping với các dữ liệu từ database bằng cách thể hiện trong nội dung của hai file Student.hbm.xml
và Batch.hbm.xml
như sau:
Student.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="springmvchibernatedemo.entity.Student" table="STUDENT">
<id name="id" type="java.lang.String">
<column name="STUDENT_ID"/>
</id>
<property name="name" type="java.lang.String">
<column name="STUDENT_NAME"/>
</property>
<many-to-one name="batch" class="springmvchibernatedemo.entity.Batch" fetch="select">
<column name="BATCH_ID"/>
</many-to-one>
</class>
</hibernate-mapping>
Ở đây, một thực thể sẽ tương ứng với một bảng trong database, và các thuộc tính trong thực thể sẽ tương ứng với các cột trong bảng. Ánh xạ một thực thể sang một bảng ta sử dụng thẻ <class>
với hai thuộc tính name và table. Ánh xạ từ một thuộc tính của thực thể tới một cột của bảng ta sử dụng thẻ <property>
và thẻ <column>
. Cá biệt cho cột nào là khóa chính của bảng thì khi ánh xạ ta sẽ sử dụng thẻ <id>
. Thẻ <many-to-one>
thể hiện mối quan hệ từ thực thể hiện tại với một thực thể khác và giúp cho việc trích chọn thông tin. Trong trường hợp này, khi ta lấy ra thông tin của một đối tượng sinh viên, thì hibernate sẽ lấy thông tin của đối tượng lớp học tương ứng và gán đối tượng đến thuộc tính batch trong đối tượng sinh viên đó.
Cách cấu hình tương tự đối với Batch.hbm.xml
Batch.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="springmvchibernatedemo.entity.Batch" table="BATCH">
<id name="id" type="java.lang.Integer">
<column name="BATCH_ID"/>
<generator class="identity"/>
</id>
<property name="name" type="java.lang.String">
<column name="BATCH_NAME"/>
</property>
<set name="students" table="STUDENT" lazy="false" fetch="select" inverse="true">
<key>
<column name="BATCH_ID" not-null="true"/>
</key>
<one-to-many class="springmvchibernatedemo.entity.Student"/>
</set>
</class>
</hibernate-mapping>
Bởi vì cột ID
trong bảng BATCH
là cột tự động sinh ra, cho nên trong file cấu hình ta dùng thẻ <generator>
để chỉ ra điều đó cho hibernate biết.
DemoController.java
package springmvchibernatedemo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import springmvchibernatedemo.business.SchoolManager;
import springmvchibernatedemo.model.SchoolModel;
@Controller
public class DemoController {
@Autowired
private SchoolManager schoolManager;
@RequestMapping(value="/viewBatch")
public ModelAndView viewBatch(SchoolModel schoolModel){
ModelAndView mav = new ModelAndView("viewBatch", "model", schoolModel);
schoolManager.getBatchInfo(schoolModel);
return mav;
}
public SchoolManager getSchoolManager() {
return schoolManager;
}
public void setSchoolManager(SchoolManager schoolManager) {
this.schoolManager = schoolManager;
}
}
Trong controller, ta có một tham chiếu thuộc kiểu schoolManager
, tham chiếu này được tự động liên kết đến một đối tượng cụ thể của lớp SchoolManager
qua cơ chế liên kết tự động bằng cách sử dụng annotation @Autowired
.
Đối tượng của lớp SchoolManager
được khởi tạo trong quá trình khởi động server qua việc khai báo trong file spring-config-biz.xml
spring-config-biz.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="schoolManager" class="springmvchibernatedemo.business.SchoolManager"/>
</beans>
Dưới đây là nội dung của SchoolManager.java
SchoolManager.java
package springmvchibernatedemo.business;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import springmvchibernatedemo.dao.BatchDAO;
import springmvchibernatedemo.entity.Batch;
import springmvchibernatedemo.model.SchoolModel;
public class SchoolManager {
@Autowired
private BatchDAO batchDAO;
public void getBatchInfo(SchoolModel schoolModel) {
Batch selectedBatch = schoolModel.getSelectedBatch();
List<Batch> batches = batchDAO.getBatchList();
if(selectedBatch != null){
Integer batchId = selectedBatch.getId();
for(Batch batch : batches){
if(batch.getId().equals(batchId)){
selectedBatch = batch;
break;
}
}
}else{
selectedBatch = batches.get(0);
}
schoolModel.setBatches(batches);
schoolModel.setSelectedBatch(selectedBatch);
}
public BatchDAO getBatchDAO() {
return batchDAO;
}
public void setBatchDAO(BatchDAO batchDAO) {
this.batchDAO = batchDAO;
}
}
Bên trong hàm getBatchInfo()
, ta sẽ lấy ra danh sách các lớp học, lấy ra thông tin của một lớp học mà được người dùng chọn trên màn hình rồi sau đó ném thông tin vào model. Cũng tương tự như trong controller, bên trong SchoolManager
có một tham chiếu thuộc kiểu BatchDAO
. Tham chiếu này cũng được liên kết một các tự động đến một đối tượng cụ thể trong quá trình khởi động server. Cách làm tương tự như trên. Một điều chú ý ở đây đó là đối tượng thuộc lớp BatchDAO
sẽ là đối tượng trực tiếp tiếp xúc và thao tác với database. Để có thể thực hiện việc trao đối dữ liệu với database, lớp BatchDAO
sẽ kế thừa lớp HibernateDaoSupport
như dưới đây:
BatchDAO.java
package springmvchibernatedemo.dao;
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import springmvchibernatedemo.entity.Batch;
public class BatchDAO extends HibernateDaoSupport{
@SuppressWarnings("unchecked")
public List<Batch> getBatchList() {
String query = "select b from Batch b";
return getHibernateTemplate().find(query);
}
}
Việc truy vấn cơ sở dữ liệu giờ đây không sử dụng câu truy vấn SQL như thông thường mà sẽ sử dụng Hibernate Query Language (HQL). Đó là kiểu truy vấn trên các thực thể chứ không phải là truy vấn trên các bảng của database. Như trên ta có thể thấy một câu truy vấn đơn giản để lấy ra danh sách tất cả các lớp học trong database.
Quay trở lại quá trình khởi tạo bean của lớp BatchDAO
. Vì như đã nói, nó là đối tượng thao tác với database, cho nên khi khỏi tạo ta phải chỉ ra nó sẽ kết nối đến database nào bằng cách chỉ ra thuộc tính sessionFactory
chính là cái mà ta đã cấu hình trong spring-config-hibernate.xml
.
spring-config-dao.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="batchDAO" class="springmvchibernatedemo.dao.BatchDAO">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>
Dưới đây là model dùng trong ví dụ của chúng ta. Thông tin trước khi được hiển thị trên view sẽ được controller cập nhật vào model. Trong model này, sẽ có một danh sách các lớp học. Và thông tin về một lớp học được người dùng chọn trên màn hình, cụ thể hơn, thông tin về một lớp học chính là danh sách sinh viên của lớp học đó.
SchoolModel.java
package springmvchibernatedemo.model;
import java.util.List;
import springmvchibernatedemo.entity.Batch;
public class SchoolModel {
private Batch selectedBatch;
private List<Batch> batches;
public Batch getSelectedBatch() {
return selectedBatch;
}
public void setSelectedBatch(Batch selectedBatch) {
this.selectedBatch = selectedBatch;
}
public List<Batch> getBatches() {
return batches;
}
public void setBatches(List<Batch> batches) {
this.batches = batches;
}
}
Cuối cùng là đoạn mã cho view sẽ giống như dưới đây. View sẽ lấy thông tin từ model và hiển thị đến người dùng cuối.
viewBatch.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>View Batch</title>
</head>
<body>
<form:form id="mainForm" method="post" commandName="model">
<strong>Choose the batch:</strong>
<form:select path="selectedBatch.id" onchange="submitForm()">
<form:options items="${model.batches }" itemValue="id" itemLabel="name"/>
</form:select>
<br/><br/>
<strong>Students engaged to the batch: </strong><br/>
<c:forEach items="${model.selectedBatch.students }" var="student">
${student.id } - ${student.name } <br/>
</c:forEach>
</form:form>
</body>
<script type="text/javascript">
function submitForm(){
document.getElementById('mainForm').submit();
}
</script>
</html>
Khi chạy ví dụ, ta sẽ thấy danh sách các lớp học sẽ được hiện dưới dạng một combo box. Tiếp đó là danh sách sinh viên của lớp học sẽ được hiện ra ở phía dưới.
Hiển thị danh sách sinh viên của lớp học Batch 1
Hiển thị danh sách sinh viên của lớp học Batch 2
Ghi chú: Ví dụ trong bài viết này có thể được viết bằng việc sử dụng Spring Boot trong bài viết ở đây.
Good luck!
sao ko up code len xem thu a
ThíchThích
can k up cho
ThíchThích
bạn có k
ThíchThích
up voi ban xutho10294@gmail.com
ThíchThích
gửi cho mình với bạn ơi, ductam0104@gmail.com
ThíchThích
tks ban!
ThíchThích
The may cai tren kia khong phai code thi la cai gi ban Trang?
ThíchThích
Cảm ơn bạn rất nhiều bạn có thể cho mình gói thư viện bàn này có đc ko ạ , tức là gói lib đấy ạ mình tìm mãi mà ko thấy nếu có thể xin gửi vào mail cho mình ạ, mail mình là binhbkat@gmail.com , mình cảm ơn
ThíchThích
Có thể cho mình xin source để chạy thử.Thanks
ThíchThích
dear bác coder!
bác có thể chỉ rõ hơn cho em cái phần deploy lên server đc ko ạ? em ko thể deploy cái webapp này lên server đc. nó báo bị lỗi 404 request resource not found.
ThíchThích
quên nữa, em dùng tomcat 7 nhé.
ThíchThích
minh lam theo bai huong dan cua ban roi nhung khong tai nao chay dc ,
Bao loi khong the tao bean
ThíchThích
thanh kiều bác Sơn với thím Trang đã viết bài này nhé,
ThíchThích
Bác có thể cho em xin lib thư viện được không?
tatnnse02002@gmail.com
Thanks bác
ThíchThích
codersontrang, mình chạy demo của bạn, nó báo lỗi này
“No WebApplicationContext found: no ContextLoaderListener registered?”
Có cần phải thêm vào ContextLoaderListener vào web.xml k bạn?
ThíchThích
cho m cái file lib với
ThíchThích
Pingback: Spring framework 5 phiên bản mới có gì vui | Coder Sơn Trang
Pingback: Sử dụng Spring Boot, Spring MVC, Thymeleaf, Hibernate, Tomcat dạng nhúng để xây dựng ứng dụng web | Coder Sơn Trang