SpringBoot 实战 (十二) | 整合 thymeleaf

15次阅读

共计 7802 个字符,预计需要花费 20 分钟才能阅读完成。

微信公众号:一个优秀的废人如有问题或建议,请后台留言,我会尽力解决你的问题。
前言
如题,今天介绍 Thymeleaf,并整合 Thymeleaf 开发一个简陋版的学生信息管理系统。
SpringBoot 提供了大量模板引擎,包含 Freemarker、Groovy、Thymeleaf、Velocity 以及 Mustache,SpringBoot 中推荐使用 Thymeleaf 作为模板引擎,因为 Thymeleaf 提供了完美的 SpringMVC 支持。Thymeleaf 是新一代 Java 模板引擎,在 Spring 4 后推荐使用。
什么是模板引擎?
Thymeleaf 是一种模板语言。那模板语言或模板引擎是什么?常见的模板语言都包含以下几个概念:数据(Data)、模板(Template)、模板引擎(Template Engine)和结果文档(Result Documents)。
数据
数据是信息的表现形式和载体,可以是符号、文字、数字、语音、图像、视频等。数据和信息是不可分离的,数据是信息的表达,信息是数据的内涵。数据本身没有意义,数据只有对实体行为产生影响时才成为信息。
模板
模板,是一个蓝图,即一个与类型无关的类。编译器在使用模板时,会根据模板实参对模板进行实例化,得到一个与类型相关的类。
模板引擎
模板引擎(这里特指用于 Web 开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的 HTML 文档。
结果文档
一种特定格式的文档,比如用于网站的模板引擎就会生成一个标准的 HTML 文档。
模板语言用途广泛,常见的用途如下:

页面渲染
文档生成
代码生成
所有“数据 + 模板 = 文本”的应用场景

Thymeleaf 简介
Thymeleaf 是一个 Java 类库,它是一个 xml/xhtml/html5 的模板引擎,可以作为 MVC 的 web 应用的 View 层。
Thymeleaf 还提供了额外的模块与 SpringMVC 集成,所以我们可以使用 Thymeleaf 完全替代 JSP。
Thymeleaf 语法
博客资料:http://www.cnblogs.com/nuoyia… 官方文档:http://www.thymeleaf.org/docu…
SpringBoot 整合 Thymeleaf
下面使用 SpringBoot 整合 Thymeleaf 开发一个简陋版的学生信息管理系统。
1、准备工作

IDEA
JDK1.8
SpringBoot2.1.3

2、pom.xml 主要依赖
<dependencies>
<!– JPA 数据访问 –>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!– thymeleaf 模板引擎 –>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!– web 启动类 –>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!– mysql 数据库连接类 –>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
3、application.yaml 文件配置
spring:
# 数据库相关
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=true
username: root
password: 123456
# jpa 相关
jpa:
hibernate:
ddl-auto: update # ddl-auto: 第一次启动项目设为 create 表示每次都重新建表,之后设置为 update
show-sql: true
4、实体类
@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
public class Student {

@Id
@GeneratedValue
/**
* 主键
*/
private Long id;

/**
* 主键
*/
private Long studentId;

/**
* 姓名
*/
private String name;

/**
* 年龄
*/
private Integer age;

/**
* 专业
*/
private String major;

/**
* 宿舍
*/
private String dormitory;

/**
* 籍贯
*/
private String city;

/*@Temporal(TemporalType.TIMESTAMP)// 将时间戳,转换成年月日时分秒的日期格式
@Column(name = “create_time”,insertable = false, updatable=false, columnDefinition = “timestamp default current_timestamp comment ‘ 注册时间 '”)
private Date createDate;

@Temporal(TemporalType.TIMESTAMP)// 将时间戳,转换成年月日时分秒的日期格式
@Column(name = “update_time”,insertable = false, updatable=true, columnDefinition = “timestamp default current_timestamp comment ‘ 修改时间 '”)
private Date updateDate;*/

}
5、dao 层
@Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
}
6、service 层
public interface StudentService {

List<Student> findStudentList();

Student findStudentById(Long id);

Student saveStudent(Student student);

Student updateStudent(Student student);

void deleteStudentById(Long id);

}
实现类:
@Service
public class StudentServiceImpl implements StudentService {

@Autowired
private StudentRepository studentRepository;

/**
* 查询所有学生信息列表
* @return
*/
@Override
public List<Student> findStudentList() {
Sort sort = new Sort(Direction.ASC,”id”);
return studentRepository.findAll(sort);
}

/**
* 根据 id 查询单个学生信息
* @param id
* @return
*/
@Override
public Student findStudentById(Long id) {
return studentRepository.findById(id).get();
}

/**
* 保存学生信息
* @param student
* @return
*/
@Override
public Student saveStudent(Student student) {
return studentRepository.save(student);
}

/**
* 更新学生信息
* @param student
* @return
*/
@Override
public Student updateStudent(Student student) {
return studentRepository.save(student);
}

/**
* 根据 id 删除学生信息
* @param id
* @return
*/
@Override
public void deleteStudentById(Long id) {
studentRepository.deleteById(id);
}
}
7、controller 层 (Thymeleaf) 使用
controller 层将 view 指向 Thymeleaf:
@Controller
@RequestMapping(“/student”)
public class StudentController {

@Autowired
private StudentService studentService;

/**
* 获取学生信息列表
* @param map
* @return
*/
@GetMapping(“/list”)
public String findStudentList(ModelMap map) {
map.addAttribute(“studentList”,studentService.findStudentList());
return “studentList”;
}

/**
* 获取保存 student 表单
*/
@GetMapping(value = “/create”)
public String createStudentForm(ModelMap map) {
map.addAttribute(“student”, new Student());
map.addAttribute(“action”, “create”);
return “studentForm”;
}

/**
* 保存学生信息
* @param student
* @return
*/
@PostMapping(value = “/create”)
public String saveStudent(@ModelAttribute Student student) {
studentService.saveStudent(student);
return “redirect:/student/list”;
}

/**
* 根据 id 获取 student 表单,编辑后提交更新
* @param id
* @param map
* @return
*/
@GetMapping(value = “/update/{id}”)
public String edit(@PathVariable Long id, ModelMap map) {
map.addAttribute(“student”, studentService.findStudentById(id));
map.addAttribute(“action”, “update”);
return “studentForm”;
}

/**
* 更新学生信息
* @param student
* @return
*/
@PostMapping(value = “/update”)
public String updateStudent(@ModelAttribute Student student) {
studentService.updateStudent(student);
return “redirect:/student/list”;
}

/**
* 删除学生信息
* @param id
* @return
*/
@GetMapping(value = “/delete/{id}”)
public String deleteStudentById(@PathVariable Long id) {
studentService.deleteStudentById(id);
return “redirect:/student/list”;
}
}
简单说下,ModelMap 对象来进行数据绑定到视图。return 字符串,该字符串对应的目录在 resources/templates 下的模板名字。@ModelAttribute 注解是用来获取页面 Form 表单提交的数据,并绑定到 Student 数据对象。
8、studentForm 表单
定义了一个 Form 表单用于注册或修改学生信息。
<form th:action=”@{/student/{action}(action=${action})}” method=”post” class=”form-horizontal”>

