第1章 初始Spring Boot【仿牛客网社区论坛项目】
- 前言
- 推荐
- 项目总结
- 第1章初识Spring Boot,开发社区首页
- 1.课程介绍
- 2.搭建开发环境
- 3.Spring入门
- 体验IOC容器
- 体验Bean的生命周期
- 体验配置类
- 体验依赖注入
- 体验三层架构
- 4.SpringMVC入门
- 配置
- 体验响应数据
- 体验响应Get请求
- 体验响应Post请求
- 体验响应HTML数据
- 体验响应JSON数据
- 5MyBatis入门
- 配置
- User
- UserMapper
- user-mapper.xml
- 测试:MapperTest
- 设置日志级别
- 6开发社区首页
- DiscussPost
- DiscussPostMapper
- discusspost-mapper.xml
- 测试Dao层
- DiscussPostService
- UserService
- 前端资源准备
- HomeController
- index.html
- Page
- 7项目调试技巧
- 测试:日志功能
- 8版本控制
- 最后
前言
2023-4-30 20:42:51
以下内容源自【Java面试项目】
仅供学习交流使用
推荐
仿牛客网项目【面试】
项目总结
第1章初识Spring Boot,开发社区首页
1.课程介绍
2.搭建开发环境
创建项目,完成搭建
添加依赖
- aspectj aop包
- Spring Web web开发
- Thymeleaf 模板引擎
- Spring Boot DevTools 开发者工具
- 其他:使用时添加
配置application.properties
#ServerProperties
#端口配置
server.port=8080
#路径配置
server.servlet.context-path=/community
创建一个AlphaController
编写sayHello()
@Controller
@RequestMapping("/alpha")
public class AlphaController {@RequestMapping("/hello")@ResponseBody//返回字符串public String sayHello(){return "Hello Spring Boot.";}
}
访问:http://localhost:8080/community/alpha/hello
3.Spring入门
修改测试代码
体验IOC容器
ApplicationContext,管理Bean
package com.jsss.community;@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
class CommunityApplicationTests implements ApplicationContextAware {private ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext=applicationContext;}@Testpublic void testApplicationContext(){System.out.println(applicationContext);}
}
创建一个Bean
AlphaDAO
package com.jsss.community.dao;public interface AlphaDao {String select();}
两个实现类
AlphaDaoHibernateImpl
package com.jsss.community.dao;import org.springframework.stereotype.Repository;@Repository("alphaDaoHibernate")//容器管理 指定Bean名字
public class AlphaDaoHibernateImpl implements AlphaDao{@Overridepublic String select() {return "Hibernate";}
}
AlphaDaoMybatisImpl
package com.jsss.community.dao;import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Repository;@Repository
@Primary//优先装配
public class AlphaDaoMybatisImpl implements AlphaDao{@Overridepublic String select() {return "Mybatis";}
}
测试:testApplicationContext()
package com.jsss.community;import com.jsss.community.dao.AlphaDao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.BeansException;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.test.context.ContextConfiguration;@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
class CommunityApplicationTests implements ApplicationContextAware {//SpringBoot会进行自动配置private ApplicationContext applicationContext;//配置方法@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext=applicationContext;}//测试容器@Testpublic void testApplicationContext(){System.out.println(applicationContext);AlphaDao alphaDao=applicationContext.getBean(AlphaDao.class);System.out.println(alphaDao.select());//MybatisalphaDao= (applicationContext.getBean("alphaDaoHibernate",AlphaDao.class));System.out.println(alphaDao.select());//Hibernate}
}
体验Bean的生命周期
创建AlphaService
package com.jsss.community.service;import org.springframework.stereotype.Service;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;@Service//容器管理
//作用域 单例 多态
//@Scope("singleton")
//@Scope("prototype")
public class AlphaService {@PostConstruct//IOC容器管理Bean生命周期:初始化public void init(){System.out.println("初始化AlphaService");}@PreDestroy//IOC容器管理Bean生命周期:销毁public void destroy(){System.out.println("销毁AlphaService");}
}
测试:testBean()
//测试Bean的生命周期//修改Scope作用域@Testpublic void testBean(){AlphaService alphaService=applicationContext.getBean(AlphaService.class);System.out.println(alphaService);alphaService=applicationContext.getBean(AlphaService.class);System.out.println(alphaService);}
体验配置类
添加AlphaConfig
package com.jsss.community.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.text.SimpleDateFormat;@Configuration
public class AlphaConfig {//配置类使用Bean注解添加Bean//方法名就是Bean名字@Beanpublic SimpleDateFormat simpleDateFormat(){return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");}}
测试:getBeanConfig()
//测试配置类@Testpublic void getBeanConfig(){SimpleDateFormat simpleDateFormat=applicationContext.getBean(SimpleDateFormat.class);System.out.println(simpleDateFormat.format(new Date()));}
体验依赖注入
容器的主动getBean
使用注解@AutoWire
测试:testDI()
@Autowired@Qualifier("alphaDaoHibernate")//指定Bean名字private AlphaDao alphaDao;@Autowiredprivate AlphaService alphaService;@Autowiredprivate SimpleDateFormat simpleDateFormat;@Testpublic void testDI(){System.out.println(alphaDao);System.out.println(alphaService);System.out.println(simpleDateFormat);}
体验三层架构
Controller–Service–Dao
Service调用Dao
package com.jsss.community.service;import com.jsss.community.dao.AlphaDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;@Service//容器管理
//作用域 单例 多态
//@Scope("singleton")
//@Scope("prototype")
public class AlphaService {@Autowiredprivate AlphaDao alphaDao;@PostConstruct//IOC容器管理Bean生命周期:初始化public void init(){System.out.println("初始化AlphaService");}@PreDestroy//IOC容器管理Bean生命周期:销毁public void destroy(){System.out.println("销毁AlphaService");}public String find(){return alphaDao.select();}}
Controller调用Service
package com.jsss.community.controller;@Controller
@RequestMapping("/alpha")
public class AlphaController {@Autowiredprivate AlphaService alphaService;@RequestMapping("/data")@ResponseBodypublic String getData(){return alphaService.find();}
}
访问:http://localhost:8080/community/alpha/data
4.SpringMVC入门
配置
# ThymeleafProperties
spring.thymeleaf.cache=false
体验响应数据
AlphaController.http()
@RequestMapping("/http")public void http(HttpServletRequest request, HttpServletResponse response){//获取请求数据System.out.println(request.getMethod());// GETSystem.out.println(request.getServletPath());// /alpha/httpEnumeration<String> enumeration = request.getHeaderNames();while (enumeration.hasMoreElements()){String name = enumeration.nextElement();String value = request.getHeader(name);System.out.println(name+": "+value);}System.out.println(request.getParameter("code"));//123// 返回响应数据response.setContentType("text/html;charset=utf-8");try (PrintWriter writer = response.getWriter();){writer.write("<h1>牛客网</h1>");} catch (IOException e) {e.printStackTrace();}}
访问:http://localhost:8080/community/alpha/http?code=123
体验响应Get请求
- 路径拼接
- Restful风格
AlphaController.getStudents()
AlphaController.getStudent()
// GET 请求// /students?current=1&limit=20@RequestMapping(path = "/students",method = RequestMethod.GET)@ResponseBodypublic String getStudents(@RequestParam(name = "current",required = false,defaultValue = "1") int current,@RequestParam(name = "limit",required = false,defaultValue = "10") int limit){System.out.println(current);System.out.println(limit);return "some students";}// /student/123@RequestMapping(path = "/student/{id}",method = RequestMethod.GET)@ResponseBodypublic String getStudent(@PathVariable("id") int id){System.out.println(id);return "a student";}
访问:http://localhost:8080/community/alpha/students?current=1&limit=20
访问:http://localhost:8080/community/alpha/student/123
体验响应Post请求
新增页面:static/html/student.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>增加学生</title>
</head>
<body><form method="post" action="/community/alpha/student"><p>姓名:<input type="text" name="name"></p><p>年龄:<input type="text" name="age"></p><p><input type="submit" value="保存"></p></form>
</body>
</html>
AlphaController.save()
// POST请求@RequestMapping(path = "/student",method = RequestMethod.POST)@ResponseBodypublic String save(String name,int age){System.out.println(name);System.out.println(age);return "success";}
访问:http://localhost:8080/community/html/student.html
体验响应HTML数据
AlphaController.getTeacher()
//响应HTML数据@RequestMapping(path = "/teacher",method = RequestMethod.GET)public ModelAndView getTeacher(){ModelAndView mav=new ModelAndView();mav.addObject("name","张三");mav.addObject("age",30);mav.setViewName("/demo/view");return mav;}
新增页面:template/demo/view.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Teacher</title>
</head>
<body><p th:text="${name}"></p><p th:text="${age}"></p>
</body>
</html>
访问:http://localhost:8080/community/alpha/teacher
AlphaController.getSchool()
@RequestMapping(path = "/school",method = RequestMethod.GET)public String getSchool(Model model){model.addAttribute("name","北京大学");model.addAttribute("age","80");return "demo/view";}
访问:http://localhost:8080/community/alpha/school
体验响应JSON数据
AlphaController.getEmp()
AlphaController.getEmps()
// 响应JSON数据(异步请求)// Java对象 -> JSON字符串 -> JS对象@RequestMapping(path = "/emp",method = RequestMethod.GET)@ResponseBodypublic Map<String,Object> getEmp(){Map<String,Object> emp =new HashMap<>();emp.put("name","张三");emp.put("age",23);emp.put("salary",8000.00);return emp;}@RequestMapping(path = "/emps",method = RequestMethod.GET)@ResponseBodypublic List<Map<String,Object>> getEmps(){List<Map<String,Object>> list=new ArrayList<>();Map<String,Object> emp =new HashMap<>();emp.put("name","张三");emp.put("age",23);emp.put("salary",8000.00);list.add(emp);emp =new HashMap<>();emp.put("name","李四");emp.put("age",24);emp.put("salary",9000.00);list.add(emp);emp =new HashMap<>();emp.put("name","王五");emp.put("age",25);emp.put("salary",10000.00);list.add(emp);return list;}
访问:http://localhost:8080/community/alpha/emp
访问:http://localhost:8080/community/alpha/emps
5MyBatis入门
配置
添加依赖
<!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.22</version></dependency><!--mybatis整合spring--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.0.1</version></dependency>
<!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency>
添加配置
# DataSourceProperties
# 驱动
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 路径
spring.datasource.url=jdbc:mysql://localhost:3306/community?characterEncoding=utf-8&useSSL=false&serverTimezone=Hongkongspring.datasource.username=root
spring.datasource.password=root
#spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.type=com.mysql.cj.jdbc.MysqlDataSource
spring.datasource.hikari.maximum-pool-size=15
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=30000# MybatisProperties
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.jsss.community.entity
#启用自动自增主键
mybatis.configuration.useGeneratedKeys=true
#开启驼峰命名自动匹配
mybatis.configuration.mapUnderscoreToCamelCase=true
User
新建:/entity/User.java
package com.jsss.community.entity;import java.util.Date;import lombok.*;@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {private int id;private String username;private String password;private String salt;private String email;private int type;private int status;private String activationCode;private String headerUrl;private Date createTime;}
UserMapper
新建:/dao/UserMapper.java
package com.jsss.community.dao;import com.jsss.community.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;@Mapper
public interface UserMapper {User selectById(int id);User selectByName(String name);User selectByEmail (String email);int insertUser(User user);int updateStatus(@Param("id")int id, @Param("status") int status);int updateHeader(@Param("id")int id, @Param("headerUrl")String headerUrl);int updatePassword(@Param("id")int id, @Param("password")String password);
}
user-mapper.xml
新建:/mapper/user-mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jsss.community.dao.UserMapper"><sql id="insertFields">username, password, salt, email, type, status, activation_code, header_url, create_time</sql><sql id="selectFields">id, username, password, salt, email, type, status, activation_code, header_url, create_time</sql><select id="selectById" resultType="User">select <include refid="selectFields"></include>from userwhere id = #{id}</select><select id="selectByName" resultType="User">select <include refid="selectFields"></include>from userwhere username = #{username}</select><select id="selectByEmail" resultType="User">select <include refid="selectFields"></include>from userwhere email = #{email}</select><insert id="insertUser" parameterType="User" keyProperty="id">insert into user (<include refid="insertFields"></include>)values(#{username}, #{password}, #{salt}, #{email}, #{type}, #{status}, #{activationCode}, #{headerUrl}, #{createTime})</insert><update id="updateStatus">update user set status = #{status} where id = #{id}</update><update id="updateHeader">update user set header_url = #{headerUrl} where id = #{id}</update><update id="updatePassword">update user set password = #{password} where id = #{id}</update></mapper>
测试:MapperTest
新建:test:MapperTest.java
package com.jsss.community;import com.jsss.community.dao.UserMapper;import com.jsss.community.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;import java.util.Date;@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class MapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testSelectUser() {User user = userMapper.selectById(101);System.out.println(user);user = userMapper.selectByName("liubei");System.out.println(user);user = userMapper.selectByEmail("nowcoder101@sina.com");System.out.println(user);}@Testpublic void testInsertUser() {User user = new User();user.setUsername("test");user.setPassword("123456");user.setSalt("abc");user.setEmail("test@qq.com");user.setHeaderUrl("http://www.nowcoder.com/101.png");user.setCreateTime(new Date());int rows = userMapper.insertUser(user);System.out.println(rows);System.out.println(user.getId());}@Testpublic void updateUser() {int rows = userMapper.updateStatus(150, 1);System.out.println(rows);rows = userMapper.updateHeader(150, "http://www.nowcoder.com/102.png");System.out.println(rows);rows = userMapper.updatePassword(150, "hello");System.out.println(rows);}}
设置日志级别
# logger
logging.level.com.jsss.community=debug
2023-4-30 23:33:09
6开发社区首页
DiscussPost
新增:entity/DiscussPost.java
package com.jsss.community.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;@Data
@AllArgsConstructor
@NoArgsConstructor
public class DiscussPost {private int id;private int userId;private String title;private String content;private int type;private int status;private Date createTime;private int commentCount;private double score;}
DiscussPostMapper
新增:/dao/DiscussPostMapper.java
package com.jsss.community.dao;import com.jsss.community.entity.DiscussPost;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;@Mapper
public interface DiscussPostMapper {List<DiscussPost> selectDiscussPosts(int userId,int offset,int limit);// @Param注解用于给参数取别名,// 如果只有一个参数,并且在<if>里使用,则必须加别名.int selectDiscussPostRows(@Param("userId") int userId);}
discusspost-mapper.xml
新增:/mapper/discusspost-mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jsss.community.dao.DiscussPostMapper"><sql id="selectFields">id, user_id, title, content, type, status, create_time, comment_count, score</sql><sql id="insertFields">user_id, title, content, type, status, create_time, comment_count, score</sql><select id="selectDiscussPosts" resultType="DiscussPost">select <include refid="selectFields"></include>from discuss_postwhere status != 2<if test="userId!=0">and user_id = #{userId}</if>order by type desc, create_time desclimit #{offset}, #{limit}</select><select id="selectDiscussPostRows" resultType="int">select count(id)from discuss_postwhere status != 2<if test="userId!=0">and user_id = #{userId}</if></select></mapper>
测试Dao层
新增:MapperTest.testSelectPosts()
@Testpublic void testSelectPosts() {List<DiscussPost> list = discussPostMapper.selectDiscussPosts(149, 0, 10);for (DiscussPost post : list) {System.out.println(post);}int rows = discussPostMapper.selectDiscussPostRows(149);System.out.println(rows);}
DiscussPostService
新增:/service/DiscussPostService.java
package com.jsss.community.service;import com.jsss.community.dao.DiscussPostMapper;import com.jsss.community.entity.DiscussPost;
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;@Service
public class DiscussPostService {@Autowiredprivate DiscussPostMapper discussPostMapper;public List<DiscussPost> findDiscussPosts(int userId, int offset, int limit) {return discussPostMapper.selectDiscussPosts(userId, offset, limit);}public int findDiscussPostRows(int userId) {return discussPostMapper.selectDiscussPostRows(userId);}}
对于帖子:
我们要显示用户名称而不是用户id
有两种解决办法:
- 关联查询
- 在高层添加
UserService
新增:/service/UserService.java
package com.jsss.community.service;import com.jsss.community.dao.UserMapper;
import com.jsss.community.entity.User;
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Service
public class UserService{@AutowiredUserMapper userMapper;public User findUserById(int id){return userMapper.selectById(id);}}
前端资源准备
复制静态文件到static下
复制网页到templates
顺便把mail复制进来
mail:将来学习发邮件的模板
HomeController
新增:/controller/HomeController()
package com.jsss.community.controller;import com.jsss.community.entity.DiscussPost;
import com.jsss.community.entity.User;
import com.jsss.community.service.DiscussPostService;
import com.jsss.community.service.UserService;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@Controller
public class HomeController {@Autowiredprivate DiscussPostService discussPostService;@Autowiredprivate UserService userService;@RequestMapping(path = "/", method = RequestMethod.GET)public String root() {return "forward:/index";}@RequestMapping(path = "/index", method = RequestMethod.GET)public String getIndexPage(Model model) {List<DiscussPost> list = discussPostService.findDiscussPosts(0, 0, 10);List<Map<String, Object>> discussPosts = new ArrayList<>();if (list != null) {for (DiscussPost post : list) {Map<String, Object> map = new HashMap<>();map.put("post", post);User user = userService.findUserById(post.getUserId());map.put("user", user);discussPosts.add(map);}}model.addAttribute("discussPosts", discussPosts);return "/index";}}
index.html
修改html标签
<html lang="en" xmlns:th="http://www.thymeleaf.org">
修改静态路径
<!--前面--><link rel="stylesheet" th:href="@{/css/global.css}" /><!--后面--><script th:src="@{/js/global.js}"></script><script th:src="@{js/index.js}"></script>
主要修改内容main的部分
修改:帖子列表的部分
静态数据改为动态数据
<!-- 帖子列表 --><ul class="list-unstyled"><li class="media pb-3 pt-3 mb-3 border-bottom" th:each="map:${discussPosts}"><a href="site/profile.html"><img th:src="${map.user.headerUrl}" class="mr-4 rounded-circle" alt="用户头像" style="width:50px;height:50px;"></a><div class="media-body"><h6 class="mt-0 mb-3"><a href="#" th:utext="${map.post.title}">备战春招,面试刷题跟他复习,一个月全搞定!</a><span class="badge badge-secondary bg-primary" th:if="${map.post.type==1}">置顶</span><span class="badge badge-secondary bg-danger" th:if="${map.post.status==1}">精华</span></h6><div class="text-muted font-size-12"><u class="mr-3" th:utext="${map.user.username}">寒江雪</u> 发布于 <b th:text="${#dates.format(map.post.createTime,'yyyy-MM-dd HH:mm:ss')}">2019-04-15 15:32:18</b><ul class="d-inline float-right"><li class="d-inline ml-2">赞 11</li><li class="d-inline ml-2">|</li><li class="d-inline ml-2">回帖 7</li></ul></div></div> </li></ul>
访问:http://localhost:8080/community/index
Page
分页功能
新增:/entity/Page.java
package com.jsss.community.entity;/*** 封装分页相关的信息.*/
public class Page {// 当前页码private int current = 1;// 显示上限private int limit = 10;// 数据总数(用于计算总页数)private int rows;// 查询路径(用于复用分页链接)private String path;public int getCurrent() {return current;}public void setCurrent(int current) {if (current >= 1) {this.current = current;}}public int getLimit() {return limit;}public void setLimit(int limit) {if (limit >= 1 && limit <= 100) {this.limit = limit;}}public int getRows() {return rows;}public void setRows(int rows) {if (rows >= 0) {this.rows = rows;}}public String getPath() {return path;}public void setPath(String path) {this.path = path;}/*** 获取当前页的起始行** @return*/public int getOffset() {// current * limit - limitreturn (current - 1) * limit;}/*** 获取总页数** @return*/public int getTotal() {// rows / limit [+1]if (rows % limit == 0) {return rows / limit;} else {return rows / limit + 1;}}/*** 获取起始页码** @return*/public int getFrom() {int from = current - 2;return from < 1 ? 1 : from;//低的时候,就按最大页算}/*** 获取结束页码** @return*/public int getTo() {int to = current + 2;int total = getTotal();return to > total ? total : to;//超的时候,就按最大页算}}
修改:HomeController.getIndexPage()
@RequestMapping(path = "/index", method = RequestMethod.GET)public String getIndexPage(Model model, Page page) {// 方法调用栈,SpringMVC会自动实例化Model和Page,并将Page注入Model.// 所以,在thymeleaf中可以直接访问Page对象中的数据.page.setRows(discussPostService.findDiscussPostRows(0));page.setPath("/index");List<DiscussPost> list = discussPostService.findDiscussPosts(0, page.getOffset(), page.getLimit());List<Map<String, Object>> discussPosts = new ArrayList<>();if (list != null) {for (DiscussPost post : list) {Map<String, Object> map = new HashMap<>();map.put("post", post);User user = userService.findUserById(post.getUserId());map.put("user", user);discussPosts.add(map);}}model.addAttribute("discussPosts", discussPosts);return "/index";}
修改:index.html:分页
<!-- 分页 --><nav class="mt-5" th:if="${page.rows>0}"><ul class="pagination justify-content-center"><li class="page-item"><a class="page-link" th:href="@{${page.path}(current=1)}">首页</a></li><li th:class="|page-item ${page.current==1?'disabled':''}|"><a class="page-link" th:href="@{${page.path}(current=${page.current-1})}">上一页</a></li><li th:class="|page-item ${i==page.current?'active':''}|" th:each="i:${#numbers.sequence(page.from,page.to)}"><a class="page-link" th:href="@{${page.path}(current=${i})}" th:text="${i}">1</a></li><li th:class="|page-item ${page.current==page.total?'disabled':''}|"><a class="page-link" th:href="@{${page.path}(current=${page.current+1})}">下一页</a></li><li class="page-item"><a class="page-link" th:href="@{${page.path}(current=${page.total})}">末页</a></li></ul></nav></div></div>
访问:http://localhost:8080/community/index?current=1
7项目调试技巧
测试:日志功能
新增:test:LoggerTests.java
package com.jsss.community;import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class LoggerTests {private static final Logger logger= LoggerFactory.getLogger(LoggerTests.class);@Testpublic void testLogger(){System.out.println(logger.getName());logger.debug("debug log");logger.info("info log");logger.warn("warn log");logger.error("error log");}
}
配置:
# logger
logging.level.com.jsss.community=debug
logging.file.name=E:/work/data/jsss/community.log
添加:/logback-spring.xml
8版本控制
git的使用
git add .
git commit -m "消息"
git push
git status
git reset HEAD
最后
这篇博客能写好的原因是:站在巨人的肩膀上
这篇博客要写好的目的是:做别人的肩膀
开源:为爱发电
学习:为我而行