Bộ sưu tập

Sử dụng Spring Boot, Spring MVC, Thymeleaf, Hibernate, Tomcat dạng nhúng để xây dựng ứng dụng web



Trong bài viết trước chúng ta đã được giới thiệu về cách sử dụng Hibernate để có thể thao tác với hệ quản trị cơ sở dữ liệu trong một ứng dụng Spring MVC. Để bắt kịp đi cùng với sự phát triển và những cải thiện của các framework đương đại, bài viết này (có kèm video hướng dẫn chi tiết ở phía dưới) sẽ hướng dẫn các bạn sử dụng các công nghệ mới như Spring Boot, Hibernate, Thymeleaf, Embedded Tomcat trên nền tảng Java 9 để có thể nhanh chóng xây dựng lên một ứng dụng web tương tự như những gì chúng ta đã thấy trong bài viết trước.

Dưới đây là cấu trúc thư mục dự án và nội dung của các file mã nguồn tương ứng:

pom.xml


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.codersontrang</groupId>
    <artifactId>SpringMVCHibernateDemo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <repositories>
        <repository>
            <id>spring-milestone</id>
            <name>spring milestone</name>
            <url>http://repo.spring.io/milestone/</url>
        </repository>
        <repository>
            <id>maven-central</id>
            <name>maven central</name>
            <url>http://central.maven.org/maven2/</url>
        </repository>
    </repositories>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.0.0.M7</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>2.0.0.M7</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.3.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>5.0.3.RELEASE</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.3.0.Beta2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.8-dmr</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-impl -->
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime -->
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.activation/activation -->
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>
    </dependencies>
</project>

SpringMVCHibernateDemoApp.java


package springmvchibernatedemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;

@SpringBootApplication
@EnableAutoConfiguration(exclude = HibernateJpaAutoConfiguration.class)
public class SpringMVCHibernateDemoApp {
	public static void main(String[] args) {
		SpringApplication.run(SpringMVCHibernateDemoApp.class, args);
	}
}

DemoController.java


package springmvchibernatedemo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
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(@ModelAttribute("model") SchoolModel schoolModel){
        ModelAndView mav = new ModelAndView("index", "model", schoolModel);
        schoolManager.getBatchInfo(schoolModel);
        return mav;
    }

    public SchoolManager getSchoolManager() {
        return schoolManager;
    }
    public void setSchoolManager(SchoolManager schoolManager) {
        this.schoolManager = schoolManager;
    }
}

SchoolManager.java


package springmvchibernatedemo.business;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import springmvchibernatedemo.dao.BatchDAO;
import springmvchibernatedemo.entity.Batch;
import springmvchibernatedemo.model.SchoolModel;

import java.util.List;

@Service
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;
    }
}

RdbConfiguration.java


package springmvchibernatedemo.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;

import javax.sql.DataSource;

@Configuration
public class RdbConfiguration {

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/springhibernatedemodb");
        dataSource.setUsername("codertiensinh");
        dataSource.setPassword("codersontrang");

        return dataSource;
    }

    @Bean
    public LocalSessionFactoryBean localSessionFactoryBean(){
        LocalSessionFactoryBean lsf = new LocalSessionFactoryBean();
        lsf.setDataSource(dataSource());
        lsf.getHibernateProperties().setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
        lsf.getHibernateProperties().setProperty("hibernate.show_sql", "true");
        lsf.setMappingResources("hibernate/Batch.hbm.xml", "hibernate/Student.hbm.xml");

        return lsf;
    }
}

BatchDAO.java


package springmvchibernatedemo.dao;


import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import springmvchibernatedemo.entity.Batch;

import java.util.List;

@Repository
public class BatchDAO extends HibernateDaoSupport{

    public BatchDAO(@Autowired SessionFactory sessionFactory){
        super();
        this.setSessionFactory(sessionFactory);
    }


    @SuppressWarnings("unchecked")
    public List<Batch> getBatchList() {
        String query = "from springmvchibernatedemo.entity.Batch";

        List<?> result =  getHibernateTemplate().find(query);
        return (List<Batch>) result;
    }
}

SchoolModel.java


package springmvchibernatedemo.model;

import springmvchibernatedemo.entity.Batch;

import java.util.List;

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;
    }
}

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;
    }
}

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>

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>

index.html


<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>View Batch</title>
</head>
<body>
    <form th:action="@{/viewBatch}" th:method="POST" th:object="${model}" id="mainForm">
        <strong>Choose the batch:</strong>

        <select th:field="*{selectedBatch.id}" onchange="submitForm()">
            <option th:each="batch: *{batches}" th:value="${batch.id}" th:text="${batch.name}"></option>
        </select>
        <br/><br/>
        <strong>Students engaged to the batch: </strong><br/>

        <ul>
            <li th:each="student: *{selectedBatch.students}" th:text="${student.id} + '-' + ${student.name}"></li>
        </ul>
    </form>
</body>


    function submitForm(){
        document.getElementById('mainForm').submit();
    }

</html>

Sau đây là video hướng dẫn cụ thể từng bước cho bài viết này:

Link của video trên Youtube tại đây.

Good luck!

2 comments on “Sử dụng Spring Boot, Spring MVC, Thymeleaf, Hibernate, Tomcat dạng nhúng để xây dựng ứng dụng web

Trả lời Jame Hủy trả lời

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Đăng xuất /  Thay đổi )

Google photo

Bạn đang bình luận bằng tài khoản Google Đăng xuất /  Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Đăng xuất /  Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Đăng xuất /  Thay đổi )

Connecting to %s