<div class=”form-group”>
<label for=”student_Id” class=”col-sm-2 control-label”> 学号:</label>
<div class=”col-xs-4″>
<input type=”text” class=”form-control” id=”student_Id” name=”name” th:value=”${student.studentId}”
th:field=”*{student.studentId}”/>
</div>
</div>

<div class=”form-group”>
<label for=”student_name” class=”col-sm-2 control-label”> 姓名:</label>
<div class=”col-xs-4″>
<input type=”text” class=”form-control” id=”student_name” name=”name” th:value=”${student.name}”
th:field=”*{student.name}”/>
</div>
</div>

<div class=”form-group”>
<label for=”student_age” class=”col-sm-2 control-label”> 年龄:</label>
<div class=”col-xs-4″>
<input type=”text” class=”form-control” id=”student_age” name=”name” th:value=”${student.age}”
th:field=”*{student.age}”/>
</div>
</div>

<div class=”form-group”>
<label for=”student_major” class=”col-sm-2 control-label”> 专业:</label>
<div class=”col-xs-4″>
<input type=”text” class=”form-control” id=”student_major” name=”name” th:value=”${student.major}”
th:field=”*{student.major}”/>
</div>
</div>

<div class=”form-group”>
<label for=”student_dormitory” class=”col-sm-2 control-label”> 宿舍:</label>
<div class=”col-xs-4″>
<input type=”text” class=”form-control” id=”student_dormitory” name=”name” th:value=”${student.dormitory}”
th:field=”*{student.dormitory}”/>
</div>
</div>

<div class=”form-group”>
<label for=”student_city” class=”col-sm-2 control-label”> 籍贯:</label>
<div class=”col-xs-4″>
<input type=”text” class=”form-control” id=”student_city” name=”writer” th:value=”${student.city}”
th:field=”*{student.city}”/>
</div>
</div>

<div class=”form-group”>
<div class=”col-sm-offset-3 col-sm-10″>
<input class=”btn btn-primary” type=”submit” value=” 提交 ”/>&nbsp;&nbsp;
<input class=”btn” type=”button” value=” 返回 ” onclick=”history.back()”/>
</div>
</div>
</form>
9、studentList 学生列表
用于展示学生信息:
<table class=”table table-hover table-condensed”>
<legend>
<strong> 学生信息列表 </strong>
</legend>
<thead>
<tr>
<th> 学号 </th>
<th> 姓名 </th>
<th> 年龄 </th>
<th> 专业 </th>
<th> 宿舍 </th>
<th> 籍贯 </th>
<th> 管理 </th>
</tr>
</thead>
<tbody>
<tr th:each=”student : ${studentList}”>
<th scope=”row” th:text=”${student.studentId}”></th>
<td><a th:href=”@{/student/update/{studentId}(studentId=${student.id})}” th:text=”${student.name}”></a></td>
<td th:text=”${student.age}”></td>
<td th:text=”${student.major}”></td>
<td th:text=”${student.dormitory}”></td>
<td th:text=”${student.city}”></td>
<td><a class=”btn btn-danger” th:href=”@{/student/delete/{studentId}(studentId=${student.id})}”> 删除 </a></td>
</tr>
</tbody>
</table>
页面效果
列表页面:点击按钮可注册学生信息

注册 / 修改学生信息页面:点提交保存学生信息到数据库并返回列表页面

有数据的列表页面:点击名字跳到注册 / 修改页面可修改学生信息,点击删除可删除学生信息

后语
如果本文对你哪怕有一丁点帮助,请帮忙点好看。你的好看是我坚持写作的动力。
另外,关注之后在发送 1024 可领取免费学习资料。资料内容详情请看这篇旧文:Python、C++、Java、Linux、Go、前端、算法资料分享

正文完
 0