✨SSM整合
頁面發送請求給控制器,控制器調用業務層處理邏輯,邏輯層向持久層發送請求,持久層與資料庫互動,後将結果傳回給業務層,業務層将處理邏輯發送給控制器,控制器再調用視圖展現資料。
本部落格按照【狂神說Java】SSM架構最新整合教學IDEA版_哔哩哔哩_bilibili 進行SSM整合(對應視訊 P1-P3 部分)
本篇更新相關功能實作(對應視訊 P4-P7 部分)
!部分代碼和視訊有出入 請自行檢查比對
✨配置Tomcat
運作 -> 編輯配置

點選 + 後選擇 Tomcat Server(本地)
點選 修正
部署工件後 點選确定
✨項目結構修改
在項目結構設定中選擇“工件”
在 WEB-INF 目錄下建立 lib 目錄
在
lib
目錄右鍵 -> 添加副本 -> 庫檔案
選擇添加所有外部庫
✨查詢書籍功能
Controller
在 com.example.controller 下建立類 BookController
package com.example.controller;
import com.example.pojo.Books;
import com.example.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/book")
public class BookController {
// controller 調 service層
@Autowired
@Qualifier("bookServiceImpl")
private BookService bookService;
// 查詢全部書籍并且傳回到一個書籍展示頁面
@RequestMapping("/allBook")
public String list(Model model) {
List<Books> list = bookService.listBooks();
model.addAttribute("list", list);
return "allBook";
}
}
前端
在 WEB-INF/jsp 下建立 allBook.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>書籍展示</title>
<%-- BootStrap美化界面--%>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>書籍清單 —— 顯示所有書籍</small>
</h1>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>書籍編号</th>
<th>書籍名稱</th>
<th>書籍數量</th>
<th>書籍詳情</th>
</tr>
</thead>
<%-- 書籍從資料庫中查詢出來 從list中周遊 foreach--%>
<tbody>
<c:forEach var="book" items="${list}">
<tr>
<td>${book.bookId}</td>
<td>${book.bookName}</td>
<td>${book.bookCounts}</td>
<td>${book.bookDetail}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
修改 **index.jsp **如下
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首頁</title>
<style>
a{
text-decoration: none;
color: black;
font-size: 18px;
}
h3{
width: 180px;
height: 38px;
margin: 100px auto;
text-align: center;
line-height: 38px;
background: deepskyblue;
border-radius: 5px;
}
</style>
</head>
<body>
<h3>
<a href="${pageContext.request.contextPath}/book/allBook">進入書籍頁面</a>
</h3>
</body>
</html>
啟動Tomcat
效果展示
http://localhost:8080/SSM_build_war_exploded/
http://localhost:8080/SSM_build_war_exploded/book/allBook
✨添加書籍功能
修改 BookController 如下
package com.example.controller;
import com.example.pojo.Books;
import com.example.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/book")
public class BookController {
// controller 調 service層
@Autowired
@Qualifier("bookServiceImpl")
private BookService bookService;
// 查詢全部書籍并且傳回到一個書籍展示頁面
@RequestMapping("/allBook")
public String list(Model model) {
List<Books> list = bookService.listBooks();
model.addAttribute("list", list);
return "allBook";
}
// 跳轉到增加書籍頁面
@RequestMapping("/toAddBook")
public String toAddPaper(){
return "addBook";
}
// 添加書籍的請求
@RequestMapping("/addBook")
public String addBook(Books books){
System.out.println("addBooks =>" + books);
bookService.insertBook(books);
// 重定向到 @RequestMapping("/allBook")請求
return "redirect:/book/allBook";
}
}
修改 allBook.jsp 如下
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>書籍展示</title>
<%-- BootStrap美化界面--%>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>書籍清單 —— 顯示所有書籍</small>
</h1>
</div>
</div>
<div class="row">
<div class="col-md-4 column">
<%-- 新增書籍--%>
<a class="btn btn-primary" href="${pageContext.request.contextPath}/book/toAddBook">新增書籍</a>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>書籍編号</th>
<th>書籍名稱</th>
<th>書籍數量</th>
<th>書籍詳情</th>
</tr>
</thead>
<%-- 書籍從資料庫中查詢出來 從list中周遊 foreach--%>
<tbody>
<c:forEach var="book" items="${list}">
<tr>
<td>${book.bookId}</td>
<td>${book.bookName}</td>
<td>${book.bookCounts}</td>
<td>${book.bookDetail}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
在 WEB-INF/jsp 下建立 addBook.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>新增書籍</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>新增書籍</small>
</h1>
</div>
</div>
<form action="${pageContext.request.contextPath}/book/addBook" method="post">
<div class="form-group">
<label for="bookName">書籍名稱</label>
<input type="text" name="bookName" class="form-control" id="bookName" required>
</div>
<div class="form-group">
<label for="bookCounts">書籍數量</label>
<input type="text" name="bookCounts" class="form-control" id="bookCounts" required>
</div>
<div class="form-group">
<label for="bookDetail">書籍描述</label>
<input type="text" name="bookDetail" class="form-control" id="bookDetail" required>
</div>
<button type="submit" class="btn btn-default">添加</button>
</form>
</div>
</div>
</body>
</html>
http://localhost:8080/SSM_build_war_exploded/book/toAddBook
✨修改書籍功能
package com.example.controller;
import com.example.pojo.Books;
import com.example.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/book")
public class BookController {
// controller 調 service層
@Autowired
@Qualifier("bookServiceImpl")
private BookService bookService;
// 查詢全部書籍并且傳回到一個書籍展示頁面
@RequestMapping("/allBook")
public String list(Model model) {
List<Books> list = bookService.listBooks();
model.addAttribute("list", list);
return "allBook";
}
// 跳轉到增加書籍頁面
@RequestMapping("/toAddBook")
public String toAddPaper(){
return "addBook";
}
// 添加書籍的請求
@RequestMapping("/addBook")
public String addBook(Books books){
System.out.println("addBook =>" + books);
bookService.insertBook(books);
// 重定向到 @RequestMapping("/allBook")請求
return "redirect:/book/allBook";
}
// 跳轉到修改頁面
@RequestMapping("/toUpdate")
public String toUpdatePaper(int id, Model model){
Books bookById = bookService.getBookById(id);
model.addAttribute("getBookById", bookById);
return "updateBook";
}
// 修改書籍的請求
@RequestMapping("updateBook")
public String updataBook(Books books){
System.out.println("updateBook =>" + books);
bookService.insertBook(books);
return "redirect:/book/allBook";
}
}
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>書籍展示</title>
<%-- BootStrap美化界面--%>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>書籍清單 —— 顯示所有書籍</small>
</h1>
</div>
</div>
<div class="row">
<div class="col-md-4 column">
<%-- 新增書籍--%>
<a class="btn btn-primary" href="${pageContext.request.contextPath}/book/toAddBook">新增書籍</a>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>書籍編号</th>
<th>書籍名稱</th>
<th>書籍數量</th>
<th>書籍詳情</th>
<th>操作</th>
</tr>
</thead>
<%-- 書籍從資料庫中查詢出來 從list中周遊 foreach--%>
<tbody>
<c:forEach var="book" items="${list}">
<tr>
<td>${book.bookId}</td>
<td>${book.bookName}</td>
<td>${book.bookCounts}</td>
<td>${book.bookDetail}</td>
<td>
<a href="${pageContext.request.contextPath}/book/toUpdate/?id=${book.bookId}">修改</a>
|
<a href="">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
在 WEB-INF/jsp 下建立 updateBook.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>修改書籍</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>修改書籍</small>
</h1>
</div>
</div>
<form action="${pageContext.request.contextPath}/book/updateBook" method="post">
<%-- 後端需要根據bookId執行SQL--%>
<%-- 前端傳遞隐藏域--%>
<input type="hidden" name="bookId" value="${getBookById.bookId}">
<div class="form-group">
<label for="bookName">書籍名稱</label>
<%-- name需要與後端一緻--%>
<input type="text" name="bookName" class="form-control" id="bookName" value="${getBookById.bookName}" required>
</div>
<div class="form-group">
<label for="bookCounts">書籍數量</label>
<input type="text" name="bookCounts" class="form-control" id="bookCounts" value="${getBookById.bookCounts}" required>
</div>
<div class="form-group">
<label for="bookDetail">書籍描述</label>
<input type="text" name="bookDetail" class="form-control" id="bookDetail" value="${getBookById.bookDetail}" required>
</div>
<button type="submit" class="btn btn-default">修改</button>
</form>
</div>
</div>
</body>
</html>
http://localhost:8080/SSM_build_war_exploded/book/toUpdate/?id=6
✨删除書籍功能
package com.example.controller;
import com.example.pojo.Books;
import com.example.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/book")
public class BookController {
// controller 調 service層
@Autowired
@Qualifier("bookServiceImpl")
private BookService bookService;
// 查詢全部書籍并且傳回到一個書籍展示頁面
@RequestMapping("/allBook")
public String list(Model model) {
List<Books> list = bookService.listBooks();
model.addAttribute("list", list);
return "allBook";
}
// 跳轉到增加書籍頁面
@RequestMapping("/toAddBook")
public String toAddPaper(){
return "addBook";
}
// 添加書籍的請求
@RequestMapping("/addBook")
public String addBook(Books books){
System.out.println("addBook =>" + books);
bookService.insertBook(books);
// 重定向到 @RequestMapping("/allBook")請求
return "redirect:/book/allBook";
}
// 跳轉到修改頁面
@RequestMapping("/toUpdate")
public String toUpdatePaper(int id, Model model){
Books bookById = bookService.getBookById(id);
model.addAttribute("getBookById", bookById);
return "updateBook";
}
// 修改書籍的請求
@RequestMapping("updateBook")
public String updataBook(Books books){
System.out.println("updateBook =>" + books);
bookService.updateBook(books);
return "redirect:/book/allBook";
}
// 删除書籍的請求
@RequestMapping("toDelete/{bookId}")
public String toDelete(@PathVariable("bookId") int id){
System.out.println("deleteBook =>" + bookService.getBookById(id));
bookService.deleteBookById(id);
return "redirect:/book/allBook";
}
}
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>書籍展示</title>
<%-- BootStrap美化界面--%>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>書籍清單 —— 顯示所有書籍</small>
</h1>
</div>
</div>
<div class="row">
<div class="col-md-4 column">
<%-- 新增書籍--%>
<a class="btn btn-primary" href="${pageContext.request.contextPath}/book/toAddBook">新增書籍</a>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>書籍編号</th>
<th>書籍名稱</th>
<th>書籍數量</th>
<th>書籍詳情</th>
<th>操作</th>
</tr>
</thead>
<%-- 書籍從資料庫中查詢出來 從list中周遊 foreach--%>
<tbody>
<c:forEach var="book" items="${list}">
<tr>
<td>${book.bookId}</td>
<td>${book.bookName}</td>
<td>${book.bookCounts}</td>
<td>${book.bookDetail}</td>
<td>
<a href="${pageContext.request.contextPath}/book/toUpdate/?id=${book.bookId}">修改</a>
|
<a href="${pageContext.request.contextPath}/book/toDelete/${book.bookId}">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
點選删除 可以删除書籍
✨新增搜尋功能
新增搜尋功能涉及 dao層、service層、controller以及前端 修改
請按照步驟依次修改
本部落格實作了模糊查詢
dao層
在 BookMapper 接口下新增方法
package com.example.dao;
import com.example.pojo.Books;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface BookMapper {
int insertBook(Books books);
int deleteBookById(@Param("bookId") int bookId);
int updateBook(Books books);
Books getBookById(@Param("bookId") int bookId);
@Select("select * from ssm_build.books")
List<Books> listBooks();
List<Books> listBookLikeName(@Param("bookName") String bookName);
}
在 BookMapper.xml 中編寫 SQL(或者使用注解)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.dao.BookMapper">
<insert id="insertBook" parameterType="books">
insert into ssm_build.books(book_id, book_name, book_counts, book_detail)
VALUES (#{bookId}, #{bookName}, #{bookCounts}, #{bookDetail})
</insert>
<delete id="deleteBookById" parameterType="int">
delete from ssm_build.books where book_id = #{bookId}
</delete>
<update id="updateBook" parameterType="books">
update ssm_build.books
set book_name = #{bookName}, book_counts = #{bookCounts}, book_detail = #{bookDetail}
where book_id = #{bookId}
</update>
<select id="getBookById" resultType="books">
select * from ssm_build.books where book_id = #{bookId}
</select>
<select id="listBookLikeName" resultType="books">
select * from ssm_build.books where book_name like '%${bookName}%'
</select>
</mapper>
service層
在 BookService 接口下新增方法
package com.example.service;
import com.example.pojo.Books;
import java.util.List;
public interface BookService {
int insertBook(Books books);
int deleteBookById(int bookId);
int updateBook(Books books);
Books getBookById(int bookId);
List<Books> listBooks();
List<Books> listBookLikeName(String bookName);
}
在 BookServiceImpl 實作類中實作方法
package com.example.service;
import com.example.dao.BookMapper;
import com.example.pojo.Books;
import java.util.List;
public class BookServiceImpl implements BookService{
// service層 調 dao層
private BookMapper bookMapper;
public void setBookMapper(BookMapper bookMapper) {
this.bookMapper = bookMapper;
}
@Override
public int insertBook(Books books) {
return bookMapper.insertBook(books);
}
@Override
public int deleteBookById(int bookId) {
return bookMapper.deleteBookById(bookId);
}
@Override
public int updateBook(Books books) {
// System.out.println("BookServiceImpl: updateBook" + books);
return bookMapper.updateBook(books);
}
@Override
public Books getBookById(int bookId) {
return bookMapper.getBookById(bookId);
}
@Override
public List<Books> listBooks() {
return bookMapper.listBooks();
}
@Override
public List<Books> listBookLikeName(String bookName) {
return bookMapper.listBookLikeName(bookName);
}
}
package com.example.controller;
import com.example.pojo.Books;
import com.example.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/book")
public class BookController {
// controller 調 service層
@Autowired
@Qualifier("bookServiceImpl")
private BookService bookService;
// 查詢全部書籍并且傳回到一個書籍展示頁面
@RequestMapping("/allBook")
public String list(Model model) {
List<Books> list = bookService.listBooks();
model.addAttribute("list", list);
return "allBook";
}
// 跳轉到增加書籍頁面
@RequestMapping("/toAddBook")
public String toAddPaper(){
return "addBook";
}
// 添加書籍的請求
@RequestMapping("/addBook")
public String addBook(Books books){
System.out.println("addBook =>" + books);
bookService.insertBook(books);
// 重定向到 @RequestMapping("/allBook")請求
return "redirect:/book/allBook";
}
// 跳轉到修改頁面
@RequestMapping("/toUpdate")
public String toUpdatePaper(int id, Model model){
Books bookById = bookService.getBookById(id);
model.addAttribute("getBookById", bookById);
return "updateBook";
}
// 修改書籍的請求
@RequestMapping("updateBook")
public String updataBook(Books books){
System.out.println("updateBook =>" + books);
bookService.updateBook(books);
return "redirect:/book/allBook";
}
// 删除書籍的請求
@RequestMapping("toDelete/{bookId}")
public String toDelete(@PathVariable("bookId") int id){
System.out.println("deleteBook =>" + bookService.getBookById(id));
bookService.deleteBookById(id);
return "redirect:/book/allBook";
}
// 查詢書籍
@RequestMapping("/queryBook")
public String queryBook(String queryBookName, Model model){
List<Books> booksList = bookService.listBookLikeName(queryBookName);
if (booksList.isEmpty()){
booksList = bookService.listBooks();
model.addAttribute("error", "未查詢到相關書籍!");
}
model.addAttribute("list", booksList );
return "allBook";
}
}
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>書籍展示</title>
<%-- BootStrap美化界面--%>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>書籍清單 —— 顯示所有書籍</small>
</h1>
</div>
</div>
<div class="row">
<div class="col-md-4 column">
<a class="btn btn-primary" href="${pageContext.request.contextPath}/book/allBook">顯示全部書籍</a>
<%-- 新增書籍--%>
<a class="btn btn-primary" href="${pageContext.request.contextPath}/book/toAddBook">新增書籍</a>
</div>
<div class="col-md-4 column"></div>
<div class="col-md-8 column">
<%-- 查詢書籍--%>
<form class="form-inline" action="${pageContext.request.contextPath}/book/queryBook" method="post" style="float: right">
<span style="color: red; font-weight: bold">${error} </span>
<label>
<input type="text" name="queryBookName" class="form-control" placeholder="請輸入要查詢的書籍名稱">
</label>
<button type="submit" class="btn btn-default">查詢</button>
</form>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>書籍編号</th>
<th>書籍名稱</th>
<th>書籍數量</th>
<th>書籍詳情</th>
<th>操作</th>
</tr>
</thead>
<%-- 書籍從資料庫中查詢出來 從list中周遊 foreach--%>
<tbody>
<c:forEach var="book" items="${list}">
<tr>
<td>${book.bookId}</td>
<td>${book.bookName}</td>
<td>${book.bookCounts}</td>
<td>${book.bookDetail}</td>
<td>
<a href="${pageContext.request.contextPath}/book/toUpdate/?id=${book.bookId}">修改</a>
|
<a href="${pageContext.request.contextPath}/book/toDelete/${book.bookId}">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
模糊查詢
✨防止 SQL 注入
當傳入參數為 Java or 1=1 時
Mapper中的SQL為
select * from ssm_build.books where book_name like '%${bookName}%'
通過Mybatis的日志可以發現dao層查詢到資料為0
之後 Controller
return "allBook";
再次進行查詢在頁面展示了所有書籍
Mybatis日志在 mybatis-config.xml 增加 setting即可開啟
<setting name="logImpl" value="STDOUT_LOGGING"/>
但是仍然可以通過前端閉合引号方式注入
例如當傳入參數為 'or 1=1 or' 時 可查詢到全部資料
更改Mapper中SQL如下可以防止SQL注入
<select id="listBookLikeName" resultType="books">
select * from ssm_build.books where book_name like "%"#{bookName}"%"
</select>
✨最終項目結構(SSM整合及相關功能實作)
✨參考及引用
SSM(SSM 架構集)_百度百科 (baidu.com)
【狂神說Java】SSM架構最新整合教學IDEA版_哔哩哔哩_bilibili
狂神說SpringMVC05:整合SSM架構 (qq.com)
⭐轉載請注明出處
本文作者:雙份濃縮馥芮白
原文連結:https://www.cnblogs.com/Flat-White/p/15219126.html
版權所有,如需轉載請注明出處。