美文网首页
SpringBoot模板引擎Thymeleaf使用入门示例

SpringBoot模板引擎Thymeleaf使用入门示例

作者: SpaceCat | 来源:发表于2021-12-12 22:05 被阅读0次

    1、Thymeleaf简介

    Thymeleaf is a modern server-side Java template engine for both web and standalone environments.
    Thymeleaf是适用于Web和独立环境的现代服务器端Java模板引擎。

    模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的html文档。从字面上理解模板引擎,最重要的就是模板二字,这个意思就是做好一个模板后套入对应位置的数据,最终以html的格式展示出来,这就是模板引擎的作用。
    这里通过一个例子,演示如何使用Thymeleaf模板引擎。

    2、前期准备:通过Mybatis访问数据库

    这里对于数据的访问,复用了前面一篇例子中的MyBatis的部分代码,为了保证这篇的独立性,这里将前面的步骤附在如下。这部分主要是展示如何通过Mybatis访问数据库中的数据。

    2.1依赖配置添加

    connnect/pom.xml文件中添加mybatis依赖,如下:

    <?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.space.mysql</groupId>
        <artifactId>connnect</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.0.RELEASE</version>
        </parent>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.11</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.2.0</version>
            </dependency>
        </dependencies>
    
    </project>
    

    2.2 添加在应用配置文件中添加MyBatis相关配置

    主要是说明下数据库记录映射的类和mapper配置文件的路径信息。
    application.properties

    spring.datasource.username=root
    spring.datasource.password=lfqylfqy
    spring.datasource.url=jdbc:mysql://localhost:3306/testdb?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    #mybatis相关配置
    #数据库记录映射类所在的包和mapper文件存放的位置
    mybatis.type-aliases-package=com.space.mysql.connect.domain
    mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
    

    新增一个mapper文件,并在其中定义相关的sql语句。
    mybatis/mapper/StudentMapper.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.space.mysql.connect.mapper.StudentMapper">
        <select id="queryStudentList" resultType="com.space.mysql.connect.domain.Student">
            select * from student
        </select>
        <select id="queryStudentById" resultType="com.space.mysql.connect.domain.Student">
            select * from student where id = #{id}
        </select>
        <insert id="addStudent" parameterType="com.space.mysql.connect.domain.Student">
            insert into Student(id, name, age) VALUES (#{id}, #{name}, #{age})
        </insert>
        <update id="updateStudent" parameterType="com.space.mysql.connect.domain.Student">
            update Student set name = #{name}, age = #{age} where id = #{id}
        </update>
        <delete id="deleteStudent" parameterType="int">
            delete from Student where id = #{id}
        </delete>
    </mapper>
    

    2.3 Java代码编写

    2.3.1 新增一个和数据库表中记录对应的java类

    这里借用之前的表结构:

    $ mysql -u root -p
    Enter password: 
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 51
    Server version: 8.0.20 MySQL Community Server - GPL
    
    Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql> use testdb;
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    
    Database changed
    mysql> describe student;
    +-------+-------------+------+-----+---------+-------+
    | Field | Type        | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+-------+
    | id    | int         | NO   | PRI | NULL    |       |
    | name  | varchar(30) | YES  |     | NULL    |       |
    | age   | varchar(10) | YES  |     | NULL    |       |
    +-------+-------------+------+-----+---------+-------+
    3 rows in set (0.00 sec)
    
    mysql>
    

    com.space.mysql.connect.domain.Student

    package com.space.mysql.connect.domain;
    
    /**
     * Created by chengxia on 2021/12/11.
     */
    public class Student {
        private int id;
        private String name;
        private int age;
    
        public Student(int id, String name, int age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }
    

    2.3.2 新增一个Mapper接口对应mapper配置文件

    这个接口可以结合配置文件,对应到sql语句。
    com.space.mysql.connect.mapper.StudentMapper

    package com.space.mysql.connect.mapper;
    
    import com.space.mysql.connect.domain.Student;
    import org.apache.ibatis.annotations.Mapper;
    
    import java.util.List;
    
    /**
     * Created by chengxia on 2021/12/11.
     */
    @Mapper
    public interface StudentMapper {
        List<Student> queryStudentById(int id);
        List<Student> queryStudentList();
        void addStudent(Student stu);
        void updateStudent(Student stu);
        void deleteStudent(int id);
    }
    

    2.3.3 新增数据库Service类对数据库操作进行包装(调用mapper)

    这里将服务多抽象了一层接口。
    服务接口类com.space.mysql.connect.service.StudentServiceInterface

    package com.space.mysql.connect.service;
    
    import com.space.mysql.connect.domain.Student;
    
    import java.util.List;
    
    /**
     * Created by chengxia on 2021/12/12.
     */
    public interface StudentServiceInterface {
        Student queryStudentById(int id);
        List<Student> queryStudentList();
        void addStudent(Student stu);
        void updateStudent(Student stu);
        void deleteStudent(int id);
    }
    

    服务实现类com.space.mysql.connect.service.StudentService

    package com.space.mysql.connect.service;
    
    import com.space.mysql.connect.domain.Student;
    import com.space.mysql.connect.mapper.StudentMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    /**
     * Created by chengxia on 2021/12/12.
     */
    @Service
    public class StudentService implements StudentServiceInterface {
        @Autowired
        private StudentMapper stuMapper;
        @Override
        public Student queryStudentById(int id) {
            List<Student> studentList = stuMapper.queryStudentById(id);
            if(studentList != null && studentList.size() > 0) {
                System.out.println(studentList.get(0));
                return studentList.get(0);
            }else{
                return null;
            }
        }
    
        @Override
        public List<Student> queryStudentList() {
            List<Student> studentList = stuMapper.queryStudentList();
            for (Student stu: studentList){
                System.out.println(stu);
            }
            return studentList;
        }
    
        @Override
        public void addStudent(Student stu) {
            stuMapper.addStudent(new Student(stu.getId(), stu.getName(), stu.getAge()));
        }
    
        @Override
        public void updateStudent(Student stu) {
            stuMapper.updateStudent(new Student(stu.getId(),stu.getName(), stu.getAge()));
        }
    
        @Override
        public void deleteStudent(int id) {
            stuMapper.deleteStudent(id);
        }
    }
    

    2.3.4 应用启动类中增加mapper等类的扫描包路径

    这一步必不可少,不然会报错mapper类的bean找不到。

    Consider defining a bean of type 'com.space.mysql.connect.mapper.StudentMapper' in your configuration.
    

    com.space.mysql.connect.main.Application

    package com.space.mysql.connect.main;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.ComponentScan;
    
    /**
     * Created by chengxia on 2021/12/7.
     */
    @SpringBootApplication
    @ComponentScan(basePackages = {"com.space.mysql.connect.controller","com.space.mysql.connect.service"})
    @MapperScan(value = "com.space.mysql.connect.mapper")
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
    

    到这里,访问数据库相关的代码就完成了。

    3、Thymeleaf模板的使用

    3.1 依赖配置

    connnect/pom.xml文件中添加Thymeleaf相关的依赖配置:

    <?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.space.mysql</groupId>
        <artifactId>connnect</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.0.RELEASE</version>
        </parent>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.11</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.2.0</version>
            </dependency>
            <dependency>
                <groupId>org.thymeleaf</groupId>
                <artifactId>thymeleaf-spring5</artifactId>
            </dependency>
            <dependency>
                <groupId>org.thymeleaf.extras</groupId>
                <artifactId>thymeleaf-extras-java8time</artifactId>
            </dependency>
        </dependencies>
    
    </project>
    

    3.2 新建一个使用Thymeleaf模板的Controller

    这里单独写一个Controller用来调用Thymeleaf显示页面。
    com.space.mysql.connect.controller.ThymeleafTemplateController

    package com.space.mysql.connect.controller;
    
    import com.space.mysql.connect.domain.Student;
    import com.space.mysql.connect.service.StudentServiceInterface;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.*;
    
    
    /**
     * Created by chengxia on 2021/12/12.
     * 这里需要尤为注意,Controller注解 ,必须用Controller,不能用原来的RestController!
     */
    @Controller
    @RequestMapping("/student")
    public class ThymeleafTemplateController {
        @Autowired
        private StudentServiceInterface stuService;
    
        @RequestMapping("/queryList")
        public String queryStudentList(ModelMap map){
            map.addAttribute("student", stuService.queryStudentList());
            return "StudentsList";
        }
        @RequestMapping("/delete")
        public String deleteStudent(@RequestParam() int id, ModelMap map){
            stuService.deleteStudent(id);
            map.addAttribute("student", stuService.queryStudentList());
            return "StudentsList";
        }
        @RequestMapping("/edit")
        public String editStudent(ModelMap map, @RequestParam(defaultValue = "0") int id){
            if(id >  0){
                //该记录已经存在,就进行更新操作,查询详情并传入map
                map.addAttribute("student", stuService.queryStudentById(id));
            }else{
                //新增一条记录
                map.addAttribute("student",new Student(0,"TmpName", 9));
            }
            return "StudentEdit";
        }
    
        @RequestMapping(value = "/save", method = {RequestMethod.GET, RequestMethod.POST})
        public String save(ModelMap map, @ModelAttribute Student student){
            if(student == null){
                return "Error Happened when add null...";
            }
    
            Student stuTmp= stuService.queryStudentById(student.getId());
            if(stuTmp == null){
                //如果没有查到记录,就新增
                stuService.addStudent(student);
            }else{
                stuService.updateStudent(student);
            }
            map.addAttribute("student", stuService.queryStudentList());
            return "StudentsList";
        }
    }
    

    3.3 新建模板文件

    3.3.1 原理简介

    Spring Boot提供了大量模板引擎, 包含括FreeMarker、Groovy、 Thymeleaf、 Velocity和Mustache, Spring Boot中推荐
    使用Thymeleaf作为模板引擎, 因为Thymeleaf提供了完美的Spring MVC的支持。
    原理上说,Thymeleaf在Spring Boot的org.springframework.boot.autoconfigure.thymeleaf包下实现自动配置,如下所示:


    image.png

    ThymeleafAutoConfiguration源码:

    @Configuration
    @EnableConfigurationProperties(ThymeleafProperties.class)
    @ConditionalOnClass({ TemplateMode.class, SpringTemplateEngine.class })
    @AutoConfigureAfter({ WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class })
    public class ThymeleafAutoConfiguration {
    
            //配置TemplateResolver
        @Configuration
        @ConditionalOnMissingBean(name = "defaultTemplateResolver")
        static class DefaultTemplateResolverConfiguration {
                ...
        }
        
            //配置TemplateEngine
        @Configuration
        protected static class ThymeleafDefaultConfiguration {
                ...
        }
            //配置SpringWebFluxTemplateEngine
        @Configuration
        @ConditionalOnWebApplication(type = Type.SERVLET)
        @ConditionalOnProperty(name = "spring.thymeleaf.enabled", matchIfMissing = true)
        static class ThymeleafWebMvcConfiguration {
               ...
        }
        
            //配置thymeleafViewResolver
        @Configuration
        @ConditionalOnWebApplication(type = Type.REACTIVE)
        @ConditionalOnProperty(name = "spring.thymeleaf.enabled", matchIfMissing = true)
        static class ThymeleafWebFluxConfiguration {
               ...
        }
        ...
    }
    

    ThymeleafAutoConfiguration自动加载Web所需的TemplateResolver、TemplateEngine、SpringWebFluxTemplateEngine以及thymeleafViewResolver,并通过ThymeleafProperties进行Thymeleaf属性配置。详细细节查看官方源码。
    ThymeleafProperties源码:

    //读取application.properties配置文件的属性
    @ConfigurationProperties(prefix = "spring.thymeleaf")
    public class ThymeleafProperties {
    
        private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
    
        public static final String DEFAULT_PREFIX = "classpath:/templates/";
    
        public static final String DEFAULT_SUFFIX = ".html";
    
        /**
         *Web模板文件前缀路径属性,Spring boot默认路径为classpath:/templates/
         */
        private String prefix = DEFAULT_PREFIX;
    
        /**
         * Web模板文件后缀属性,默认为html
         */
        private String suffix = DEFAULT_SUFFIX;
    
        /**
         * Web模板模式属性,默认为HTML
         */
        private String mode = "HTML";
    
        /**
         *  Web模板文件编码属性,默认为UTF_8
         */
        private Charset encoding = DEFAULT_ENCODING;
    
            ....
    }
    

    从上面如下部分的代码:

    public static final String DEFAULT_PREFIX = "classpath:/templates/";
    public static final String DEFAULT_SUFFIX = ".html";
    

    可以从ThymeleafProperties中看出,Thymeleaf的默认设置,以及可以通过前缀为spring.thymeleaf属性修改Thymeleaf默认配置。默认地,模板文件的后缀是“.html”放在templates目录下。

    3.3.2 新建显示和修改信息的模板文件

    显示信息列表的模板文件。
    templates/StudentsList.html

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Student List</title>
        <style>
            table{border-collapse: collapse;}
            table, th, td{boder:1px solid black; padding:5px; text-align:center;}
        </style>
    </head>
    <body>
    <br/>
    <br/>
    <br/>
    <a href="/student/edit">New Student</a>
    <br/>
    <br/>
    <br/>
    <table>
        <thead>
        <th width="20%">ID</th>
        <th width="20%">Name</th>
        <th width="20%">Age</th>
        </thead>
        <tbody>
        <tr th:each="student:${student}">
            <td th:text="${student.id}"></td>
            <td th:text="${student.name}"></td>
            <td th:text="${student.age}"></td>
            <td>
                <a th:href="@{/student/edit(id=${student.id})}">Edit</a>
                <a th:href="@{/student/delete(id=${student.id})}">Delete</a>
            </td>
        </tr>
        </tbody>
    </table>
    </body>
    </html>
    

    修改信息的模板。
    templates/StudentEdit.html

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Student Edit or New</title>
        <style>
            table{border-collapse: collapse;}
            table, th, td{boder:1px solid black; padding:5px; text-align:center;}
        </style>
    </head>
    <body>
    <form th:action="@{/student/save}" method="post">
        <div>
            <label>ID</label>
            <input type="text" name="id" readonly="readonly" th:field="${student.id}"/>
        </div>
        <div>
            <label>Name</label>
            <input type="text" name="name" th:field="${student.name}"/>
            <br/>
    
            <label>Age</label>
            <input type="text" name="age" th:field="${student.age}"/>
        </div>
        <div>
            <input type="submit" value="Submit"/>
        </div>
    </form>
    </body>
    </html>
    

    到这里,代码全部完成了,目录结构如下:


    image.png

    4、运行效果

    启动应用之后:
    http://localhost:8080/student/queryList

    image.png
    点击上面的Delete,跳转到链接http://localhost:8080/student/delete?id=0
    image.png
    点击上面的Edit,跳转到链接http://localhost:8080/student/edit?id=2
    image.png
    将上面的年龄改成999:
    image.png
    点击Submit,跳转到http://localhost:8080/student/save
    image.png
    点击上面的New Student,跳转到http://localhost:8080/student/edit
    image.png
    修改信息如下:
    image.png
    点击Submit,跳转到http://localhost:8080/student/save
    image.png

    到这里示例就结束了。

    参考资料

    相关文章

      网友评论

          本文标题:SpringBoot模板引擎Thymeleaf使用入门示例

          本文链接:https://www.haomeiwen.com/subject/ppsdfrtx.html