基于springboot小说阅读网站设计与实现
随着社会发展速度的愈来愈快,以及社会压力变化的越来越快速,致使很多人采取各种不同的方法进行解压。大多数人的稀释压力的方法,是捧一本书籍,心情地让自己沉浸在情节里面,以短暂的愉悦让自己得以释怀。晒书小说阅读网是典型的信息发布网站,其开发主要包括后台数据库的建立和维护以及前端应用程序的开发两个方面。对于前者要求建立起数据一致性和完整性强、数据安全性好的数据库。而对于后者则要求应用程序功能完备,易使用等特点。
论文主要围绕小说阅读网站的设计与实现展开研究,遵循软件工程设计流程,在需求分析的基础上,明确了小说阅读网站的各项功能。利用springboot、 mybatis等技术,设计实现了一个基于B/S模式的小说阅读网站,可完成管理员管理数据,作者发布小说,用户阅读小说的功能,并对该小说阅读网站的各个功能模块进行测试。所设计的用户操作界面布局合理、交互友好。
该网站的使用可以使管理人员更加有效地掌握用户的各类信息数据,保证了用户数据的及时性和准确性,直接解决了用户数量大、 人员情况复杂与流动性大的管理难题,提升了小说阅读效率。
关键字: 小说阅读;B/S模式;springboot;mysql
ABSTRACT
With the rapid development of society and the rapid change of social pressure, many people take different methods to decompress. The way most people dilute their pressure is to hold a book, immerse themselves in the plot in a mood, and let themselves be relieved with a short pleasure. As a typical information publishing website, the development of the website mainly includes the establishment and maintenance of the background database and the development of front-end applications. For the former, it is required to establish a database with strong data consistency and integrity and good data security. For the latter, the application program should be complete and easy to use.
The thesis mainly focuses on the design and implementation of novel reading website, follows the software engineering design process, and clarifies the functions of novel reading website on the basis of demand analysis. Using spring boot, mybatis and other technologies, a novel reading website based on B/S mode is designed and implemented, which can complete the functions of administrator managing data, author publishing novels, and user reading novels, and test each functional module of the novel reading website. The user interface designed is reasonable in layout and friendly in interaction.
The use of this website can enable managers to more effectively master various types of user information data, ensure the timeliness and accuracy of user data, directly solve the management problems of large number of users, complex personnel situation and large mobility, and improve the efficiency of novel reading.
Key words: novel reading; B/S mode; springboot; mysql
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
<facet type="web" name="Web">
<configuration>
<webroots />
<sourceRoots>
<root url="file://$MODULE_DIR$/src/main/java" />
<root url="file://$MODULE_DIR$/src/main/resources" />
</sourceRoots>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-thymeleaf:2.3.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.3.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.3.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.13.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.13.3" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.30" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.26" level="project" />
<orderEntry type="library" name="Maven: org.thymeleaf:thymeleaf-spring5:3.0.11.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.thymeleaf:thymeleaf:3.0.11.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.attoparser:attoparser:2.0.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.unbescape:unbescape:1.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.thymeleaf.extras:thymeleaf-extras-java8time:3.0.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.3.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.3.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.11.3" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.11.3" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.11.3" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.11.3" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.11.3" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.11.3" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.3.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.41" level="project" />
<orderEntry type="library" name="Maven: org.glassfish:jakarta.el:3.0.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.41" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.2.12.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.2.12.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.2.12.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.2.12.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.2.12.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.2.12.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-boot-starter:3.4.2" level="project" />
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.4.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.3.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.3.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.2.12.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.2.12.RELEASE" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:8.0.22" level="project" />
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.16" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.3.7.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.3.7.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.3.7.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.jayway.jsonpath:json-path:2.4.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:1.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:5.0.4" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: jakarta.activation:jakarta.activation-api:1.2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.16.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest:2.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter:5.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-api:5.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.opentest4j:opentest4j:1.2.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-commons:1.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-params:5.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-engine:5.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-engine:1.6.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:3.3.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy:1.10.18" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.10.18" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.6" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-junit-jupiter:3.3.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.2.12.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.2.12.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.2.12.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.7.0" level="project" />
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-generator:3.3.0" level="project" />
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.3.0" level="project" />
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-core:3.3.0" level="project" />
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-annotation:3.3.0" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.3" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.velocity:velocity-engine-core:2.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.10" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.72" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-spring:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-lang:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-cache:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-hash:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-core:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-cipher:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-config-core:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-config-ogdl:1.4.0" level="project" />
<orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.3" level="project" />
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-event:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-web:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-devtools:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.3.7.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.2.3" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.1" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:1.3.1" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.2.3" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.1.2" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:1.0" level="project" />
</component>
</module>
package com.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.pojo.*;
import com.pojo.result.Result;
import com.pojo.result.ResultPage;
import com.service.*;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.ModelAndView;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
/**
* <p>
* 积分物品表 前端控制器
* </p>
*
* @since 2024-09-06
*/
@RestController
@RequestMapping("/book")
public class BookController {
@Autowired
private BookService bookService;
@Autowired
private CategoryService categoryService;
@Autowired
private CommentService commentService;
@Autowired
private UserService userService;
@Autowired
private MarkService markService;
//添加书籍
@PostMapping("/add")
public Result add(Book book) {
User currentUser = (User) SecurityUtils.getSubject().getPrincipal();
//验证表单信息
if (bookService.getOne(new LambdaQueryWrapper<Book>().eq(Book::getName, book.getName())) != null) {
return Result.failure("已有相同名称的书籍,请重新命名");
} else {
book.setUserId(currentUser.getId());
book.setCreateDate(new Date());
book.setAuthor(currentUser.getName());
return Result.decide(bookService.save(book));
}
}
//删除书籍
@PostMapping("/delete")
public Result delete(@RequestParam(value = "id") String id) {
return Result.decide(bookService.removeById(id));
}
//修改书籍
@PostMapping("/update")
public Result update(Book book) {
Book currentBook = bookService.getById(book.getId());
//验证表单信息
if (bookService.getOne(new LambdaQueryWrapper<Book>().eq(Book::getName, book.getName())) != null
&& !book.getName().equals(currentBook.getName())) {
return Result.failure("已有相同名称的商品,请重新命名");
} else {
return Result.decide(bookService.updateById(book));
}
}
//根据id获取书籍
@PostMapping("/getOne")
public Result getOne(@RequestParam(value = "id") String id) {
return Result.success(bookService.getById(id));
}
//条件分页获取
@RequestMapping("/getAll")
public ResultPage getAll(@RequestParam(value = "userName", required = false) String userName,
@RequestParam(value = "bookName", required = false) String bookName,
@RequestParam(value = "categoryId", required = false) String categoryId,
@RequestParam(value = "page") Integer page,
@RequestParam(value = "limit") Integer limit) {
//分页条件
PageHelper.startPage(page, limit);
//获取当前用户信息
User currentUser = (User) SecurityUtils.getSubject().getPrincipal();
List<Book> ls = bookService.getAll(userName, bookName, categoryId, currentUser.getRoleId() == 0 ? null : currentUser.getId());
PageInfo<Book> pageInfo = new PageInfo<>(ls, limit);
return new ResultPage(0, (int) pageInfo.getTotal(), pageInfo.getList());
}
//首页点击榜数据展示
@RequestMapping("/listClickRank")
public Result listClickRank(String num) {
LambdaQueryWrapper<Book> query = new LambdaQueryWrapper<>();
query.eq(Book::getStatus, 1)
.orderByDesc(Book::getHits)
.last("limit " + num);
return Result.success(bookService.list(query));
}
//展示书籍详情
@RequestMapping("/getBookDetail/{bookId}")
public ModelAndView getBookDetail(@PathVariable String bookId) {
ModelAndView mv = new ModelAndView();
//作品信息
Book book = bookService.getById(bookId);
try {
//点击量+1
LambdaUpdateWrapper<Book> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper
.set(Book::getHits, book.getHits() + 1)
.eq(Book::getId, bookId);
bookService.update(updateWrapper);
} catch (Exception e) {
e.printStackTrace();
}
Category category = categoryService.getOne(book.getCategoryId());
book.setCategoryName(category.getName());
mv.addObject("book", book);
//评论信息
LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper
.eq(Comment::getBookId, bookId);
List<Comment> commentList = commentService.list(queryWrapper);
for (Comment comment : commentList) {
User user = userService.getById(comment.getUserId());
comment.setUserName(user == null ? "历史用户" : user.getName());
}
mv.addObject("commentList", commentList);
//评分
mv.addObject("mark", markService.selectAvg(bookId));
mv.setViewName("/index/bookDetail.html");
return mv;
}
//全部作品页面
@RequestMapping("/bookList")
public ModelAndView bookList() {
ModelAndView mv = new ModelAndView();
mv.setViewName("/index/bookList.html");
return mv;
}
//条件分页获取分类
@RequestMapping("/searchByPage")
public Result searchByPage(@RequestParam(value = "keyword", required = false) String keyWord,
@RequestParam(value = "catId", required = false) String categoryId,
@RequestParam(value = "curr") Integer page,
@RequestParam(value = "limit") Integer limit) {
//分页条件
PageHelper.startPage(page, limit);
//获取当前用户信息
User currentUser = (User) SecurityUtils.getSubject().getPrincipal();
List<Book> ls = bookService.getAllIndex(keyWord, categoryId);
PageInfo<Book> pageInfo = new PageInfo<>(ls, limit);
return Result.success(pageInfo);
}
//排行榜页面
@RequestMapping("/bookRankPage")
public ModelAndView bookRankPage() {
ModelAndView mv = new ModelAndView();
mv.setViewName("/index/bookRank.html");
return mv;
}
//排行榜数据展示
@RequestMapping("/bookRankList")
public Result bookRankList(String type) {
List<Book> ls = null;
LambdaQueryWrapper<Book> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Book::getStatus, 1)
.last("limit 30");
if ("0".equals(type)) {
//点击榜
queryWrapper.orderByDesc(Book::getHits);
ls = bookService.list(queryWrapper);
for (Book book : ls) {
Category category = categoryService.getOne(book.getCategoryId());
Double mark = markService.selectAvg(book.getId());
BigDecimal b = new BigDecimal(mark);
book.setMark(b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
book.setCategoryName(category.getName());
}
} else if ("1".equals(type)){
//收藏榜
queryWrapper.orderByDesc(Book::getCollectNum);
ls = bookService.list(queryWrapper);
for (Book book : ls) {
Category category = categoryService.getOne(book.getCategoryId());
Double mark = markService.selectAvg(book.getId());
BigDecimal b = new BigDecimal(mark);
book.setMark(b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
book.setCategoryName(category.getName());
}
} else {
//评分榜
ls = bookService.list(queryWrapper);
for (Book book : ls) {
//分类
Category category = categoryService.getOne(book.getCategoryId());
book.setCategoryName(category.getName());
//评分
Double mark = markService.selectAvg(book.getId());
BigDecimal b = new BigDecimal(mark);
book.setMark(b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
}
Collections.sort(ls, (a, b) -> {
return b.getMark().compareTo(a.getMark());
});
}
return Result.success(ls);
}
//作家榜,根据作家的作品的收藏总数排序
@RequestMapping("/authorRankList")
public Result authorRankList() {
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper
.eq(User::getStatus, 1)
.eq(User::getRoleId, 1)
.last("limit 30");
List<User> ls = userService.list(queryWrapper);
for (User user : ls) {
Integer collectNum = bookService.getCollectNum(user.getId());
user.setAllCollectNums(collectNum == null ? 0 : collectNum);
}
Collections.sort(ls, (a, b)->{
return b.getAllCollectNums() - a.getAllCollectNums();
});
return Result.success(ls);
}
}