参考: https://www.thymeleaf.org/
springboot官方推荐的就是springboot+thymleaf框架,这里讲述一下搭建过程
需要源码的可以到我的github下载 : https://github.com/Feiyu123/Springboot-thymleaf
建立过程和上一篇差不多,新建一个Spring Initializr的WEB工程
可以参考我的上一篇博客 : https://blog.csdn.net/haleyliu123/article/details/80267694
一. 项目的pom.xml文件:
先来看一下项目结构:
springboot+thymleaf基本jar包: spring-boot-starter-web ,spring-boot-starter-test,spring-boot-starter-thymeleaf
4.0.0
com.lrq
demo
0.0.1-SNAPSHOT
jar
demo
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
1.5.1.RELEASE
UTF-8
UTF-8
1.8
1.1.1
1.0.0
1.1.0
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.mybatis.spring.boot
mybatis-spring-boot-starter
${mybatis.version}
tk.mybatis
mapper-spring-boot-starter
${mybatis.tk.version}
com.github.pagehelper
pagehelper-spring-boot-starter
${pagehelper.version}
mysql
mysql-connector-java
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-maven-plugin
二. application.properties(定义各种配置常量)
#启用模板缓存(开发时建议关闭)
spring.thymeleaf.cache = false
#Content-Type值
spring.thymeleaf.content-type = text/html
#在构建URL时预先查看名称的前缀
spring.thymeleaf.prefix = classpath:/templates/
#构建URL时附加查看名称的后缀
spring.thymeleaf.suffix = .html
#测试连接数据库,mybatis用的是SELECT 1
spring.datasource.tomcat.validation-query=SELECT 1
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.driver-class-name= com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
#连接池中允许的最大连接数。缺省值:10;推荐的公式:((core_count * 2) + effective_spindle_count)
spring.datasource.hikari.maximum-pool-size=50
#一个连接的生命时长(毫秒),超时而且没被使用则被释放(retired),缺省:30分钟,建议设置比数据库超时时长少30秒以上
spring.datasource.hikari.max-lifetime=1765000
#端口号
server.port=28082
#访问路径
server.context-path=/demo
#指明mybatis实体类包位置
mybatis.type-aliases-package=com.lrq.demo.model
#指明mappers位置,可以指明多个位置
mybatis.mapper-locations=classpath:mapper/*.xml
#指明分页插件是给mysql用的
pagehelper.helper-dialect=mysql
pagehelper.reasonable=true
pagehelper.support-methods-arguments=true
pagehelper.params=count=countSql
三. logback.xml (配置日志地址)
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -%msg%n
${LOG_HOME}/springboot_demo.log.%d{yyyy-MM-dd}.log
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} -%msg%n
四. src 三层架构搭建
User 类
package com.lrq.demo.model;
import java.util.Objects;
public class User {
private Integer id;
private String name;
private String idNo;
private String gender;
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 String getIdNo() {
return idNo;
}
public void setIdNo(String idNo) {
this.idNo = idNo;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(id, user.id) &&
Objects.equals(name, user.name) &&
Objects.equals(idNo, user.idNo) &&
Objects.equals(gender, user.gender);
}
@Override
public int hashCode() {
return Objects.hash(id, name, idNo, gender);
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", idNo='" + idNo + '\'' +
", gender='" + gender + '\'' +
'}';
}
}
PageInfo类(需要把Page包装成PageInfo对象才能序列化)
package com.lrq.demo.model;
import com.github.pagehelper.Page;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
public class PageInfo implements Serializable {
private static final long serialVersionUID = 1L;
//当前页
private int pageNum;
//每页的数量
private int pageSize;
//总记录数
private long total;
//总页数
private int pages;
//结果集
private List list;
//是否为第一页
private boolean isFirstPage = false;
//是否为最后一页
private boolean isLastPage = false;
public PageInfo() {
}
/**
* 包装Page对象
*
* @param list
*/
public PageInfo(List list) {
if (list instanceof Page) {
Page page = (Page) list;
this.pageNum = page.getPageNum();
this.pageSize = page.getPageSize();
this.pages = page.getPages();
this.list = page;
this.total = page.getTotal();
} else if (list instanceof Collection) {
this.pageNum = 1;
this.pageSize = list.size();
this.pages = 1;
this.list = list;
this.total = list.size();
}
if (list instanceof Collection) {
//判断页面边界
judgePageBoudary();
}
}
/**
* 判定页面边界
*/
private void judgePageBoudary() {
isFirstPage = pageNum == 1;
isLastPage = pageNum == pages;
}
public int getPageNum() {
return pageNum;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public long getTotal() {
return total;
}
public void setTotal(long total) {
this.total = total;
}
public int getPages() {
return pages;
}
public void setPages(int pages) {
this.pages = pages;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public boolean isIsFirstPage() {
return isFirstPage;
}
public void setIsFirstPage(boolean isFirstPage) {
this.isFirstPage = isFirstPage;
}
public boolean isIsLastPage() {
return isLastPage;
}
public void setIsLastPage(boolean isLastPage) {
this.isLastPage = isLastPage;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("PageInfo{");
sb.append("pageNum=").append(pageNum);
sb.append(", pageSize=").append(pageSize);
sb.append(", total=").append(total);
sb.append(", pages=").append(pages);
sb.append(", list=").append(list);
sb.append(", isFirstPage=").append(isFirstPage);
sb.append(", isLastPage=").append(isLastPage);
sb.append(", navigatepageNums=");
sb.append('}');
return sb.toString();
}
}
UserDao类
package com.lrq.demo.dao;
import com.github.pagehelper.Page;
import com.lrq.demo.model.User;
import org.springframework.stereotype.Repository;
import java.util.Map;
@Repository
public interface UserDao {
User getUserByName(Map map);
void addUser(User user);
Page findPageInfoByName(Map map);
}
dao的实现层mapper:user.xml
insert into user
(
name,
idNo,
gender
)values(
#{name},
#{idNo},
#{gender}
)
UserService
package com.lrq.demo.service; import com.github.pagehelper.Page; import com.lrq.demo.model.User; public interface UserService { User getUserByName(String name); void addUser(User user); PagefindByPage(String name,int pageNo, int pageSize); }
UserService的实现层:UserServiceImpl类
package com.lrq.demo.service.impl; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import com.lrq.demo.dao.UserDao; import com.lrq.demo.model.User; import com.lrq.demo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.Map; @Service public class UserServiceImpl implements UserService{ @Autowired private UserDao userDao; @Override public User getUserByName(String name) { Mapmap = new HashMap<>(); map.put("name",name); return userDao.getUserByName(map); } @Override public void addUser(User user) { userDao.addUser(user); } @Override public Page findByPage(String name,int pageNo, int pageSize) { Map map = new HashMap<>(); map.put("name",name); PageHelper.startPage(pageNo, pageSize); return userDao.findPageInfoByName(map); } }
package com.lrq.demo.controller; import com.lrq.demo.model.User; import com.lrq.demo.service.UserService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class UserController { private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class); @Autowired private UserService userService; @GetMapping("/toUserPage") public String toUserPage(Model model){ LOGGER.info("跳转到用户页面"); model.addAttribute("name","Henry"); return "userPage"; } @PostMapping("/getUser") @ResponseBody public User getUser(String name){ LOGGER.info("获取用户信息.name={}",name); User user = userService.getUserByName(name); LOGGER.info("获取用户信息.user={}",user.toString()); return user; } }
package com.lrq.demo; import com.github.pagehelper.Page; import com.lrq.demo.dao.UserDao; import com.lrq.demo.model.PageInfo; import com.lrq.demo.model.User; import com.lrq.demo.service.UserService; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class DemoApplicationTests { private Logger logger = LoggerFactory.getLogger(DemoApplicationTests.class); @Autowired private UserService userService; @Test public void testFindByPage() { Pagepersons = userService.findByPage("H",0,2); // 需要把Page包装成PageInfo对象才能序列化。该插件也默认实现了一个PageInfo PageInfo pageInfo = new PageInfo<>(persons); Assert.assertNotNull(persons); List list = pageInfo.getList(); for(User u : list){ System.out.println(u.toString()); } } }
控制台结果:
表数据:
表中有3条数据带有H的,从pageNo=0开始 取2条数据,刚好吻合
五. thymleaf + html 页面(现在基本用H5页面,不用jsp)
由于现在前后端分离盛行,采用H5页面的方式进行配置。thymleaf作为全新的页面模板框架,比较适用于html。
要html支持thymleaf必须加
html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>userInfotitle>
head>
<body>
<form id="iform" th:action="@{/getUser}" method="post">
<input type="text" th:value="${name}" id="name" name="name" readonly="readonly"/>
<input type="submit" />
form>
body>
html>
用th:value="${name}" 来取model的值,在浏览器输入http://localhost:28082/demo/toUserPage访问页面
提交表单返回结果,成功
再看一下后台