Album ảnh

Sử dụng Spring MVC và Hibernate để xây dựng ứng dụng web


https://codersontrang.com/2013/05/20/su-dung-spring-mvc-va-hibernate-de-xay-dung-ung-dung-web/

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 hibernateresources là các source folder, để tạo một source folder trong Eclipse IDE chọn New -> Other -> source folder):

springmvchibernatedemo_3

Trong ví dụ này ta cần sử dụng các thư viện như hình dưới đây:

springmvchibernatedemo_4

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à STUDENTBATCH, 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 1Batch 2, trong đó, lớp Batch 1 sẽ có hai sinh viên là Student1Student2, 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/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 driverClassNameurl 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.javaBatch.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.xmlBatch.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

springmvchibernatedemo_1

Hiển thị danh sách sinh viên của lớp học Batch 2

springmvchibernatedemo_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!

18 comments on “Sử dụng Spring MVC và Hibernate để xây dựng ứng dụng web

  1. 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ích

  2. Pingback: Spring framework 5 phiên bản mới có gì vui | Coder Sơn Trang

  3. 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

Gửi phản hồi cho An Hủy trả lời