1.实现分页功能:
首先要分析页面的https://elasticsearch.cn/explore/ 分页特点,当前页不是第一页时,“<”就会出现,与之对应的,当当前页不是最后一页时,“>”就会出现;另外页面是以7个数字为一组,当这7个数字不包含首页时,“<<”就会出现,而不包含尾页时,“>>”就会出现。
select * from question limit a, b: 从a位置开始,返回b个数据
select * from question limit a offset b:从b位置开始返回a个数据
2.P27:引入jquery后还显示404错误
解决方法:引入资源的顺序问题,必须先引入jquery,后引入bootstrap.min.js,因为在bootstrap.min.js有对jquery的使用。
3.thymeleaf:将固定的样式进行封装,在不同的页面进行调用。
navigation.html:存放格式的页面
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="nav">
//放固定的格式
</div>
</body>
</html>
进行调用
<div th:insert="navigation :: nav"></div>
4.@PathVariable:路径变量
可以在后台直接拿到页面传过来的数据,通过得到的数据来进行相应操作。
@GetMapping("/question/{id}")
public String question(@PathVariable(name = "id") Integer id,
Model model) {
QuestionDTO questionDTO = questionService.getById(id); model.addAttribute("question", questionDTO);
return "question";
}
5.拦截器:Interceptor
在运行网页之前,先进行某些操作。
6.退出登录操作的实现
在html中将退出登录映射到 /logout
<li><a href="/logout">退出登录</a></li>
// 在相应的controller中实现退出登录操作
@GetMapping("/logout")
public String logout(HttpServletRequest request,
HttpServletResponse response) {
// 将session从页面中移除
request.getSession().removeAttribute("user");
// 将自定义的 token cookie从页面中移除
Cookie cookie = new Cookie("token", "null");
cookie.setMaxAge(0);
response.addCookie(cookie);
return "redirect:/";
}
7.在html中接受id属性
<!--用于接收 id属性-->
<input type="hidden" name="id" th:value="${id}">
8.集成Mybatis Generator:http://mybatis.org/generator/
(1)在pom文件中加入相关插件
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.0</version>
需要驱动
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
</dependencies>
</plugin>
(2)在resources下建立generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- 数据库基本数据设置-->
<context id="DB2Tables" targetRuntime="MyBatis3">
<!--实现分页功能的插件 -->
<plugin type="org.mybatis.generator.plugins.RowBoundsPlugin"></plugin>
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/test?serverTimezone=UTC"
userId="root"
password="123456">
</jdbcConnection>
<javaTypeResolver >
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- model所在的位置-->
<javaModelGenerator targetPackage="life.zxw.community.community.model" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- xml所在的位置-->
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- xml映射的mapper-->
<javaClientGenerator type="XMLMAPPER" targetPackage="life.zxw.community.community.mapper" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 连接数据库中的表,重要属性为 tableName-->
<table tableName="user" domainObjectName="User" >
</table>
</context>
</generatorConfiguration>
(3)在运行程序上添加上@MapperScan
@MapperScan(basePackages = "life.zxw.community.community .mapper")
(4)在Terminal中运行,将会根据数据库表自动生成各种sql语句
mvn -Dmybatis.generator.overwrite=true mybatis-generator:generate
9.@Transactional:事务处理, 自动提交事务或者遇到异常自动回滚 。
https://www.jianshu.com/p/5687e2a38fbc
10.java 8 Stream:可以以一种声明的方式处理数据
https://www.runoob.com/java/java8-streams.html (菜鸟教程)
List<String> string = Arrays.asList("abc","","ba");
List<String> ss = string.stream().filter(s -> !s.isEmpty()).collect(Collectors.toList());
List<String> aa = string.stream().map(s -> s.toUpperCase()).collect(Collectors.toList());
System.out.println(ss);
[abc, ba]
System.out.println(aa);
[ABC, , BA]
// 获取去重的评论人
Set<Long> commentators = comments.stream().map(comment -> comment.getCommentator()).collect(Collectors.toSet());
List<Long> userIds = new ArrayList<>();
userIds.addAll(commentators);
// 获取评论人并转换成Map
UserExample userExample = new UserExample();
userExample.createCriteria()
.andIdIn(userIds);
List<User> users = userMapper.selectByExample(userExample);
Map<Long, User> userMap = users.stream().collect(Collectors.toMap(user -> user.getId(), user -> user));
// 转换comment为commentDTO
List<CommentDTO> commentDTOS = comments.stream().map(comment -> {
CommentDTO commentDTO = new CommentDTO();
BeanUtils.copyProperties(comment, commentDTO);
commentDTO.setUser(userMap.get(comment.getCommentator()));
return commentDTO;
}).collect(Collectors.toList());
return commentDTOS;
11.Mybatis Generator:生成属于自己的代码
(1)在\src\main\resources\mapper下建立自己的xml文件,书写相关的sql语句,并映射到相应的mapper
(2)在\src\main\java\life\zxw\community\community\mapper下建立自己的mapper
12.实现MarkDown编辑(利用 editor.md ): http://editor.md.ipandao.com/
(1)创建markdown编辑器
<link rel="stylesheet" href="editor.md/css/editormd.min.css" />
<script src="jquery.min.js"></script>
<script src="editor.md/editormd.min.js"></script>
<div id="editor">
<!-- Tips: Editor.md can auto append a `<textarea>` tag -->
<textarea style="display:none;">### Hello Editor.md !</textarea>
</div>
<script type="text/javascript">
$(function() {
var editor = editormd("editor", {
// width: "100%",
// height: "100%",
// markdown: "xxxx", // dynamic set Markdown text
path : "editor.md/lib/" // Autoload modules mode, codemirror, marked... dependents libs path
});
});
</script>
(2)将markdown的内容展现出来,将其放在展示内容的页面
<link rel="stylesheet" href="editormd/css/editormd.preview.css" />
<script src="jquery.min.js"></script>
<script src="editormd/editormd.js"></script>
<script src="editormd/lib/marked.min.js"></script>
<script src="editormd/lib/prettify.min.js"></script>
//展示markdown内容
<div id="test-markdown-view">
<!-- Server-side output Markdown text -->
<textarea style="display:none;">### Hello world!</textarea>
</div>
<script type="text/javascript">
$(function() {
var testView = editormd.markdownToHTML("test-markdown-view", {
// markdown : "[TOC]\n### Hello world!\n## Heading 2", // Also, you can dynamic set Markdown text
// htmlDecode : true, // Enable / disable HTML tag encode.
// htmlDecode : "style,script,iframe", // Note: If enabled, you should filter some dangerous HTML tags for website security.
});
});
</script>
14.动态sql: if,choose(when,otherwise),where,set,foreach等
mybatis核心对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装。
参考文献: https://blog.csdn.net/madman_donghui/article/details/79449524
15.实现搜索功能
(1)将页面的搜索内容发送到后端
<form class="navbar-form navbar-left" action="/" method="get">
<div class="form-group">
<input type="text" class="form-control" name="search" placeholder="搜索问题"> </div>
<button type="submit" class="btn btn-default">搜索</button></form>
(2)
拿到页面传来的请求搜索内容
@RequestParam(name = "search",required = false) String search
进行搜索
PagesDTO pagesDTO = questionService.list(search,page,size);
将拿到的内容设置成 sql正则表达式中的样子(REGEXP)
if (StringUtils.isNotBlank(search)){
String[] strings = StringUtils.split(search," ");
search = Arrays.stream(strings).collect(Collectors.joining("|"));
}
将页面信息page,size以及search封装成QuestionQueryDTO,以便信息的拿取
利用自己写的动态sql来拿到查找问题数目
Integer totalcount = extMapper.countBySearch(questionQueryDTO);
拿到问题列表
List<Question> questions = extMapper.selectByearch(questionQueryDTO);
将拿到的问题列表以及search返回到页面
model.addAttribute("pagesDTO", pagesDTO);
model.addAttribute("search", search);
(3)
当并没有进行搜索时,即search==null,这时候正常显示页面。
<ul class="pagination" th:if="${search==null}">
当进行搜索时,即search!=null,这时候显示与搜索问题相关的页面,与此同时,翻页时也将search加入地址。
<ul class="pagination" th:if="${search!=null}">
<a th:href="@{/(page=${page},search=${search})}" th:text="${page}">
16.添加日志
设置日志存储路径
logging.file.path=logs/community.
设置日志等级
loglogging.level.root=info
设计日志最大存储天数
logging.file.max-history=15
设置日志最大存储容量
logging.file.maxsize=100MB
server.servlet.session.timeout=15552000
spring.servlet.multipart.max-file-size=20MB
spring.servlet.multipart.max-request-size=20MB
},search=${
search})}" th:text="${
page}">
16.添加日志
设置日志存储路径
logging.file.path=logs/community.
设置日志等级
loglogging.level.root=info
设计日志最大存储天数
logging.file.max-history=15
设置日志最大存储容量
logging.file.maxsize=100MB
server.servlet.session.timeout=15552000
spring.servlet.multipart.max-file-size=20MB
spring.servlet.multipart.max-request-size=20MB