• springboot:视图渲染技术


    目录

    一、Freemarker入门

    application.yml

    配置可使用的Freemarker界面

    index.ftl

     IndexController 

    二、Freemarker的基本语法

    整合

    IndexController 

    index.ftl

    注意

    common.ftl

    application.yml

    三、Freemarker综合案例

    准备好现项目所需ssm中的代码

    Clazz 

    application.yml

    ClazzMapper 

    ClazzMapper.xml

    ClazzBiz 

    PageBean 

     StringUtils 

     ClazzBizImpl 

    整合aop pageHelper插件

     PagerAspect 

     application.yml

    jsp->freemaker

    clzList.ftl

    clzEdit.ftl

    ClazzController 

    Springboot04Application 

     application.yml

     实现分页功能

    FreemarkerPageHelper 

     ClazzController 


    一、Freemarker入门

    官方学习网址:什么是 FreeMarker? - FreeMarker 中文官方参考手册

    新建一个模块 勾选以下的组件

     pom.xml中数据库的版本降低

     调整

    application.yml

    1. mybatis:
    2. mapper-locations: classpath:mappers/*xml
    3. type-aliases-package: com.cdl.springboot04.mybatis.entity
    4. server:
    5. port: 8080
    6. spring:
    7. application:
    8. name: springboot04
    9. datasource:
    10. driver-class-name: com.mysql.jdbc.Driver
    11. name: defaultDataSource
    12. password: 123456
    13. url: jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=UTF-8&useSSL=false
    14. username: root
    15. freemarker:
    16. cache: false
    17. charset: utf-8
    18. expose-request-attributes: true
    19. expose-session-attributes: true
    20. suffix: .ftl
    21. template-loader-path: classpath:/templates/
    22. # resources:
    23. # static-locations: classpath:/static/# 应用服务 WEB 访问端口
    24. mvc:
    25. static-path-pattern: classpath:/static/

    测试:

    配置可使用的Freemarker界面

     

     

     

     

     新建一个Freemarker的界面

    index.ftl

    1. HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    2. "http://www.w3.org/TR/html4/loose.dtd">
    3. <html>
    4. <head>
    5. <title>title>
    6. head>
    7. <body>
    8. 欢迎来到 Freemaker 首页
    9. body>
    10. html>

     IndexController 

    1. package com.cdl.springboot04.controller;
    2. import org.springframework.stereotype.Controller;
    3. import org.springframework.web.bind.annotation.RequestMapping;
    4. /**
    5. * @author cdl
    6. * @site www.cdl.com
    7. * @create 2022-11-01 18:33
    8. */
    9. @Controller
    10. public class IndexController {
    11. @RequestMapping("/")
    12. public String index(){
    13. System.out.println("come in ...");
    14. // suffix: .ftl
    15. // template-loader-path: classpath:/templates/
    16. // /templates/index.ftl
    17. return "index";
    18. }
    19. }

    在启动类运行

     访问成功

    二、Freemarker的基本语法

    提供默认值

    后台代码

    1. package com.cdl.springboot04.controller;
    2. import org.springframework.stereotype.Controller;
    3. import org.springframework.ui.Model;
    4. import org.springframework.web.bind.annotation.GetMapping;
    5. import org.springframework.web.bind.annotation.RequestMapping;
    6. import org.springframework.web.servlet.ModelAndView;
    7. import java.util.ArrayList;
    8. /**
    9. * @author cdl
    10. * @site www.cdl.com
    11. * @create 2022-11-01 18:33
    12. */
    13. @Controller
    14. public class IndexController {
    15. // @RequestMapping("/")
    16. // public ModelAndView index(){
    17. //第一种写法
    18. // ModelAndView mv = new ModelAndView();
    19. // mv.setViewName("index");
    20. // mv.addObject("uname","小陈");
    21. // System.out.println("come in ...");
    22. suffix: .ftl
    23. template-loader-path: classpath:/templates/
    24. /templates/index.ftl
    25. // return mv;
    26. // }
    27. @GetMapping("/")
    28. public String index(Model model) {
    29. System.out.println("come in............");
    30. model.addAttribute("uname", "小刘");
    31. model.addAttribute("sex", "girl");
    32. return "index";
    33. }
    34. }

    前端代码

    1. HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    2. "http://www.w3.org/TR/html4/loose.dtd">
    3. <html>
    4. <head>
    5. <title>title>
    6. head>
    7. <body>
    8. <#--欢迎来到 Freemaker 首页-->
    9. <h3>取值h3>
    10. <p>提供默认值p>
    11. <#--当接受的参数值不为空,这个问题是需要避免的-->
    12. <#--${uname}-->
    13. ${uname !}
    14. body>
    15. html>

    前端结果

    当后台没有传值的时候 

    ${uname ! "小王"} 结果是小王的默认值

    整合

    后台

    IndexController 

    1. package com.cdl.springboot04.controller;
    2. import com.cdl.springboot04.entity.User;
    3. import org.springframework.stereotype.Controller;
    4. import org.springframework.ui.Model;
    5. import org.springframework.web.bind.annotation.GetMapping;
    6. import java.util.ArrayList;
    7. import java.util.List;
    8. /**
    9. * @author cdl
    10. * @site www.cdl.com
    11. * @create 2022-11-01 18:33
    12. */
    13. @Controller
    14. public class IndexController {
    15. // @RequestMapping("/")
    16. // public ModelAndView index(){
    17. //第一种写法
    18. // ModelAndView mv = new ModelAndView();
    19. // mv.setViewName("index");
    20. // mv.addObject("uname","小陈");
    21. // System.out.println("come in ...");
    22. suffix: .ftl
    23. template-loader-path: classpath:/templates/
    24. /templates/index.ftl
    25. // return mv;
    26. // }
    27. @GetMapping("/")
    28. public String index(Model model) {
    29. System.out.println("come in............");
    30. model.addAttribute("uname", "小刘");
    31. model.addAttribute("sex", "girl");
    32. List lst = new ArrayList<>();
    33. lst.add(new User(1, "zs"));
    34. lst.add(new User(2, "ls"));
    35. lst.add(new User(3, "ww"));
    36. model.addAttribute("lst",lst);
    37. model.addAttribute("arr", new Integer[]{5, 6, 7, 8, 9});
    38. return "index";
    39. }
    40. }

    前端

    index.ftl

    1. HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    2. "http://www.w3.org/TR/html4/loose.dtd">
    3. <html>
    4. <head>
    5. <title>title>
    6. head>
    7. <body>
    8. <#--欢迎来到 Freemaker 首页-->
    9. <h3>取值h3>
    10. <p>提供默认值p>
    11. <#--当接受的参数值不为空,这个问题是需要避免的-->
    12. <#--${uname}-->
    13. ${uname ! "小王"}
    14. <h3>对null值先进行判断h3>
    15. <p>exists用在逻辑判断p>
    16. <#if uname?exists>
    17. ${uname}
    18. <br>
    19. <p>??是判断对象是否为空p>
    20. <#if uname??>
    21. ${uname}
    22. <br>
    23. <p>if_exists用来打印东西p>
    24. ${uname?if_exists}
    25. <br>
    26. <h3>2.条件h3>
    27. <#if sex=='nv'>
    28. <#elseif sex='nan'>
    29. <#else>
    30. 未知
    31. <br>
    32. <h3>3.循环h3>
    33. <p>1)取出数组中的元素p>
    34. <#list arr as a>
    35. ${a}==
    36. <br>
    37. <p>2)取出集合中的对象(注:访问的类要被public所修饰)p>
    38. <#list lst as item>
    39. ${item.id} : ${item.name} <br>
    40. <h3>4 include指令h3>
    41. <#include "/common.ftl" >
    42. <h3>5 局部变量(assign)/全局变量(global)h3>
    43. ${ctx} :${ctx2}
    44. body>
    45. html>

    注意

    common.ftl

    1. <#assign ctx>
    2. ${springMacroRequestContext.contextPath}
    3. <#global ctx2>
    4. ${springMacroRequestContext.contextPath}

    application.yml

    1. mybatis:
    2. mapper-locations: classpath:mappers/*xml
    3. type-aliases-package: com.cdl.springboot04.mybatis.entity
    4. server:
    5. port: 8080
    6. servlet:
    7. context-path: /springboot04
    8. spring:
    9. application:
    10. name: springboot04
    11. datasource:
    12. driver-class-name: com.mysql.jdbc.Driver
    13. name: defaultDataSource
    14. password: 123456
    15. url: jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=UTF-8&useSSL=false
    16. username: root
    17. freemarker:
    18. cache: false
    19. charset: utf-8
    20. expose-request-attributes: true
    21. expose-session-attributes: true
    22. suffix: .ftl
    23. template-loader-path: classpath:/templates/
    24. # resources:
    25. # static-locations: classpath:/static/# 应用服务 WEB 访问端口
    26. mvc:
    27. static-path-pattern: classpath:/static/

    三、Freemarker综合案例

    利用Freemarker完成基本的增删改查,参照之前ssm项目进行改造

    准备好现项目所需ssm中的代码

    新建一个model 的包 将之前ssm项目中的Clazz类复制进来 

    Clazz 

    1. package com.cdl.springboot04.model;
    2. import com.sun.istack.internal.NotNull;
    3. import lombok.AllArgsConstructor;
    4. import lombok.Data;
    5. import lombok.NoArgsConstructor;
    6. /**
    7. * NotNull:针对的是基本数据类型
    8. * @NotEmpty 作用于集合
    9. * @NotBlank 作用于字符串
    10. */
    11. @Data
    12. @NoArgsConstructor
    13. @AllArgsConstructor
    14. public class Clazz {
    15. protected Integer cid;
    16. protected String cname;
    17. protected String cteacher;
    18. protected String pic;
    19. }

    注意:扫描包的更改

    application.yml

    1. mybatis:
    2. mapper-locations: classpath:mappers/*xml
    3. type-aliases-package: com.cdl.springboot04.model
    4. server:
    5. port: 8080
    6. servlet:
    7. context-path: /springboot04
    8. spring:
    9. application:
    10. name: springboot04
    11. datasource:
    12. driver-class-name: com.mysql.jdbc.Driver
    13. name: defaultDataSource
    14. password: 123456
    15. url: jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=UTF-8&useSSL=false
    16. username: root
    17. freemarker:
    18. cache: false
    19. charset: utf-8
    20. expose-request-attributes: true
    21. expose-session-attributes: true
    22. suffix: .ftl
    23. template-loader-path: classpath:/templates/
    24. # resources:
    25. # static-locations: classpath:/static/# 应用服务 WEB 访问端口
    26. mvc:
    27. static-path-pattern: classpath:/static/

    新建一个mapper的包 将对应的mapper复制进去

    ClazzMapper 

    1. package com.cdl.springboot04.mapper;
    2. import com.cdl.springboot04.model.Clazz;
    3. import org.springframework.stereotype.Repository;
    4. import java.util.List;
    5. import java.util.Map;
    6. @Repository
    7. public interface ClazzMapper {
    8. int deleteByPrimaryKey(Integer cid);
    9. int insert(Clazz record);
    10. int insertSelective(Clazz record);
    11. Clazz selectByPrimaryKey(Integer cid);
    12. List listPager(Clazz clazz);
    13. List listMapPager(Clazz clazz);
    14. int updateByPrimaryKeySelective(Clazz record);
    15. int updateByPrimaryKey(Clazz record);
    16. }

    将mapper.xml的文件放入resources下的mapper中

    ClazzMapper.xml

    1. "1.0" encoding="UTF-8" ?>
    2. mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    3. <mapper namespace="com.cdl.springboot04.mapper.ClazzMapper" >
    4. <resultMap id="BaseResultMap" type="com.cdl.springboot04.model.Clazz" >
    5. <constructor >
    6. <idArg column="cid" jdbcType="INTEGER" javaType="java.lang.Integer" />
    7. <arg column="cname" jdbcType="VARCHAR" javaType="java.lang.String" />
    8. <arg column="cteacher" jdbcType="VARCHAR" javaType="java.lang.String" />
    9. <arg column="pic" jdbcType="VARCHAR" javaType="java.lang.String" />
    10. constructor>
    11. resultMap>
    12. <sql id="Base_Column_List" >
    13. cid, cname, cteacher, pic
    14. sql>
    15. <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    16. select
    17. <include refid="Base_Column_List" />
    18. from t_struts_class
    19. where cid = #{cid,jdbcType=INTEGER}
    20. select>
    21. <select id="listMapPager" resultType="java.util.Map" parameterType="Clazz" >
    22. select
    23. <include refid="Base_Column_List" />
    24. from t_struts_class
    25. <where>
    26. <if test="cname != null and cname != ''">
    27. and cname like CONCAT('%',#{cname},'%')
    28. if>
    29. <if test="cid != null and cid != ''">
    30. and cid = #{cid}
    31. if>
    32. where>
    33. select>
    34. <select id="listPager" resultType="com.cdl.springboot04.model.Clazz" parameterType="Clazz" >
    35. select
    36. <include refid="Base_Column_List" />
    37. from t_struts_class
    38. <where>
    39. <if test="cname != null and cname != ''">
    40. and cname like CONCAT('%',#{cname},'%')
    41. if>
    42. <if test="cid != null and cid != ''">
    43. and cid = #{cid}
    44. if>
    45. where>
    46. select>
    47. <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
    48. delete from t_struts_class
    49. where cid = #{cid,jdbcType=INTEGER}
    50. delete>
    51. <insert id="insert" parameterType="Clazz" >
    52. insert into t_struts_class (cid, cname, cteacher,
    53. pic)
    54. values (#{cid,jdbcType=INTEGER}, #{cname,jdbcType=VARCHAR}, #{cteacher,jdbcType=VARCHAR},
    55. #{pic,jdbcType=VARCHAR})
    56. insert>
    57. <insert id="insertSelective" parameterType="Clazz" >
    58. insert into t_struts_class
    59. <trim prefix="(" suffix=")" suffixOverrides="," >
    60. <if test="cid != null" >
    61. cid,
    62. if>
    63. <if test="cname != null" >
    64. cname,
    65. if>
    66. <if test="cteacher != null" >
    67. cteacher,
    68. if>
    69. <if test="pic != null" >
    70. pic,
    71. if>
    72. trim>
    73. <trim prefix="values (" suffix=")" suffixOverrides="," >
    74. <if test="cid != null" >
    75. #{cid,jdbcType=INTEGER},
    76. if>
    77. <if test="cname != null" >
    78. #{cname,jdbcType=VARCHAR},
    79. if>
    80. <if test="cteacher != null" >
    81. #{cteacher,jdbcType=VARCHAR},
    82. if>
    83. <if test="pic != null" >
    84. #{pic,jdbcType=VARCHAR},
    85. if>
    86. trim>
    87. insert>
    88. <update id="updateByPrimaryKeySelective" parameterType="Clazz" >
    89. update t_struts_class
    90. <set >
    91. <if test="cname != null" >
    92. cname = #{cname,jdbcType=VARCHAR},
    93. if>
    94. <if test="cteacher != null" >
    95. cteacher = #{cteacher,jdbcType=VARCHAR},
    96. if>
    97. <if test="pic != null" >
    98. pic = #{pic,jdbcType=VARCHAR},
    99. if>
    100. set>
    101. where cid = #{cid,jdbcType=INTEGER}
    102. update>
    103. <update id="updateByPrimaryKey" parameterType="Clazz" >
    104. update t_struts_class
    105. set cname = #{cname,jdbcType=VARCHAR},
    106. cteacher = #{cteacher,jdbcType=VARCHAR},
    107. pic = #{pic,jdbcType=VARCHAR}
    108. where cid = #{cid,jdbcType=INTEGER}
    109. update>
    110. mapper>

    新建一个biz的包 放接口

    ClazzBiz 

    1. package com.cdl.springboot04.biz;
    2. import com.cdl.springboot04.model.Clazz;
    3. import com.cdl.springboot04.util.PageBean;
    4. import org.springframework.cache.annotation.CacheEvict;
    5. import org.springframework.cache.annotation.CachePut;
    6. import java.util.List;
    7. import java.util.Map;
    8. public interface ClazzBiz {
    9. int deleteByPrimaryKey(Integer cid);
    10. int insert(Clazz record);
    11. int insertSelective(Clazz record);
    12. Clazz selectByPrimaryKey(Integer cid);
    13. int updateByPrimaryKeySelective(Clazz record);
    14. int updateByPrimaryKey(Clazz record);
    15. List listPager(Clazz clazz, PageBean pageBean);
    16. List listMapPager(Clazz clazz, PageBean pageBean);
    17. }

     将对应的工具类拿过来

    PageBean 

    1. package com.cdl.springboot04.util;
    2. import java.util.HashMap;
    3. import java.util.Map;
    4. import javax.servlet.http.HttpServletRequest;
    5. /**
    6. * 分页工具类
    7. *
    8. */
    9. public class PageBean {
    10. private int page = 1;// 页码
    11. private int rows = 10;// 页大小
    12. private int total = 0;// 总记录数
    13. private boolean pagination = true;// 是否分页
    14. private String url; //保存上一次请求的URL
    15. private Map paramMap = new HashMap<>();// 保存上一次请求的参数
    16. /**
    17. * 初始化pagebean的,保存上一次请求的重要参数
    18. * @param req
    19. */
    20. public void setRequest(HttpServletRequest req) {
    21. // 1.1 需要保存上一次请求的URL
    22. this.setUrl(req.getRequestURL().toString());
    23. // 1.2 需要保存上一次请求的参数 bname、price
    24. this.setParamMap(req.getParameterMap());
    25. // 1.3 需要保存上一次请求的分页设置 pagination
    26. this.setPagination(req.getParameter("pagination"));
    27. // 1.4 需要保存上一次请求的展示条目数
    28. this.setRows(req.getParameter("rows"));
    29. // 1.5 初始化请求的页码 page
    30. this.setPage(req.getParameter("page"));
    31. }
    32. public void setPage(String page) {
    33. if(StringUtils.isNotBlank(page))
    34. this.setPage(Integer.valueOf(page));
    35. }
    36. public void setRows(String rows) {
    37. if(StringUtils.isNotBlank(rows))
    38. this.setRows(Integer.valueOf(rows));
    39. }
    40. public void setPagination(String pagination) {
    41. // 只有在前台jsp填写了pagination=false,才代表不分页
    42. if(StringUtils.isNotBlank(pagination))
    43. this.setPagination(!"false".equals(pagination));
    44. }
    45. public String getUrl() {
    46. return url;
    47. }
    48. public void setUrl(String url) {
    49. this.url = url;
    50. }
    51. public Map getParamMap() {
    52. return paramMap;
    53. }
    54. public void setParamMap(Map paramMap) {
    55. this.paramMap = paramMap;
    56. }
    57. public PageBean() {
    58. super();
    59. }
    60. public int getPage() {
    61. return page;
    62. }
    63. public void setPage(int page) {
    64. this.page = page;
    65. }
    66. public int getRows() {
    67. return rows;
    68. }
    69. public void setRows(int rows) {
    70. this.rows = rows;
    71. }
    72. public int getTotal() {
    73. return total;
    74. }
    75. public void setTotal(int total) {
    76. this.total = total;
    77. }
    78. public void setTotal(String total) {
    79. this.total = Integer.parseInt(total);
    80. }
    81. public boolean isPagination() {
    82. return pagination;
    83. }
    84. public void setPagination(boolean pagination) {
    85. this.pagination = pagination;
    86. }
    87. /**
    88. * 获得起始记录的下标
    89. *
    90. * @return
    91. */
    92. public int getStartIndex() {
    93. return (this.page - 1) * this.rows;
    94. }
    95. /**
    96. * 最大页
    97. * @return
    98. */
    99. public int maxPage() {
    100. // total % rows == 0 ? total / rows : total / rows +1
    101. return this.total % this.rows == 0 ? this.total / this.rows : this.total / this.rows + 1;
    102. }
    103. /**
    104. * 下一页
    105. * @return
    106. */
    107. public int nextPage() {
    108. // 如果当前页小于最大页,那就下一页为当前页+1;如果不小于,说明当前页就是最大页,那就无需+1
    109. return this.page < this.maxPage() ? this.page + 1 : this.page;
    110. }
    111. /**
    112. * 上一页
    113. * @return
    114. */
    115. public int previousPage() {
    116. return this.page > 1 ? this.page - 1 : this.page;
    117. }
    118. @Override
    119. public String toString() {
    120. return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination + "]";
    121. }
    122. }

     StringUtils 

    1. package com.cdl.springboot04.util;
    2. public class StringUtils {
    3. // 私有的构造方法,保护此类不能在外部实例化
    4. private StringUtils() {
    5. }
    6. /**
    7. * 如果字符串等于null或去空格后等于"",则返回true,否则返回false
    8. *
    9. * @param s
    10. * @return
    11. */
    12. public static boolean isBlank(String s) {
    13. boolean b = false;
    14. if (null == s || s.trim().equals("")) {
    15. b = true;
    16. }
    17. return b;
    18. }
    19. /**
    20. * 如果字符串不等于null或去空格后不等于"",则返回true,否则返回false
    21. *
    22. * @param s
    23. * @return
    24. */
    25. public static boolean isNotBlank(String s) {
    26. return !isBlank(s);
    27. }
    28. }

    对应接口的实现类 

     ClazzBizImpl 

    1. package com.cdl.springboot04.biz.impl;
    2. import com.cdl.springboot04.biz.ClazzBiz;
    3. import com.cdl.springboot04.mapper.ClazzMapper;
    4. import com.cdl.springboot04.model.Clazz;
    5. import com.cdl.springboot04.util.PageBean;
    6. import org.springframework.beans.factory.annotation.Autowired;
    7. import org.springframework.stereotype.Service;
    8. import java.util.List;
    9. import java.util.Map;
    10. /**
    11. * @author小李飞刀
    12. * @site www.javaxl.com
    13. * @company xxx公司
    14. * @create  2022-08-17 15:13
    15. */
    16. @Service
    17. public class ClazzBizImpl implements ClazzBiz {
    18. @Autowired
    19. private ClazzMapper clazzMapper;
    20. @Override
    21. public int deleteByPrimaryKey(Integer cid) {
    22. // System.out.println("不做任何操作...");
    23. return clazzMapper.deleteByPrimaryKey(cid);
    24. // return 0;
    25. }
    26. @Override
    27. public int insert(Clazz record) {
    28. return clazzMapper.insert(record);
    29. }
    30. @Override
    31. public int insertSelective(Clazz record) {
    32. return clazzMapper.insertSelective(record);
    33. }
    34. @Override
    35. public Clazz selectByPrimaryKey(Integer cid) {
    36. return clazzMapper.selectByPrimaryKey(cid);
    37. }
    38. @Override
    39. public int updateByPrimaryKeySelective(Clazz record) {
    40. return clazzMapper.updateByPrimaryKeySelective(record);
    41. }
    42. @Override
    43. public int updateByPrimaryKey(Clazz record) {
    44. return clazzMapper.updateByPrimaryKey(record);
    45. }
    46. @Override
    47. public List listPager(Clazz clazz, PageBean pageBean) {
    48. return clazzMapper.listPager(clazz);
    49. }
    50. @Override
    51. public List listMapPager(Clazz clazz, PageBean pageBean) {
    52. if(true)
    53. throw new RuntimeException("查询班级信息异常,异常存在于ClazzBizImpl.list。。。。");
    54. return clazzMapper.listMapPager(clazz);
    55. }
    56. }

    整合aop pageHelper插件

    导入所需要的pom依赖

    1. <dependency>
    2. <groupId>org.springframeworkgroupId>
    3. <artifactId>spring-aspectsartifactId>
    4. <version>5.0.2.RELEASEversion>
    5. dependency>
    6. <dependency>
    7. <groupId>com.github.pagehelpergroupId>
    8. <artifactId>pagehelper-spring-boot-starterartifactId>
    9. <version>1.2.3version>
    10. dependency>

     PagerAspect 

    1. package com.cdl.springboot04.aspect;
    2. import com.cdl.springboot04.util.PageBean;
    3. import com.github.pagehelper.PageHelper;
    4. import com.github.pagehelper.PageInfo;
    5. import org.aspectj.lang.ProceedingJoinPoint;
    6. import org.aspectj.lang.annotation.Around;
    7. import org.aspectj.lang.annotation.Aspect;
    8. import org.springframework.stereotype.Component;
    9. import java.util.List;
    10. /**
    11. * @author小李飞刀
    12. * @site www.javaxl.com
    13. * @company xxx公司
    14. * @create  2022-08-12 16:32
    15. */
    16. @Component
    17. @Aspect
    18. public class PagerAspect {
    19. /**
    20. * *:返回值类型
    21. * *..:无限包
    22. * *Service:以Service结尾接口名
    23. * *Pager:以Pager方法
    24. * 只要同时匹配上诉四个条件,就会被列为目标对象
    25. * 上述配置要生效,代理注解不能少
    26. * @param args
    27. * @return
    28. * @throws Throwable
    29. */
    30. @Around("execution(* *..*Biz.*Pager(..))")
    31. public Object invoke(ProceedingJoinPoint args) throws Throwable {
    32. Object[] params = args.getArgs();
    33. PageBean pageBean = null;
    34. for (Object param : params) {
    35. if(param instanceof PageBean){
    36. pageBean = (PageBean)param;
    37. break;
    38. }
    39. }
    40. if(pageBean != null && pageBean.isPagination())
    41. PageHelper.startPage(pageBean.getPage(),pageBean.getRows());
    42. // 执行目标方法
    43. Object list = args.proceed(params);
    44. if(null != pageBean && pageBean.isPagination()){
    45. PageInfo pageInfo = new PageInfo((List) list);
    46. pageBean.setTotal(pageInfo.getTotal()+"");
    47. }
    48. return list;
    49. }
    50. }

     application.yml中添加该配置

    pagehelper:
      reasonable: true
      supportMethodsArguments: true
      page-size-zero: true
      helper-dialect: mysql

     application.yml

    1. mybatis:
    2. mapper-locations: classpath:mappers/*xml
    3. type-aliases-package: com.cdl.springboot04.model
    4. server:
    5. port: 8080
    6. servlet:
    7. context-path: /springboot04
    8. spring:
    9. application:
    10. name: springboot04
    11. datasource:
    12. driver-class-name: com.mysql.jdbc.Driver
    13. name: defaultDataSource
    14. password: 123456
    15. url: jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=UTF-8&useSSL=false
    16. username: root
    17. freemarker:
    18. cache: false
    19. charset: utf-8
    20. expose-request-attributes: true
    21. expose-session-attributes: true
    22. suffix: .ftl
    23. template-loader-path: classpath:/templates/
    24. # resources:
    25. # static-locations: classpath:/static/# 应用服务 WEB 访问端口
    26. mvc:
    27. static-path-pattern: classpath:/static/
    28. pagehelper:
    29. reasonable: true
    30. supportMethodsArguments: true
    31. page-size-zero: true
    32. helper-dialect: mysql

     此时就具备了分页的功能

    jsp->freemaker

     将对应的clzList.jsp和clzEdit.jsp复制放入clz里面 参考得出clzList.ftl和clzEdit.ftl

    clzList.jsp

    1. <%@ page language="java" contentType="text/html; charset=UTF-8"
    2. pageEncoding="UTF-8"%>
    3. <%@ taglib uri="http://jsp.veryedu.cn" prefix="z"%>
    4. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    5. html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    6. <html>
    7. <head>
    8. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    9. <link
    10. href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"
    11. rel="stylesheet">
    12. <script
    13. src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js">script>
    14. <title>博客列表title>
    15. <style type="text/css">
    16. .page-item input {
    17. padding: 0;
    18. width: 40px;
    19. height: 100%;
    20. text-align: center;
    21. margin: 0 6px;
    22. }
    23. .page-item input, .page-item b {
    24. line-height: 38px;
    25. float: left;
    26. font-weight: 400;
    27. }
    28. .page-item.go-input {
    29. margin: 0 10px;
    30. }
    31. style>
    32. head>
    33. <body>
    34. <form class="form-inline"
    35. action="${pageContext.request.contextPath }/clz/list" method="post">
    36. <div class="form-group mb-2">
    37. <input type="text" class="form-control-plaintext" name="cname"
    38. placeholder="请输入班级名称">
    39. div>
    40. <button type="submit" class="btn btn-primary mb-2">查询button>
    41. <a class="btn btn-primary mb-2" href="${pageContext.request.contextPath }/clz/toEdit">新增a>
    42. form>
    43. <table class="table table-striped bg-success">
    44. <thead>
    45. <tr>
    46. <th scope="col">IDth>
    47. <th scope="col">班级名称th>
    48. <th scope="col">指导老师th>
    49. <th scope="col">班级相册th>
    50. <th scope="col">操作th>
    51. tr>
    52. thead>
    53. <tbody>
    54. <c:forEach var="b" items="${lst }">
    55. <tr>
    56. <td>${b.cid }td>
    57. <td>${b.cname }td>
    58. <td>${b.cteacher }td>
    59. <td>
    60. <img src="${pageContext.request.contextPath }${b.pic }" style="height: 100px;width: 100px;" />
    61. td>
    62. <td>
    63. <a href="${pageContext.request.contextPath }/clz/toEdit?cid=${b.cid}">修改a>
    64. <a href="${pageContext.request.contextPath }/clz/del?cid=${b.cid}">删除a>
    65. <a href="${pageContext.request.contextPath }/clzUpload.jsp?cid=${b.cid}">上传图片a>
    66. <a href="${pageContext.request.contextPath }/clz/download?cid=${b.cid}">下载图片a>
    67. td>
    68. tr>
    69. c:forEach>
    70. tbody>
    71. table>
    72. <z:page pageBean="${pageBean }">z:page>
    73. body>
    74. html>

    clzEdit.jsp

    1. <%@ page language="java" contentType="text/html; charset=UTF-8"
    2. pageEncoding="UTF-8"%>
    3. html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    4. <html>
    5. <head>
    6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    7. <title>博客的编辑界面title>
    8. head>
    9. <body>
    10. <%--<form action="${pageContext.request.contextPath }/clz/${empty b ? 'add' : 'edit'}" method="post">--%>
    11. <form action="${pageContext.request.contextPath }/clz/${empty b ? 'valiAdd' : 'edit'}" method="post">
    12. cid:<input type="text" name="cid" value="${b.cid }"><span style="color: red;">${msg.cid}span><br>
    13. cname:<input type="text" name="cname" value="${b.cname }"><span style="color: red;">${msg.cname}span><br>
    14. cteacher:<input type="text" name="cteacher" value="${b.cteacher }"><span style="color: red;">${msg.cteacher}span><br>
    15. <input type="submit">
    16. form>
    17. body>
    18. html>

    clzList.ftl

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    5. <link
    6. href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"
    7. rel="stylesheet">
    8. <script
    9. src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js">script>
    10. <title>班级列表title>
    11. <style type="text/css">
    12. .page-item input {
    13. padding: 0;
    14. width: 40px;
    15. height: 100%;
    16. text-align: center;
    17. margin: 0 6px;
    18. }
    19. .page-item input, .page-item b {
    20. line-height: 38px;
    21. float: left;
    22. font-weight: 400;
    23. }
    24. .page-item.go-input {
    25. margin: 0 10px;
    26. }
    27. style>
    28. head>
    29. <body>
    30. <#include "/common.ftl">
    31. <#--查询的条件框-->
    32. <form class="form-inline"
    33. action="${ctx }/clz/list" method="post">
    34. <div class="form-group mb-2">
    35. <input type="text" class="form-control-plaintext" name="cname"
    36. placeholder="请输入班级名称">
    37. div>
    38. <button type="submit" class="btn btn-primary mb-2">查询button>
    39. <a class="btn btn-primary mb-2" href="${ctx }/clz/toEdit">新增a>
    40. form>
    41. <#--数据展示表格-->
    42. <table class="table table-striped bg-success">
    43. <thead>
    44. <tr>
    45. <th scope="col">IDth>
    46. <th scope="col">班级名称th>
    47. <th scope="col">指导老师th>
    48. <th scope="col">操作th>
    49. tr>
    50. thead>
    51. <tbody>
    52. <#list lst as b>
    53. <tr>
    54. <td>${b.cid !}td>
    55. <td>${b.cname !}td>
    56. <td>${b.cteacher !}td>
    57. <td>
    58. <a href="${ctx }/clz/toEdit?cid=${b.cid}">修改a>
    59. <a href="${ctx }/clz/del?cid=${b.cid}">删除a>
    60. td>
    61. tr>
    62. tbody>
    63. table>
    64. <#--jsp是借助助手类,而这里是Freemarker,没有jsp相关依赖-->
    65. ${pagestr !}
    66. body>
    67. html>

    clzEdit.ftl

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    5. <title>班级的编辑界面title>
    6. head>
    7. <body>
    8. <#include "/common.ftl">
    9. <#if b??>
    10. <#--修改-->
    11. <form action="${ctx }/clz/edit" method="post">
    12. cid:<input type="text" name="cid" value="${b.cid !}"><br>
    13. cname:<input type="text" name="cname" value="${b.cname !}"><br>
    14. cteacher:<input type="text" name="cteacher" value="${b.cteacher !}"><br>
    15. <input type="submit">
    16. form>
    17. <#else>
    18. <#--新增-->
    19. <form action="${ctx }/clz/add" method="post">
    20. cid:<input type="text" name="cid" value=""><br>
    21. cname:<input type="text" name="cname" value=""><br>
    22. cteacher:<input type="text" name="cteacher" value=""><br>
    23. <input type="submit">
    24. form>
    25. body>
    26. html>

    因为新建了clz的包,所以业务逻辑层要修改

    ClazzController 

    1. package com.cdl.springboot04.controller;
    2. import com.cdl.springboot04.biz.ClazzBiz;
    3. import com.cdl.springboot04.model.Clazz;
    4. import com.cdl.springboot04.util.PageBean;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.stereotype.Controller;
    7. import org.springframework.validation.BindingResult;
    8. import org.springframework.validation.FieldError;
    9. import org.springframework.web.bind.annotation.RequestMapping;
    10. import javax.servlet.http.HttpServletRequest;
    11. import java.util.HashMap;
    12. import java.util.List;
    13. import java.util.Map;
    14. /**
    15. * @author小李飞刀
    16. * @site www.javaxl.com
    17. * @company xxx公司
    18. * @create  2022-08-17 15:23
    19. */
    20. @Controller
    21. @RequestMapping("/clz")
    22. public class ClazzController {
    23. @Autowired
    24. private ClazzBiz clazzBiz;
    25. // list->clzList
    26. // toList->重定向list->"redirect:/clz/list"
    27. // toEdit->跳转到编辑界面->clzEdit
    28. // Clazz : 以前是通过模型驱动接口封装,现在是直接在方法中接受参数即可
    29. @RequestMapping("/list")
    30. public String list(Clazz clazz, HttpServletRequest request){
    31. System.out.println("我添加了 新的代码,终于不重启了....");
    32. PageBean pageBean = new PageBean();
    33. pageBean.setRequest(request);
    34. List lst = this.clazzBiz.listPager(clazz, pageBean);
    35. request.setAttribute("lst",lst);
    36. request.setAttribute("pageBean",pageBean);
    37. return "clz/clzList";
    38. }
    39. @RequestMapping("/toEdit")
    40. public String toEdit(Clazz clazz, HttpServletRequest request){
    41. Integer cid = clazz.getCid();
    42. // 传递的id代表了修改,没传代表新增
    43. if(cid != null){
    44. List lst = this.clazzBiz.listPager(clazz, null);
    45. request.setAttribute("b",lst.get(0));
    46. }
    47. return "clz/clzEdit";
    48. }
    49. @RequestMapping("/add")
    50. public String add(Clazz clazz){
    51. this.clazzBiz.insertSelective(clazz);
    52. return "redirect:/clz/list";
    53. }
    54. @RequestMapping("/edit")
    55. public String edit(Clazz clazz){
    56. this.clazzBiz.updateByPrimaryKeySelective(clazz);
    57. return "redirect:/clz/list";
    58. }
    59. @RequestMapping("/del")
    60. public String del(Clazz clazz){
    61. this.clazzBiz.deleteByPrimaryKey(clazz.getCid());
    62. return "redirect:/clz/list";
    63. }
    64. }

    测试一波:

    运行后台启动报错

     因为启动类没有开启扫描

    Springboot04Application 

    1. package com.cdl.springboot04;
    2. import org.mybatis.spring.annotation.MapperScan;
    3. import org.springframework.boot.SpringApplication;
    4. import org.springframework.boot.autoconfigure.SpringBootApplication;
    5. @MapperScan("com.cdl.springboot04.mapper")//扫描
    6. @EnableTransactionManagement//开启事务
    7. @SpringBootApplication
    8. public class Springboot04Application {
    9. public static void main(String[] args) {
    10. SpringApplication.run(Springboot04Application.class, args);
    11. }
    12. }

    后台启动成功

     前端页面访问成功

     模糊查询

     添加进application.yml

     

    logging:
        level:
            com.cdl.springboot04: debug

     application.yml

    1. mybatis:
    2. mapper-locations: classpath:mappers/*xml
    3. type-aliases-package: com.cdl.springboot04.model
    4. server:
    5. port: 8080
    6. servlet:
    7. context-path: /springboot04
    8. spring:
    9. application:
    10. name: springboot04
    11. datasource:
    12. driver-class-name: com.mysql.jdbc.Driver
    13. name: defaultDataSource
    14. password: 123456
    15. url: jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=UTF-8&useSSL=false
    16. username: root
    17. freemarker:
    18. cache: false
    19. charset: utf-8
    20. expose-request-attributes: true
    21. expose-session-attributes: true
    22. suffix: .ftl
    23. template-loader-path: classpath:/templates/
    24. # resources:
    25. # static-locations: classpath:/static/# 应用服务 WEB 访问端口
    26. mvc:
    27. static-path-pattern: classpath:/static/
    28. pagehelper:
    29. reasonable: true
    30. supportMethodsArguments: true
    31. page-size-zero: true
    32. helper-dialect: mysql
    33. logging:
    34. level:
    35. com.cdl.springboot04: debug

    删除

     删除成功

     新增

     新增成功

     修改

     修改成功

     实现分页功能

    新建一个分页的工具类

    FreemarkerPageHelper 

    1. package com.cdl.springboot04.util;
    2. import java.util.Map;
    3. import java.util.Map.Entry;
    4. import java.util.Set;
    5. /**
    6. * @author cdl
    7. * @site www.cdl.com
    8. * @create 2022-11-02 1:25
    9. */
    10. public class FreemarkerPageHelper {
    11. public static String toHTML(PageBean pageBean) {
    12. StringBuffer sb = new StringBuffer();
    13. // 隐藏的form表单---这个就是上一次请求下次重新发的奥义所在
    14. // 上一次请求的URL
    15. sb.append("
      ");
    16. sb.append(" ");
    17. // 上一次请求的参数
    18. Map paramMap = pageBean.getParamMap();
    19. if(paramMap != null && paramMap.size() > 0) {
    20. Set> entrySet = paramMap.entrySet();
    21. for (Entry entry : entrySet) {
    22. // 参数名
    23. String key = entry.getKey();
    24. // 参数值
    25. for (String value : entry.getValue()) {
    26. // 上一次请求的参数,再一次组装成了新的Form表单
    27. // 注意:page参数每次都会提交,我们需要避免
    28. if(!"page".equals(key)) {
    29. sb.append(" ");
    30. }
    31. }
    32. }
    33. }
    34. sb.append("");
    35. // 分页条
    36. sb.append("
        ");
    37. sb.append("
    38. );
  • ");
  • sb.append("
  • );
  • ");// less than 小于号
  • // sb.append("
  • 1
  • ");
  • // sb.append("
  • 2
  • ");
  • sb.append("
  • "+pageBean.getPage()+"
  • ");
  • sb.append("
  • >
  • ");
  • sb.append("
  • 尾页
  • ");
  • sb.append("
  • 到第);
  • sb.append(" type='text' id='skipPage' name='' />
  • ");
  • sb.append("
  • );
  • ");
  • sb.append("
  • 共"+pageBean.getTotal()+"条
  • ");
  • sb.append("");
  • // 分页执行的JS代码
  • sb.append("");
  • return sb.toString();
  • }
  • }
  •  ClazzController 

    添加使用分页工具类的代码

    1. package com.cdl.springboot04.controller;
    2. import com.cdl.springboot04.biz.ClazzBiz;
    3. import com.cdl.springboot04.model.Clazz;
    4. import com.cdl.springboot04.util.FreemarkerPageHelper;
    5. import com.cdl.springboot04.util.PageBean;
    6. import org.springframework.beans.factory.annotation.Autowired;
    7. import org.springframework.stereotype.Controller;
    8. import org.springframework.validation.BindingResult;
    9. import org.springframework.validation.FieldError;
    10. import org.springframework.web.bind.annotation.RequestMapping;
    11. import javax.servlet.http.HttpServletRequest;
    12. import java.util.HashMap;
    13. import java.util.List;
    14. import java.util.Map;
    15. /**
    16. * @author小李飞刀
    17. * @site www.javaxl.com
    18. * @company xxx公司
    19. * @create  2022-08-17 15:23
    20. */
    21. @Controller
    22. @RequestMapping("/clz")
    23. public class ClazzController {
    24. @Autowired
    25. private ClazzBiz clazzBiz;
    26. // list->clzList
    27. // toList->重定向list->"redirect:/clz/list"
    28. // toEdit->跳转到编辑界面->clzEdit
    29. // Clazz : 以前是通过模型驱动接口封装,现在是直接在方法中接受参数即可
    30. @RequestMapping("/list")
    31. public String list(Clazz clazz, HttpServletRequest request){
    32. System.out.println("我添加了 新的代码,终于不重启了....");
    33. PageBean pageBean = new PageBean();
    34. pageBean.setRequest(request);
    35. List lst = this.clazzBiz.listPager(clazz, pageBean);
    36. request.setAttribute("lst",lst);
    37. request.setAttribute("pageBean",pageBean);
    38. //分页
    39. request.setAttribute("pagestr", FreemarkerPageHelper.toHTML(pageBean));
    40. return "clz/clzList";
    41. }
    42. @RequestMapping("/toEdit")
    43. public String toEdit(Clazz clazz, HttpServletRequest request){
    44. Integer cid = clazz.getCid();
    45. // 传递的id代表了修改,没传代表新增
    46. if(cid != null){
    47. List lst = this.clazzBiz.listPager(clazz, null);
    48. request.setAttribute("b",lst.get(0));
    49. }
    50. return "clz/clzEdit";
    51. }
    52. @RequestMapping("/add")
    53. public String add(Clazz clazz){
    54. this.clazzBiz.insertSelective(clazz);
    55. return "redirect:/clz/list";
    56. }
    57. @RequestMapping("/edit")
    58. public String edit(Clazz clazz){
    59. this.clazzBiz.updateByPrimaryKeySelective(clazz);
    60. return "redirect:/clz/list";
    61. }
    62. @RequestMapping("/del")
    63. public String del(Clazz clazz){
    64. this.clazzBiz.deleteByPrimaryKey(clazz.getCid());
    65. return "redirect:/clz/list";
    66. }
    67. }

    成功

     

     注意:

     

  • 相关阅读:
    YAML 快速上手
    PHP:BinarySearchTree二叉搜索树(附完整源码)
    Android LiveData 介绍
    入门级swagger2和knife4j的详细使用
    【怎么理解回流与重绘?以及触发场景】
    网络编程:发送0字节数据的效果
    java题库——认证考试题1
    常用正在表达式
    代码随想录 --- day21 --- 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数 、236. 二叉树的最近公共祖先
    本月本周github热度霸榜项目——jeecgboot
  • 原文地址:https://blog.csdn.net/weixin_62735525/article/details/127638213