wordpress模板 站长,医疗器械网上商城,初中作文网,塑料模板目录
一、FreeMarker 简介
1.1 什么是FreeMarker#xff1f;
1.2 Freemarker模板组成部分
1.3 为什么要使用FreeMarker
二、Springboot集成FreeMarker
2.1 配置
2.2 数据类型
2.2.1 字符串
2.2.2 数值
2.2.3 布尔值
2.2.4 日期
2.3 常见指令
2.3.2 assign
2.3…目录
一、FreeMarker 简介
1.1 什么是FreeMarker
1.2 Freemarker模板组成部分
1.3 为什么要使用FreeMarker
二、Springboot集成FreeMarker
2.1 配置
2.2 数据类型
2.2.1 字符串
2.2.2 数值
2.2.3 布尔值
2.2.4 日期
2.3 常见指令
2.3.2 assign
2.3.3 include
...
三、常见指令实现增删改查综合案例⭐
3.1 后端
3.2 前端
3.3 效果展示
3.3.1 新增功能
3.3.2 修改功能
3.3.3 查询功能
3.3.4 删除功能 一、FreeMarker 简介
1.1 什么是FreeMarker FreeMarker是一款 模板引擎 它允许开发人员使用模板和数据来生成输出文本如HTML网页、电子邮件、配置文件和源代码等。它是一个Java类库可以被嵌入到开发人员所创建的产品中。开发人员可以使用FreeMarker来动态生成和渲染视图以便将数据呈现给最终用户。
官方手册https://freemarker.apache.org/
下面是一些关键点 模板引擎 FreeMarker是一种模板引擎允许开发者定义模板文件其中包含要动态填充的占位符或表达式。这些模板文件可以包含HTML、XML、文本等。 动态内容生成 FreeMarker的主要用途是根据模板和数据生成最终的输出内容。模板中的占位符将被实际的数据替代从而生成动态的、个性化的输出。 嵌入式组件 FreeMarker是一个Java类库可以轻松地集成到Java应用程序中。这使得开发人员可以在他们的Java应用中使用FreeMarker来处理视图层的动态内容生成。 面向程序员 FreeMarker通常被程序员用于构建动态的用户界面或生成其他类型的文本输出。它不直接面向最终用户而是提供给开发人员一个工具使他们能够以更灵活和动态的方式生成内容。 1.2 Freemarker模板组成部分
FreeMarker模板文件主要由如下4个部分组成: 文本直接输出的部分 注释使用 #-- ... -- 格式做注释里面内容不会输出 插值即 ${...} 或 #{...} 格式的部分类似于占位符将使用数据模型中的部分替代输出 FTL指令即FreeMarker指令全称是FreeMarker Template Language和HTML标记类似但名字前加#予以区分不会输出 1.3 为什么要使用FreeMarker
FreeMarker在Spring Boot中被广泛使用的原因与其特性和与Spring Boot的集成有关。 轻量级 FreeMarker相对轻量不引入过多的依赖易于集成和使用。 与Spring框架整合良好 FreeMarker与Spring框架集成良好通过Spring Boot的自动配置可以很容易地配置FreeMarker作为模板引擎。 Spring Boot 默认支持 Spring Boot对多个模板引擎提供了自动配置支持包括FreeMarker。因此Spring Boot项目中使用FreeMarker非常方便只需在依赖中引入相应的starter即可。 开箱即用 FreeMarker可以作为Spring Boot的一部分无需额外的配置。这使得开发者能够快速启动项目并使用FreeMarker构建视图。 简化模板文件的构建 FreeMarker的模板语法相对简洁可以更容易地与后端Java代码交互。在Spring Boot项目中Java对象的数据可以直接在FreeMarker模板中使用。 FreeMarker的诞生是为了取代JSP。虽然JSP功能强大可以写Java代码实现复杂的逻辑处理但是页面会有大量业务逻辑不利于维护和阅读更不利于前后台分工容易破坏MVC结构所以舍弃JSP选择使用FreeMarker是大势所趋。 二、Springboot集成FreeMarker
2.1 配置
1、配置pom.xml引入依赖
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-freemarker/artifactId
/dependency 2、添加application.yml配置 freemarker:# 设置模板后缀名suffix: .ftl# 设置文档类型content-type: text/html# 设置页面编码格式charset: UTF-8# 设置页面缓存cache: false# 设置ftl文件路径template-loader-path: classpath:/templates# 设置静态文件路径js,css等mvc:static-path-pattern: /static/** 3、新建模板文件.ftl
在resources/templates目录新建一个.ftl文件 第一创建是没有这个文件类型的选项的所以我们要定义个.ftl格式的文件 settings -- Editor -- File and Code Templates 该内容模板于html差不多的最后在创建文件的时候就有个一个.ftl格式的文件选项 index.ftl
!DOCTYPE html
html langzh
headmeta charsetUTF-8titleFreemarker/title
/head
body
h1Hello FreeMarker!!!/h1
/body
/html
Controller
package com.ycxw.boot.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;/*** author 云村小威* create 2023-12-13 18:57*/
Controller
public class IndexController {RequestMapping(/)public String home(){return index;}
}一个基本的数据显示就成功了 2.2 数据类型
2.2.1 字符串 在文本中确定字符串值的方法是看双引号比如 some text或单引号比如 some text。这两种形式是等同的。 如果文本自身包含用于字符引用的引号 ( 或 )或反斜杠时 应该在它们的前面再加一个反斜杠这就是转义。 转义允许直接在文本中输入任何字符 也包括换行。 ${Its \quoted\ and this is a backslash: \\} 字符串类型处理
方法含义?substring(start,end)截取字符串左闭右开?uncap_first首字母小写输出?cap_first首字母大写输出?lower_case字母转小写输出?upper_case字母转大写输出?length获取字符串长度?starts_with(xx)?string是否以指定字符开头boolean类型?ends_with(xx)?string是否以指定字符结尾boolean类型?index_of(xx)获取指定字符的索引?trim去除字符串前后空格?replace(xx,xx)替换指定字符串
字符串空值情况处理
FreeMarker 的变量必须赋值否则就会抛出异常。而对于 FreeMarker 来说null 值和不存在的变量是完全一样的因为 FreeMarker 无法理解 null 值。
#-- 如果值不存在直接输出会报错 --
#--${str}--
#-- 使用!当值不存在时默认显示空字符串 --
${str!}br
#-- 使用!xx当值不存在时默认显示指定字符串 --
${str!这是一个默认值}br
#-- 使用??判断字符串是否为空返回布尔类型。如果想要输出需要将布尔类型转换成字符串 --
${(str??)?string}br 注意事项 使用??或?starts_with(xx)判断字符串是否为空或指定字符开头返回布尔类型。如果想要输出需要将布尔类型转换成字符串在后面添加 ?c or ?string 例如 ${嗨害嗨?starts_with(我)}
${str??} 不进行转换则会报错 2.2.2 数值
输入不带引号的数字就可以直接指定一个数字 必须使用点作为小数的分隔符而不能是其他的分组分隔符。
${0.45}br
${18}br
#-- 将数值转换成字符串输出 --
${1000?c} br
#-- 将数值转换成货币类型的字符串输出 --
${1000?string.currency} br
#-- 将数值转换成百分比类型的字符串输出 --
${0.45?string.percent} br
#-- 将浮点型数值保留指定小数位输出 ##表示保留两位小数 --
${0.45723123?string[0.##]} br
2.2.3 布尔值
直接写 true 或者 false 就表示一个布尔值了不需使用引号。 在freemarker中布尔类型不能直接输出如果输出要先转成字符串 ${flag?c}br
${flag?string}br
${flag?string(yes,no)}br 2.2.4 日期
日期变量可以存储和日期/时间相关的数据。 在freemarker中日期类型不能直接输出如果输出要先转成日期型或字符串 日期格式输出
输出方式说明?date年月日?time时分秒?datetime年月日时分秒?string(自定义格式)指定格式
#-- 输出日期格式 --
${createDate?date} br
#-- 输出时间格式 --
${createDate?time} br
#-- 输出日期时间格式 --
${createDate?datetime} br
#-- 输出格式化日期格式 --
${createDate?string(yyyy年MM月dd日 HH时mm分ss秒)} br 注意事项 在.ftl文件中不能直接创建时间需要通过后端传入时间进行显示替换掉createDate 2.3 常见指令
2.3.2 assign
使用该指令你可以创建一个新的变量 或者替换一个已经存在的变量。
案例演示
#-- 创建一个str的变量 --
#assign strhello
#-- 输出str --
${str} br
#-- 一次创建多个变量 --
#assign num1 names[嗨,害,嗨]
${num} and ${names?join(,)} 2.3.3 include
可以使用它在你的模板中插入另外一个 FreeMarker 模板文件 (由 path 参数指定) 该标签主要用于引入其他资源简化数据 首先创建一个公共页面定义一个变量存储本地访问路径 在index.ftl中进行引入调用src数值
#-- 引入公共页面 --
#include common.ftl
a href${src}/xxx/a ... 还有如if/elseif/else、list指令在下面的综合案例中进行演示 三、常见指令实现增删改查综合案例⭐
3.1 后端
BookMapper.xml select idlist resultMapBaseResultMap resultTypecom.ycxw.boot.entity.Bookselectinclude refidBase_Column_List/from t_bookwhere 11if testbookname !null and bookname !and bookname like CONCAT(%,#{bookname},%)/if/select 在此添加了模糊查询的方法其他的增删改都是自动生成。 BookMapper.java
package com.ycxw.boot.mapper;import com.ycxw.boot.entity.Book;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;import java.util.List;/**
* author 云村小威
* description 针对表【t_book(书本信息表)】的数据库操作Mapper
* createDate 2023-12-12 14:50:45
* Entity com.ycxw.boot.entity.Book
*/
Repository
public interface BookMapper {ListBook list(Param(bookname)String bookname);...其他方法
}BookService.java
package com.ycxw.boot.service;import com.ycxw.boot.entity.Book;
import org.apache.ibatis.annotations.Param;import java.util.List;/*** author 云村小威* create 2023-12-12 15:11*/
public interface BookService {ListBook list(Param(bookname)String bookname);int insert(Book record);int deleteByPrimaryKey(Long id);int updateByPrimaryKey(Book record);
}BookServiceImpl.java
package com.ycxw.boot.service.impl;import com.ycxw.boot.entity.Book;
import com.ycxw.boot.mapper.BookMapper;
import com.ycxw.boot.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;/*** author 云村小威* create 2023-12-12 15:12*/
Service
public class BookServiceImpl implements BookService {Autowiredprivate BookMapper bookMapper;Overridepublic ListBook list(String bookname) {return bookMapper.list(bookname);}Overridepublic int insert(Book record) {return bookMapper.insert(record);}Overridepublic int deleteByPrimaryKey(Long id) {return bookMapper.deleteByPrimaryKey(id);}Overridepublic int updateByPrimaryKey(Book record) {return bookMapper.updateByPrimaryKey(record);}
}IndexController.java
package com.ycxw.boot.controller;import com.ycxw.boot.entity.Book;
import com.ycxw.boot.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;import java.util.List;/*** author 云村小威* create 2023-12-13 18:57*/
Controller
public class IndexController {Autowiredprivate BookService bookService;/*** 查询所有** param model* return*/RequestMapping(/)public String home(Model model) {ListBook list bookService.list(null);model.addAttribute(book, list);return index;}/*** 新增** param book* return*/PostMapping(/add)public String add(RequestBody Book book) {bookService.insert(book);return redirect:/;}/*** 删除** param book* return*/RequestMapping(/del)public String del(Book book) {bookService.deleteByPrimaryKey(book.getId().longValue());return redirect:/;}/*** 修改** param book* return*/PutMapping(/edit)public String edit(RequestBody Book book) {bookService.updateByPrimaryKey(book);return redirect:/;}/*** 模糊查询** param bookname* param model* return*/RequestMapping(value /search, method RequestMethod.POST)public String search(RequestParam(bookname) String bookname, Model model) {// 在这里使用 bookname 进行相关的处理ListBook list bookService.list(bookname);model.addAttribute(book, list);return index; // 返回搜索结果页面}}3.2 前端
common.ftl 公共资源
#--引入当前项目的运行路径--
#assign src${springMacroRequestContext.contextPath}
#--引入样式与脚本--
link relstylesheet hrefhttps://cdn.jsdelivr.net/npm/bootstrap5.1.0/dist/css/bootstrap.min.css
script srchttps://code.jquery.com/jquery-3.6.1.min.js/script
!-- 引入Bootstrap的JavaScript文件需要在jQuery之后引入 --
script srchttps://cdn.jsdelivr.net/npm/bootstrap5.1.0/dist/js/bootstrap.bundle.min.js/scriptindex.ftl自定义引擎模版
!DOCTYPE html
html langzh
headmeta charsetUTF-8titleFreeMarker/title#--引入公共模块--#include common.ftl
/head
body
div classcontainer mt-5 idbodydiv classrow justify-content-centerdiv classcol-3input typetext classform-control idinput placeholder请输入书籍名称stylewidth: 300px//divdiv classcol-2button typesubmit classbtn btn-dark mb-3 onclickquery()搜索/buttonbutton typebutton classbtn btn-outline-dark mb-3 data-bs-togglemodaldata-bs-target#exampleModal新增书籍/button/div/divdiv classrowtable classtable table-hover stylewidth: 65%;margin: autothead classtable-darktrth序号/thth书籍名称/thth价格/thth类型/thth操作/th/tr/theadtbody#if book??#list book as btrtd${b.id}/tdtd${b.bookname}/tdtd${b.price}/tdtd${b.booktype}/tdtda href${src}/del?id${b.id}删除/aa hrefjavascript:void(0);onclickeditModal(${b.id}, ${b.bookname}, ${b.booktype}, ${b.price})data-bs-togglemodal data-bs-target#editModal修改/a/td/tr/#list/#if/tbody/table/div
/div
!-- 新增弹窗 --
div classmodal fade idexampleModal tabindex-1 aria-labelledbyexampleModalLabel aria-hiddentruediv classmodal-dialogdiv classmodal-contentdiv classmodal-headerh5 classmodal-title idexampleModalLabel新增书籍/h5button typebutton classbtn-close data-bs-dismissmodal aria-labelClose/button/divdiv classmodal-body!-- 表单 --formdiv classmb-3label fortitle classform-label书籍名称/labelinput typetext classform-control idname placeholder请输入标题/divdiv classmb-3label forauthor classform-label类型/labelselect classform-select idbookType aria-labelDefault select exampleoption selected请选择书籍类型/optionoption value动作动作/optionoption value冒险冒险/optionoption value文学文学/option/select/divdiv classmb-3label forprice classform-label价格/labelinput typenumber classform-control idprice placeholder请输入价格/divbutton typebutton classbtn btn-outline-dark data-bs-dismissmodal aria-labelClose取消/buttonbutton typebutton classbtn btn-dark onclickadd()提交/button/form/div/div/div
/div
!-- 修改弹窗 --
div classmodal fade ideditModal tabindex-1 aria-labelledbyexampleModalLabel aria-hiddentruediv classmodal-dialogdiv classmodal-contentdiv classmodal-headerh5 classmodal-title idexampleModalLabel修改书籍/h5button typebutton classbtn-close data-bs-dismissmodal aria-labelClose/button/divdiv classmodal-body!-- 表单 --formdiv classmb-3label forid classform-label书籍编号/labelinput typetext classform-control idid disabled/divdiv classmb-3label fortitle classform-label书籍名称/labelinput typetext classform-control idname_edit placeholder请输入标题/divdiv classmb-3label forauthor classform-label类型/labelselect classform-select idtype_edit aria-labelDefault select exampleoption selected请选择书籍类型/optionoption value动作动作/optionoption value冒险冒险/optionoption value文学文学/option/select/divdiv classmb-3label forprice classform-label价格/labelinput typenumber classform-control idprice_edit placeholder请输入价格/divbutton typebutton classbtn btn-outline-dark data-bs-dismissmodal aria-labelClose取消/buttonbutton typebutton classbtn btn-dark onclickedit()确认修改/button/form/div/div/div
/div
/body
script/*模糊查询*/function query() {//获取输入值var name $(#input).val();// 发送AJAX请求$.ajax({url: ${src}/search,type: POST,contentType: application/x-www-form-urlencoded,data: {bookname: name},success: function (data) {//更新整个页面元素$(#body).html(data);}});}/*新增方法*/function add() {// 获取表单数据var name $(#name).val();var type $(#bookType).val();var price $(#price).val();// 创建一个对象来存储表单数据var book {bookname: name,booktype: type,price: price};// 发送AJAX请求$.ajax({url: ${src}/add,type: POST,contentType: application/json,data: JSON.stringify(book),success: function (res) {console.log(res);// 请求成功处理逻辑alert(书籍添加成功);// 关闭弹窗var modal $(#exampleModal);modal.modal(hide);// 刷新页面location.reload();}});}/* 修改方法(回显数据) */function editModal(id, name, type, price) {// 将数据设置到弹窗表单中$(#id).val(id);$(#name_edit).val(name);$(#type_edit).val(type);$(#price_edit).val(price);// 显示修改弹窗$(#editModal).modal(show);}/*修改方法*/function edit() {// 获取表单数据var id $(#id).val();var name $(#name_edit).val();var type $(#type_edit).val();var price $(#price_edit).val();// 创建一个对象来存储表单数据var book {id: id,bookname: name,booktype: type,price: price};// 发送AJAX请求$.ajax({url: ${src}/edit,type: PUT,contentType: application/json,data: JSON.stringify(book),success: function (res) {console.log(res);// 请求成功处理逻辑alert(书籍修改成功);// 关闭弹窗var modal $(#editModal);modal.modal(hide);// 刷新页面location.reload();}});}
/script
/html 3.3 效果展示
3.3.1 新增功能 3.3.2 修改功能 3.3.3 查询功能 3.3.4 删除功能