文档地址: http://www.spring-boot.org/doc/
数据校验 1、restful风格类型数据校验 1 2 3 4 @RequestMapping("/valid/{group:[a-zA-Z0-9_]+}/{userid}") public String valid1 (@PathVariable("group") String group, @PathVariable("userid") String userid) { return group+":" +userid; }
2、普通方式参数传递校验 1 2 3 4 5 6 7 8 9 10 @RestController @Validated public class DemoController { @RequestMapping("/vatest") public String validtest2 (@NotBlank (message = "请输入姓名!" ) String name , @Email(message = "电子邮件格式错误!") String email){ return name+"------" +email; } }
3、对象参数校验 相关注解:
@NotNull 限制必须不为null,注意支持String类型校验 用在integer上报错
@NotEmpty 验证注解的元素值不为 null 且不为空(字符串长度不为0、集合大小不为0) 用在integer上报错
@NotBlank 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格 用在integer上报错
@Pattern(value) 限制必须符合指定的正则表达式
@Size(max,min) 限制字符长度必须在 min 到 max 之间(也可以用在集合上)
@Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式
@Max(value) 限制必须为一个不大于指定值的数字
@Min(value) 限制必须为一个不小于指定值的数字
@DecimalMax(value) 限制必须为一个不大于指定值的数字
@DecimalMin(value) 限制必须为一个不小于指定值的数字
@Null 限制只能为null(很少用)
@AssertFalse 限制必须为false (很少用)
@AssertTrue 限制必须为true (很少用)
@Past 限制必须是一个过去的日期
@Future 限制必须是一个将来的日期
@Digits(integer,fraction) 限制必须为一个小数,且整数部分的位数不能超过 integer,小数部分的位数不能超过 fraction (很少用)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 public class Car { @Max(value=100,message="id不能大于100") private int id; @NotBlank(message="用户名不能为空") @Length(min = 2, max = 10, message = "用户名 长度必须在 {min} - {max} 之间") private String name; @DecimalMin(value="1.0",message="价格最低1元") @DecimalMax(value="10.0",message="价格最高10元") private float price; @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd hh:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss") private Date createDate; @JsonIgnore private String memo; @JsonInclude @NotNull(message="属性字段不能为空") @NotBlank(message="属性字段不能为空白") private String isnull; @Max(value=1000,message = "id最大1000") private Integer id; @Pattern(regexp = "[a-z]+" ,message = "参数a-z") private String name; @Max(value = 100,message = "age最大100") private Integer age; }
json参数校验
1 2 3 4 5 6 @RequestMapping("/vatest3") public User validtest3 (@RequestBody @Validated User user) { return user; }
统一异常处理类
使用这个则会直接返回异常信息到页面而不是系统错误信息页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package com.syl.demo01.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.*;import javax.validation.ConstraintViolation;import javax.validation.ConstraintViolationException;import java.lang.invoke.ConstantCallSite;@ControllerAdvice public class CustomExceptioinHandler { @ExceptionHandler(ConstraintViolationException.class) @ResponseBody @ResponseStatus public String test01 (ConstraintViolationException e) { for (ConstraintViolation<?> s : e.getConstraintViolations()) { return s.getInvalidValue() + ": " + s.getMessage(); } return "请求参数不合法!" ; } }
springBoot静态资源 默认静态资源映射
Spring Boot 对静态资源映射提供了默认配置
Spring Boot 默认将 /** 所有访问映射到以下目录:
classpath:/static
classpath:/public
classpath:/resources
classpath:/META-INF/resources
如:在resources目录下新建 public、resources、static 三个目录,并分别放入 a.jpg b.jpg c.jpg 图片
浏览器访问
http://localhost:8080/a.jpg
http://localhost:8080/b.jpg
http://localhost:8080/c.jpg
自定义静态资源访问
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package com.syl.demo01.controller;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration public class StaticConfiguer implements WebMvcConfigurer { @Override public void addResourceHandlers (ResourceHandlerRegistry registry) { registry.addResourceHandler("/pic/**" ).addResourceLocations("file:E:\\pic\\" ); } }
web.upload-path:这个属于自定义的属性,指定了一个路径,注意要以/结尾;
spring.mvc.static-path-pattern=/**:表示所有的访问都经过静态资源路径;
spring.resources.static-locations:在这里配置静态资源路径,前面说了这里的配置是覆盖默认配置,所以需要将默认的也加上否则static、public等这些路径将不能被当作静态资源路径,在这个最末尾的file:${web.upload-path}之所有要加file:是因为指定的是一个具体的硬盘路径,其他的使用classpath指的是系统环境变量。
1 2 3 4 5 6 web.upload-path =E:/pic/ spring.mvc.static-path-pattern =/** spring.resources.static-locations =classpath:/META-INF/resources/,classpath:/resources/,\ classpath:/static/,classpath:/public/,file:${web.upload-path}
配置文件属性application.yml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 server: port: 8888 servlet: context-path: /java001 name: jerry age: 123 user: name:"tom" age:12
自定义配置文件
application.yml是系统默认的配置文件,当然我们也可以创建自定义配置文件,在路径src/main/resources下面创建文件test.properties
注意:spring boot 1.5版本后@PropertySource注解就不能加载自定义的yml配置文件了
springboot整合mybatis
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 8.0.17</version > </dependency > <dependency > <groupId > org.mybatis.spring.boot</groupId > <artifactId > mybatis-spring-boot-starter</artifactId > <version > 2.0.0</version > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > 1.1.20</version > </dependency >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 spring: datasource: url: jdbc:mysql://localhost:3306/dfdata?serverTimezone=UTC type: com.alibaba.druid.pool.DruidDataSource username: root password: root001 driver-class-name: com.mysql.cj.jdbc.Driver mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.syl.demo01.entity
编写service、serviceimpl,在dao包里创建UserMapper.java,在resources文件夹下创建mapper文件夹,在mapper文件夹下创建usermapper.xml,指定nameplace为usermapper.java的全类名路径,最后不要忘了在启动类上加注解包扫描mapper类
UserService.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import com.syl.demo01.entity.User;import java.util.List;public interface UserService { public List<User> getUserList () ; public void createUser (User user) ; public User getUser (Integer id) ; public void updateUser (Integer id,User user) ; public void deleteUser (Integer id) ; }
UserServiceImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 package com.syl.demo01.service.impl;import com.syl.demo01.dao.UserMapper;import com.syl.demo01.entity.User;import com.syl.demo01.service.UserTest;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;@Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public List<User> getUserList () { return userDao.getAll(); } @Override public void createUser (User user) { userDao.save(user); } @Override public User getUser (Integer id) { return userDao.findOne(id); } @Override public void updateUser (Integer id, User user) { user.setId(id); userDao.update(user); } @Override public void deleteUser (Integer id) { userDao.delete(id); } }
UserMapper.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import com.syl.demo01.entity.User;import java.util.List;public interface UserMapper { List<User> getAll () ; void save (User user) ; User findOne (Integer id) ; void update (User user) ; void delete (Integer id) ; }
UserMapper.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <?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.syl.demo01.dao.UserMapper" > <select id ="getAll" resultType ="com.syl.demo01.entity.User" > select * from ut </select > <insert id ="save" parameterType ="com.syl.demo01.entity.User" > insert into ut (id,name,age) values (#{id},#{name},#{age}) </insert > <select id ="findOne" parameterType ="java.lang.Integer" resultType ="com.syl.demo01.entity.User" > select * from ut where id=#{id} </select > <update id ="update" parameterType ="com.syl.demo01.entity.User" > update ut set name=#{name},age=#{age} where id=#{id} </update > <delete id ="delete" parameterType ="java.lang.Integer" > delete from ut where id=#{id} </delete > </mapper >
Application.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package com.syl.demo01;import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication @MapperScan("com.syl.demo01.dao") public class Application { public static void main (String[] args) { SpringApplication.run(Demo01Application.class, args); } }
SpringBoot使用JPA操作数据库 文档地址: https://docs.spring.io/spring-data/jpa/docs/2.2.1.RELEASE/reference/html/#reference
1、添加依赖 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <parent > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-parent</artifactId > <version > 2.1.7.RELEASE</version > <relativePath /> </parent > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-data-jpa</artifactId > </dependency > <dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 8.0.17</version > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > 1.1.20</version > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web-services</artifactId > </dependency >
2、在application.yml添加数据库配置 1 2 3 4 5 6 7 8 9 10 11 spring: datasource: url : jdbc:mysql://localhost:3306/test2?serverTimezone=GMT%2B8 type : com.alibaba.druid.pool.DruidDataSource username : root password : root001 driver-class-name : com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: true
3、编写代码实现简单CRUD jpa常用注解
注解
作用
@Entity
声明类为实体或表
@Table
声明表名
@Basic
指定非约束明确的各个字段
@Embedded
指定类或它的值是一个可嵌入的类的实例的实体的属性
@Id
指定的类的属性,用于识别(一个表中的主键)
@GeneratedValue
指定如何标识属性可以被初始化,例如自动、手动、或从序列表中获得的值
@Transient
指定的属性,它是不持久的,即:该值永远不会存储在数据库中
@Column
指定持久属性栏属性
@SequenceGenerator
指定在@GeneratedValue注解中指定的属性的值。它创建了一个序列
@TableGenerator
指定在@GeneratedValue批注指定属性的值发生器。它创造了的值生成的表
@AccessType
这种类型的注释用于设置访问类型。如果设置@AccessType(FIELD),则可以直接访问变量并且不需要getter和setter,但必须为public。如果设置@AccessType(PROPERTY),通过getter和setter方法访问Entity的变量
@JoinColumn
指定一个实体组织或实体的集合。这是用在多对一和一对多关联
@UniqueConstraint
指定的字段和用于主要或辅助表的唯一约束
@ColumnResult
参考使用select子句的SQL查询中的列名
@ManyToMany
定义了连接表之间的多对多一对多的关系
@ManyToOne
定义了连接表之间的多对一的关系
@OneToMany
定义了连接表之间存在一个一对多的关系
@OneToOne
定义了连接表之间有一个一对一的关系
@NamedQueries
指定命名查询的列表
@NamedQuery
指定使用静态名称的查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 package com.springboot.day02.entity;import javax.persistence.Column;import javax.persistence.Id;import javax.persistence.Entity;import javax.persistence.GeneratedValue;@Entity public class User { @Id @GeneratedValue private Integer id; @Column(name = "name",nullable = true,length = 20) private String name; @Column(name = "age",nullable = true, length = 3) private Integer age; public User () {} public User (Integer id, String name, Integer age) { this .id = id; this .name = name; this .age = age; } 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 Integer getAge () { return age; } public void setAge (Integer age) { this .age = age; } }
接口UserRepository
1 2 3 4 5 6 7 8 9 10 11 12 13 package com.springboot.day02.dao;import com.springboot.day02.entity.User;import org.springframework.data.jpa.repository.JpaRepository;public interface UserRepository extends JpaRepository <User,Integer> {}
controller层简单增删改查代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 package com.springboot.day02.controller;import com.springboot.day02.dao.UserRepository;import com.springboot.day02.entity.User;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import java.util.List;import java.util.Optional;@RestController public class JpaTestController { @Autowired UserRepository userRepository; @GetMapping("findAll") public List<User> findAll () { return userRepository.findAll(); } @PostMapping("save") public String save (User user) { userRepository.save(user); return "success" ; } @GetMapping("findOne/{id}") public Optional<User> findone (@PathVariable Integer id) { Optional<User> user = userRepository.findById(id); System.out.println(user); return user; } @PutMapping("update") public String update (User user) { User user1 = userRepository.saveAndFlush(user); if (user1!=null ){ return "success" ; } return "fail" ; } @DeleteMapping("delete/{id}") public String delete (@PathVariable Integer id ) { userRepository.deleteById(id); return "success" ; } }
4、复杂查询 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 package com.springboot.day02.dao;import com.springboot.day02.entity.User;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.data.jpa.repository.Query;import java.util.List;public interface UserRepository extends JpaRepository <User,Integer> { List<User> findByNameIs (String name) ; List<User> findByIdBetween (Integer id1,Integer id2) ; List<User> findByIdLessThan (Integer id) ; List<User> findByIdLessThanEqual (Integer id) ; List<User> findByAgeGreaterThan (Integer id) ; List<User> findByAgeAfter (Integer id) ; List<User> findByNameIsNotNull () ; List<User> findByNameNotNull () ; List<User> findByNameIsNull () ; List<User> findByNameLike (String name) ; List<User> findByIdOrderByAgeDesc (Integer id) ; List<User> findByIdOrderByAgeAsc (Integer id) ; }
Keyword
Sample
JPQL snippet
And
findByLastnameAndFirstname
… where x.lastname = ?1 and x.firstname = ?2
Or
findByLastnameOrFirstname
… where x.lastname = ?1 or x.firstname = ?2
Is,Equals
findByFirstnameEquals
where x.firstname = ?1
Between
findByStartDateBetween
where x.startDate between ?1 and ?2
LessThan
findByAgeLessThan
where x.age < ?1
LessThanEqual
findByAgeLessThanEqual
where x.age < ?1
GreaterThan
findByAgeGreaterThan
where x.age > ?1
GreaterThanEqual
findByAgeGreaterThanEqual
where x.age >= ?1
After
findByStartDateAfter
where x.startDate > ?1
Before
findByStartDateBefore
where x.startDate < ?1
IsNull
findByAgeIsNull
where x.age is null
IsNotNull,NotNull
findByAge(Is)NotNull
where x.age not null
Like
findByFirstnameLike
where x.firstname like ?1
NotLike
findByFirstnameNotLike
where x.firstname not like ?1
StartingWith
findByFirstnameStartingWith
where x.firstname like ?1 (parameter bound with appended %)
EndingWith
findByFirstnameEndingWith
where x.firstname like ?1 (parameter bound with prepended %)
Containing
findByFirstnameContaining
where x.firstname like ?1 (parameter bound wrapped in %)
OrderBy
findByAgeOrderByLastnameDesc
where x.age = ?1 order by x.lastname desc
Not
findByLastnameNot
where x.lastname <> ?1
In
findByAgeIn(Collection ages)
where x.age in ?1
NotIn
findByAgeNotIn(Collection age)
where x.age not in ?1
True
findByActiveTrue()
where x.active = true
False
findByActiveFalse()
where x.active = false
IgnoreCase
findByFirstnameIgnoreCase
where UPPER(x.firstame) = UPPER(?1)
5、自定义查询 dao层接口
1 2 3 4 5 6 7 8 9 10 @Query("select u from User u where name=:name and age=:age") User findByNameAndAge (String name,Integer age) ; @Query("select u from User u where name like %:name%") List<User> findByNameLike (String name) ; @Query(value = "select * from user u where length(name)=:length ",nativeQuery = true) List<User> findNameIsFour (Integer length) ;
controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @RequestMapping("findByNameAndAge/{name}/{age}") public User findByNameAndAge (@PathVariable String name,@PathVariable Integer age) { return userRepository.findByNameAndAge(name,age); } @RequestMapping("findByNameLike/{name}") public List<User> findByNameLike (@PathVariable String name) { return userRepository.findByNameLike(name); } @RequestMapping("findNameIsFour/{len}") public List<User> findNameIsFour (@PathVariable Integer len) { return userRepository.findNameIsFour(len); }
6、SpringBoot 使用JPA @Modifying和@Query、@Transactional注解DML 1 2 3 4 5 6 7 8 9 10 @Modifying @Transactional @Query("update User u set name=:name where id=:id") int updateName (String name,Integer id) ;@Modifying @Transactional @Query("delete from User where id=:id") int deleteUser (Integer id) ;
controller
1 2 3 4 5 6 7 8 9 10 11 12 13 @RequestMapping("updateName/{name}/{id}") public String updateName (@PathVariable String name,@PathVariable Integer id) { int i = userRepository.updateName(name, id); return i>0 ?"success" :"fail" ; } @RequestMapping("deleteUser/{id}") public String deleteUser (@PathVariable Integer id) { int i = userRepository.deleteUser(id); return i>0 ?"success" :"fail" ; }
7、jpa分页排序
1 2 3 4 Sort.sort(Person.class); Sort.by("firstname" ).ascending().and(Sort.by("lastname" ).descending());
dao
1 List<User> findByNameContaining (String name, Sort sort) ;
controller
1 2 3 4 5 6 @RequestMapping("findByNameContaining/{name}/{filed}") public List<User> findByNameContaining (@PathVariable String name,@PathVariable String filed) { List<User> byNameContaining = userRepository.findByNameContaining(name, Sort.by(filed).descending()); return byNameContaining; }
dao
1 Page<User> findAll (Pageable pageable) ;
controller
1 2 3 4 @RequestMapping("findAllPager") public Page<User> findAllPager () { return userRepository.findAll(PageRequest.of(1 , 5 ,Sort.by("age" ).ascending())); }
dao
1 Slice<User> findByNameContaining (String name,Pageable pageable) ;
controller
1 2 3 4 @RequestMapping("getAll/{name}") public Slice<User> getAll (@PathVariable String name) { return userRepository.findByNameContaining(name,PageRequest.of(1 , 2 ,Sort.by("age" ).ascending())); }
8、一对多 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @Entity public class Phone { @Id @GeneratedValue private Integer id; private String name; private Integer pid; } @Entity public class Person { @Id @GeneratedValue private Integer id; @Column(name = "name",length = 20) private String name; @OneToMany(mappedBy = "pid",cascade = CascadeType.ALL,fetch = FetchType.EAGER) private List<Phone> phones; }
dao
1 2 3 4 5 6 public interface PersonRepository extends JpaRepository <Person, Integer> { @Query("select p1 from Person p1 ,Phone p2 where p1.id=:id and p1.id=p2.pid") Person findPerson (Integer id) ; }
controller
1 2 3 4 5 6 @RequestMapping("findPerson/{id}") public Person findPerson (@PathVariable Integer id) { return personRepository.findPerson(id); }
9、多对多 老师和学生多对多,以老师作为主表维护中间表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 @Entity @JsonIgnoreProperties("teachers") public class Student { @Id @GeneratedValue private Integer id; private String name; @ManyToMany(mappedBy = "students") private List<Teacher> teachers; } @Entity public class Teacher { @Id @GeneratedValue private Integer id; private String name; @ManyToMany @JoinTable(name="tea_stu", //中间表的表名,默认 主表_从表 joinColumns=@JoinColumn(name="tea_id"), //字段一 inverseJoinColumns=@JoinColumn(name="stu_id")) private List<Student> students;
10、springBoot中使用Thymeleaf(百里香) 依赖
1 2 3 4 5 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-thymeleaf</artifactId > </dependency >
application.yml中配置
1 2 3 4 5 spring: thymeleaf: cache: false
resources/templates/index.html
1 2 3 4 5 6 7 8 9 10 11 <!DOCTYPE html > <html lang ="en" xmlns:th ="http://www.thymeleaf.org" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <h1 th:text ="${message}" > </h1 > </body > </html >
controller
1 2 3 4 5 6 7 8 9 10 11 @Controller public class ThymeleafController { @GetMapping("/first") public String indexPage (Model model) { String message = "Hello, Thymeleaf!" ; model.addAttribute("message" , message); return "index" ; } }
从model中取值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 <h1 th:text ="${userName}" > </h1 > <input type ="text" name ="names" th:value ="${userName}" /> <span th:text ="'欢迎来:'+${userName}+'学习!'" > </span > <span th:text ="|欢迎来:${userName}学习!|" > </span > <span th:text ="${user.id}" > </span > <img th:src ="${src.src2}" /> <tr th:each ="u,iterStat : ${userList}" > <td th:text ="${u.id}" > </td > <td th:text ="${u.name}" > </td > <td th:text ="${u.age}" > </td > <td th:text ="${iterStat.count}" > count</td > </tr > <h1 th:if ="${flag=='yes'}" > oh yes</h1 > <h1 th:unless ="${flag=='no'}" > oh No</h1 > <div th:switch ="${menu}" > <p th:case ="'admin'" > User is an administrator</p > <p th:case ="${manager}" > User is a manager</p > </div >
1 <link rel ="stylesheet" type ="text/css" media ="all" href ="../../css/gtvg.css" th:href ="@{/css/gtvg.css}" />
当我们在没有后台渲染的情况下,浏览器会认得href, 当我们在有后台渲染的情况下,后台会把这个标签渲染为这样:
1 <link rel ="stylesheet" type ="text/css" media ="all" href ="/css/gtvg.css" />
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <!doctype html > <html xmlns ="http://www.w3.org/1999/xhtml" xmlns:th ="http://www.thymeleaf.org" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <body > <h1 th:fragment ="copy" > © 1999-2018 Offcn.All Rights Reserved </h1 > </body > </body > </html >
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <div th:insert ="~{footer :: copy}" > </div > </br > <div th:replace ="~{footer :: copy}" > </div > </br > <div th:include ="~{footer :: copy}" > </div >
常见内置工具对象
#dates
#numbers
#strings
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 时间:<span th:text ="${#dates.format(date,'yyyy-MM-dd HH:mm:ss')}" > 4564546</span > </br > 金额:<span th:text ="'¥'+${#numbers.formatDecimal(price, 1, 2)}" > 180</span > </br > <p th:text ="${#strings.abbreviate(strText,60)}" > 内容内容内容</p > <span th:if ="${!#strings.isEmpty(str2)}" > 字符串str2不为空</span > </br > <span th:text ="${#strings.substring(str2,0,4)}" > 字符串str2的值</span > </body >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <input type ="text" class ="form-control" name ="name" id ="name" th:value ="*{name}" placeholder ="name" /> <a href ="toAdd" th:href ="@{toAdd}" class ="btn btn-info" > add</a > <tr th:each ="user : ${page}" > <th scope ="row" th:text ="${user.id}" > 1</th > <td th:text ="${user.name}" > neo</td > <td th:text ="${user.age}" > 6</td > <td > <a th:href ="@{'toEdit/'+${user.id}}" > edit</a > </td > <td > <a th:href ="@{'delete/'+${user.id}}" > delete</a > </td > </tr > <form class ="form-horizontal" th:action ="@{add}" method ="post" > </form > <form class ="form-horizontal" th:action ="@{/manageruser/edit}" th:object ="${user}" method ="post" > <input type ="text" name ="name" th:value ="*{name}" /> </form >