contentFilters;
-
- public PostTitleContentFilterChain() {
- LocalTextContentFilter localTextContentFilter = new LocalTextContentFilter();
- RemoteTextContentFilter remoteTextContentFilter = new RemoteTextContentFilter();
- // 本地文本敏感词校验
- contentFilters.add(localTextContentFilter);
- // 第三方文本敏感词校验
- contentFilters.add(remoteTextContentFilter);
- }
-
- /**
- * 过滤标题
- *
- * @param post 帖子信息
- * @return true —— 通过,false —— 未通过
- */
- public boolean filterTitle(Post post) {
- for (ContentFilter contentFilter : contentFilters) {
- if (!contentFilter.filterContent(post.getTitle())) {
- return false;
- }
- }
- return true;
- }
-}
diff --git a/src/main/java/cn/allms/community/domain/service/contentfilter/RemoteTextContentFilter.java b/src/main/java/cn/allms/community/domain/service/contentfilter/RemoteTextContentFilter.java
deleted file mode 100644
index 7acf6eb..0000000
--- a/src/main/java/cn/allms/community/domain/service/contentfilter/RemoteTextContentFilter.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package cn.allms.community.domain.service.contentfilter;
-
-/**
- * 远程文本内容过滤器
- * @author xieYj
- * @date 2021/5/11 15:22
- */
-public class RemoteTextContentFilter extends TextContentFilter{
- @Override
- public boolean filterContent(Object object) {
- // TODO 需要调用第三方服务才能实现
- return false;
- }
-}
diff --git a/src/main/java/cn/allms/community/domain/service/contentfilter/TextContentFilter.java b/src/main/java/cn/allms/community/domain/service/contentfilter/TextContentFilter.java
deleted file mode 100644
index 83d7293..0000000
--- a/src/main/java/cn/allms/community/domain/service/contentfilter/TextContentFilter.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package cn.allms.community.domain.service.contentfilter;
-
-/**
- * 文本过滤器
- * @author xieYj
- * @date 2021/5/11 15:18
- */
-public abstract class TextContentFilter extends ContentFilter{
- /**
- * 文本过滤器,抽象
- * @param object 过滤对象
- * @return
- */
- @Override
- public abstract boolean filterContent(Object object);
-}
diff --git a/src/main/java/cn/allms/community/infrastructure/constant/CommonConstants.java b/src/main/java/cn/allms/community/infrastructure/constant/CommonConstants.java
deleted file mode 100644
index 4332c68..0000000
--- a/src/main/java/cn/allms/community/infrastructure/constant/CommonConstants.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package cn.allms.community.infrastructure.constant;
-
-/**
- * 公共常量
- * @author xieYj
- * @date 2021/5/11 14:56
- */
-public interface CommonConstants {
- String TOPIC_SPLIT_COMMA = ",";
-}
diff --git a/src/main/java/cn/allms/community/infrastructure/constant/ExceptionCodeConstant.java b/src/main/java/cn/allms/community/infrastructure/constant/ExceptionCodeConstant.java
deleted file mode 100644
index 6b0abad..0000000
--- a/src/main/java/cn/allms/community/infrastructure/constant/ExceptionCodeConstant.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package cn.allms.community.infrastructure.constant;
-
-/**
- * 异常码状态常量
- *
- * @author xieYj
- * @date 2021/5/11 14:17
- */
-public interface ExceptionCodeConstant {
- String POST_SOURCE_CONTENT_AT_LEAST_SIXTEEN_WORDS = "2001";
- String ONE_POST_MOST_JOIN_INTO_FIVE_TOPICS = "2002";
-}
diff --git a/src/main/java/cn/allms/community/infrastructure/exception/BusinessException.java b/src/main/java/cn/allms/community/infrastructure/exception/BusinessException.java
deleted file mode 100644
index 4c41736..0000000
--- a/src/main/java/cn/allms/community/infrastructure/exception/BusinessException.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package cn.allms.community.infrastructure.exception;
-
-/**
- * @author xieYj
- * @date 2021/5/11 13:59
- */
-public class BusinessException extends Exception {
- /**
- * 业务异常码
- */
- private String code;
- /**
- * 业务异常参数
- */
- private Object[] arguments;
-
- public BusinessException() {
- super();
- }
-
- public BusinessException(Throwable cause) {
- super(cause);
- }
-
- public BusinessException(String message) {
- super(message);
- }
-
- public BusinessException(String code, String message) {
- super(message);
- this.code = code;
- }
-
- public BusinessException(String message, Object[] arguments) {
- super(message);
- this.arguments = arguments;
- }
-
- public BusinessException(String code, String message, Object[] arguments) {
- super(message);
- this.code = code;
- this.arguments = arguments;
- }
-
- public BusinessException(String message, Object[] arguments, Throwable cause) {
- super(message, cause);
- this.arguments = arguments;
- }
-
- public BusinessException(String code, String message, Object[] arguments, Throwable cause) {
- super(message, cause);
- this.code = code;
- this.arguments = arguments;
- }
-
- public BusinessException(String message, Throwable cause) {
- super(message, cause);
- }
-
-
- public BusinessException(String code, String message, Throwable cause) {
- super(message, cause);
- this.code = code;
- }
-
-
- public BusinessException(String message,
- Throwable cause,
- boolean enableSuppression,
- boolean writableStackTrace) {
- super(message, cause, enableSuppression, writableStackTrace);
- }
-
-
- public BusinessException(String code,
- String message,
- Throwable cause,
- boolean enableSuppression,
- boolean writableStackTrace) {
- super(message, cause, enableSuppression, writableStackTrace);
- this.code = code;
- }
-
-}
diff --git a/src/main/java/com/example/demorest/DemoRestApplication.java b/src/main/java/com/example/demorest/DemoRestApplication.java
new file mode 100644
index 0000000..edf18ce
--- /dev/null
+++ b/src/main/java/com/example/demorest/DemoRestApplication.java
@@ -0,0 +1,16 @@
+package com.example.demorest;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @author josxy
+ */
+@SpringBootApplication
+public class DemoRestApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(DemoRestApplication.class, args);
+ }
+
+}
diff --git a/src/main/java/com/example/demorest/controller/BookController.java b/src/main/java/com/example/demorest/controller/BookController.java
new file mode 100644
index 0000000..cedfa8b
--- /dev/null
+++ b/src/main/java/com/example/demorest/controller/BookController.java
@@ -0,0 +1,164 @@
+package com.example.demorest.controller;
+
+import com.example.demorest.entity.Book;
+import com.example.demorest.exception.InvalidRequestException;
+import com.example.demorest.exception.ResourceNoFoundException;
+import com.example.demorest.repository.BookRepository;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.BeanWrapper;
+import org.springframework.beans.BeanWrapperImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.beans.PropertyDescriptor;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * rest 风格 api
+ *
+ * GET /api/v1/books 所有书单
+ * GET /api/v1/books/{id} 获取一条书单
+ * POST /api/v1/books 新建一条书单
+ * PUT /api/v1/books/{id} 更新一条书单,提供全部信息
+ * PATCH /api/v1/books/{id} 更新一条书单,提供部分信息
+ * DELETE /api/v1/books/{id} 删除一条书单
+ * DELETE /API/v1/books 删除所有书单
+ *
+ * @author Echo
+ * @version 1.0
+ * @date 2019-01-05 21:59
+ */
+@RestController
+@RequestMapping("/v1")
+public class BookController {
+ private final BookRepository bookRepository;
+
+ @Autowired
+ public BookController(BookRepository bookRepository) {
+ this.bookRepository = bookRepository;
+ }
+
+ /**
+ * 获取所有书单
+ * GET /api/v1/books 所有书单
+ *
+ * @return http 响应
+ */
+ @GetMapping("/books")
+ public HttpEntity> books() {
+ return new ResponseEntity<>(bookRepository.findAll(), HttpStatus.OK);
+ }
+
+ /**
+ * 获取一个书单 * GET /api/v1/books/{id} 获取一条书单 * * @param id id
+ *
+ * @return http 响应
+ */
+ @GetMapping("/books/{id}")
+ public HttpEntity> booksOne(@PathVariable Long id) {
+ return new ResponseEntity<>(bookRepository.findById(id).orElseThrow(() ->
+ new ResourceNoFoundException(String.format("Book by id %s not found!", id))),
+ HttpStatus.OK);
+ }
+
+ /**
+ * 添加一个书单
+ * POST /api/v1/books 新建一条书单
+ *
+ * @param book 书单
+ * @return http 响应
+ */
+ @PostMapping("/books")
+ public HttpEntity> booksAdd(@Valid @RequestBody Book book, BindingResult bindingResult) {
+ if (bindingResult.hasErrors()) {
+ throw new InvalidRequestException("Invalid parameter", bindingResult);
+ }
+ return new ResponseEntity<>(bookRepository.save(book), HttpStatus.CREATED);
+ }
+
+ /**
+ * 更新一个书单,提供一个书单的全部信息
+ * PUT /api/v1/books/{id} 更新一条书单,提供全部信息
+ *
+ * @param id 更新的id
+ * @param book 更新后的书单
+ * @return http 响应
+ */
+ @PutMapping("/books/{id}")
+ public HttpEntity> booksPut(@Valid @PathVariable Long id, @RequestBody Book book, BindingResult bindingResult) {
+ Book exist = bookRepository.findById(id).orElseThrow(() ->
+ new ResourceNoFoundException(String.format("Book by id %s not found!", id)));
+ if (bindingResult.hasErrors()) {
+ throw new InvalidRequestException("Invalid parameter", bindingResult);
+ }
+ book.setId(exist.getId());
+ return new ResponseEntity<>(bookRepository.save(book), HttpStatus.OK);
+ }
+
+ /**
+ * 更新一个书单,提供一个书单的部分信息
+ * PATCH /api/v1/books/{id} 更新一条书单,提供部分信息
+ *
+ * @param id 更新的id
+ * @param book 更新后的书单
+ * @return http 响应
+ */
+ @PatchMapping("/books/{id}")
+ public HttpEntity> booksPatch(@PathVariable Long id, @RequestBody Book book) {
+ Book exist = bookRepository.findById(id).orElseThrow(() ->
+ new ResourceNoFoundException(String.format("Book by id %s not found!", id)));
+ BeanWrapper beanWrapper = new BeanWrapperImpl(book);
+ PropertyDescriptor[] propertyDescriptors = beanWrapper.getPropertyDescriptors();
+ List nullPropertyNames = new ArrayList<>();
+ for (PropertyDescriptor pd :
+ propertyDescriptors) {
+ if (beanWrapper.getPropertyValue(pd.getName()) == null) {
+ nullPropertyNames.add(pd.getName());
+ }
+ }
+ BeanUtils.copyProperties(book, exist, nullPropertyNames.toArray(new String[nullPropertyNames.size()]));
+ return new ResponseEntity<>(bookRepository.save(exist), HttpStatus.OK);
+ }
+
+ /**
+ * 删除一个书单
+ * DELETE /api/v1/books/{id} 删除一条书单
+ *
+ * @param id id
+ * @return http 响应
+ */
+ @DeleteMapping("/books/{id}")
+ public HttpEntity> booksDeleteOne(@PathVariable Long id) {
+ Book exist = bookRepository.findById(id).orElseThrow(() ->
+ new ResourceNoFoundException(String.format("Book by id %s not found!", id)));
+ bookRepository.deleteById(exist.getId());
+ return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+ }
+
+ /**
+ * 删除所有书单
+ * DELETE /API/v1/books 删除所有书单
+ *
+ * @return http 响应
+ */
+ @DeleteMapping("/books")
+ public HttpEntity> booksDeleteAll() {
+ List books = bookRepository.findAll();
+ if (books.isEmpty()) {
+ throw new ResourceNoFoundException("Not found books!");
+ }
+ bookRepository.deleteAll();
+ return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+ }
+}
diff --git a/src/main/java/com/example/demorest/entity/Book.java b/src/main/java/com/example/demorest/entity/Book.java
new file mode 100644
index 0000000..0830cd8
--- /dev/null
+++ b/src/main/java/com/example/demorest/entity/Book.java
@@ -0,0 +1,47 @@
+package com.example.demorest.entity;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+import org.hibernate.annotations.ColumnDefault;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.validation.constraints.Digits;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 书单对象
+ * @author xieYj
+ * @date 2021/5/12 13:57
+ */
+@Entity
+@Data
+public class Book {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(insertable = false, length = 20, nullable = false)
+ private Long id;
+
+ @NotBlank(message = "书名不能为空")
+ @Column(columnDefinition = "varchar(50) comment '书名'")
+ private String name;
+
+ @NotBlank(message = "作者不能为空")
+ @Column(columnDefinition = "varchar(25) comment '作者'")
+ private String author;
+
+ @Column(columnDefinition = "varchar(255) comment '描述'")
+ public String description;
+
+ /**
+ * status 非空
+ */
+ @NotNull(message = "status 不能为空")
+ @ColumnDefault("1")
+ @Column(columnDefinition = "tinyint(1) comment '是否存在,false|0不存在,true|1已存在'")
+ public Boolean status;
+}
diff --git a/src/main/java/com/example/demorest/exception/InvalidRequestException.java b/src/main/java/com/example/demorest/exception/InvalidRequestException.java
new file mode 100644
index 0000000..da82b16
--- /dev/null
+++ b/src/main/java/com/example/demorest/exception/InvalidRequestException.java
@@ -0,0 +1,24 @@
+package com.example.demorest.exception;
+
+import lombok.Getter;
+import org.springframework.validation.Errors;
+
+/**
+ * 无效的参数请求异常
+ *
+ * @author xieYj
+ * @date 2021/5/12 16:22
+ */
+public class InvalidRequestException extends RuntimeException {
+ @Getter
+ private Errors errors;
+
+ public InvalidRequestException(String message, Errors errors) {
+ super(message);
+ this.errors = errors;
+ }
+
+ public InvalidRequestException(Errors errors) {
+ this.errors = errors;
+ }
+}
diff --git a/src/main/java/com/example/demorest/exception/ResourceNoFoundException.java b/src/main/java/com/example/demorest/exception/ResourceNoFoundException.java
new file mode 100644
index 0000000..f81db54
--- /dev/null
+++ b/src/main/java/com/example/demorest/exception/ResourceNoFoundException.java
@@ -0,0 +1,13 @@
+package com.example.demorest.exception;
+
+/**
+ * 资源找不到异常
+ *
+ * @author xieYj
+ * @date 2021/5/12 16:24
+ */
+public class ResourceNoFoundException extends RuntimeException {
+ public ResourceNoFoundException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/com/example/demorest/handle/ApiExceptionHandler.java b/src/main/java/com/example/demorest/handle/ApiExceptionHandler.java
new file mode 100644
index 0000000..92143b7
--- /dev/null
+++ b/src/main/java/com/example/demorest/handle/ApiExceptionHandler.java
@@ -0,0 +1,63 @@
+package com.example.demorest.handle;
+
+import com.example.demorest.exception.InvalidRequestException;
+import com.example.demorest.exception.ResourceNoFoundException;
+import com.example.demorest.resource.ErrorResource;
+import com.example.demorest.resource.FieldResource;
+import com.example.demorest.resource.InvalidErrorResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.Errors;
+import org.springframework.validation.FieldError;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 书单API全局异常处理
+ *
+ * @author xieYj
+ * @date 2021/5/12 16:31
+ */
+@RestControllerAdvice(basePackages = "com.example.demorest.controller")
+public class ApiExceptionHandler {
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ @ExceptionHandler(ResourceNoFoundException.class)
+ public HttpEntity> handleNotFound(ResourceNoFoundException e) {
+ ErrorResource errorResource = new ErrorResource(e.getMessage());
+ logger.error(errorResource.toString());
+ return new ResponseEntity<>(errorResource, HttpStatus.NOT_FOUND);
+ }
+
+ @ExceptionHandler(InvalidRequestException.class)
+ public HttpEntity> handleInvalidRequest(InvalidRequestException e) {
+ Errors errors = e.getErrors();
+ List fieldResources = new ArrayList<>();
+ List fieldErrors = errors.getFieldErrors();
+ for (FieldError fieldError : fieldErrors) {
+ fieldResources.add(
+ new FieldResource(fieldError.getObjectName(),
+ fieldError.getField(),
+ fieldError.getCode(),
+ fieldError.getDefaultMessage())
+ );
+ }
+ InvalidErrorResource invalidErrorResource = new InvalidErrorResource(e.getMessage(), fieldResources);
+ logger.error(invalidErrorResource.toString());
+ return new ResponseEntity<>(invalidErrorResource, HttpStatus.BAD_REQUEST);
+ }
+
+
+ @ExceptionHandler(Exception.class)
+ public HttpEntity> handleException(Exception e) {
+ logger.error(e.getMessage());
+ return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+}
diff --git a/src/main/java/com/example/demorest/repository/BookRepository.java b/src/main/java/com/example/demorest/repository/BookRepository.java
new file mode 100644
index 0000000..1d510d1
--- /dev/null
+++ b/src/main/java/com/example/demorest/repository/BookRepository.java
@@ -0,0 +1,15 @@
+package com.example.demorest.repository;
+
+import com.example.demorest.entity.Book;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * 书单仓储层,jpa实现
+ * @author xieYj
+ * @date 2021/5/12 15:19
+ */
+@Repository
+public interface BookRepository extends JpaRepository {
+
+}
diff --git a/src/main/java/com/example/demorest/resource/ErrorResource.java b/src/main/java/com/example/demorest/resource/ErrorResource.java
new file mode 100644
index 0000000..f9dbe2b
--- /dev/null
+++ b/src/main/java/com/example/demorest/resource/ErrorResource.java
@@ -0,0 +1,20 @@
+package com.example.demorest.resource;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+/**
+ * 资源错误
+ *
+ * @author xieYj
+ * @date 2021/5/12 16:27
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+@ToString
+@Getter
+public class ErrorResource {
+ private String message;
+}
diff --git a/src/main/java/com/example/demorest/resource/FieldResource.java b/src/main/java/com/example/demorest/resource/FieldResource.java
new file mode 100644
index 0000000..a6cc093
--- /dev/null
+++ b/src/main/java/com/example/demorest/resource/FieldResource.java
@@ -0,0 +1,34 @@
+package com.example.demorest.resource;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+/**
+ * 字段错误
+ *
+ * @author josxy
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+@ToString
+@Getter
+public class FieldResource {
+ /**
+ * 实体对象
+ */
+ private String resource;
+ /**
+ * 字段
+ */
+ private String field;
+ /**
+ * 代码
+ */
+ private String code;
+ /**
+ * 具体信息
+ */
+ private String message;
+}
diff --git a/src/main/java/com/example/demorest/resource/InvalidErrorResource.java b/src/main/java/com/example/demorest/resource/InvalidErrorResource.java
new file mode 100644
index 0000000..9eb0335
--- /dev/null
+++ b/src/main/java/com/example/demorest/resource/InvalidErrorResource.java
@@ -0,0 +1,20 @@
+package com.example.demorest.resource;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+/**
+ * 资源错误信息封装
+ * @author xieYj
+ * @date 2021/5/12 16:29
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+@ToString
+@Getter
+public class InvalidErrorResource {
+ private String message;
+ private Object errors;
+}
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
index e558821..dc3d7b8 100644
--- a/src/main/resources/application-dev.yml
+++ b/src/main/resources/application-dev.yml
@@ -1,4 +1,21 @@
+spring:
+ application:
+ name: restful-api
+ datasource:
+ url: jdbc:p6spy:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8&useSSL=false
+ username: root
+ password: 123456
+ platform: mysql
+ driver-class-name: com.p6spy.engine.spy.P6SpyDriver
+ jpa:
+ # 关闭jpa自带的show sql
+ show-sql: false
+ open-in-view: false
+ #加上这句会执行import.sql
+ generate-ddl: true
+ hibernate:
+ ddl-auto: create
server:
- port: 9420
servlet:
context-path: /api
+ port: 8001
diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml
new file mode 100644
index 0000000..7ccc0b1
--- /dev/null
+++ b/src/main/resources/application-prod.yml
@@ -0,0 +1,19 @@
+spring:
+ application:
+ name: restful-api
+ datasource:
+ url: jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=utf-8&useSSL=false
+ username: root
+ password: 123456
+ platform: mysql
+ jpa:
+ show-sql: false
+ open-in-view: false
+ #加上这句会执行import.sql
+ generate-ddl: false
+ hibernate:
+ ddl-auto: update
+server:
+ servlet:
+ context-path: /api
+ port: 8001
diff --git a/src/main/resources/application-release.yml b/src/main/resources/application-release.yml
deleted file mode 100644
index 256cb23..0000000
--- a/src/main/resources/application-release.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-server:
- port: 9420
- servlet:
- context-path: /server
diff --git a/src/main/resources/import.sql b/src/main/resources/import.sql
new file mode 100644
index 0000000..fd6d1d5
--- /dev/null
+++ b/src/main/resources/import.sql
@@ -0,0 +1,24 @@
+INSERT INTO spring.book (id, author, description, name, status) VALUES (1, '孟宁', '本书从理解计算机硬件的核心工作机制(存储程序计算机和函数调用堆栈)和用户态程序如何通过系统调用陷入内核(中断异常)入手,通过上下两个方向双向夹击的策略,并利用实际可运行程序的反汇编代码从实践的角度理解操作系统内核,分析Linux内核源代码,从系统调用陷入内核、进程调度与进程切换开始,最后返回到用户态进程。', '庖丁解牛Linux内核分析', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (2, '孙亮', '大数据时代为机器学习的应用提供了广阔的空间,各行各业涉及数据分析的工作都需要使用机器学习算法。本书围绕实际数据分析的流程展开,着重介绍数据探索、数据预处理和常用的机器学习算法模型。本书从解决实际问题的角度出发,介绍回归算法、分类算法、推荐算法、排序算法和集成学习算法。在介绍每种机器学习算法模型时,书中不但阐述基本原理,而且讨论模型的评价与选择。为方便读者学习各种算法,本书介绍了R语言中相应的软件包并给出了示例程序。', '实用机器学习', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (3, '托马斯·哈斯尔万特', '本书以基础的统计学知识和假设检验为重点,简明扼要地讲述了Python在数据分析、可视化和统计建模中的应用。主要包括Python的简单介绍、研究设计、数据管理、概率分布、不同数据类型的假设检验、广义线性模型、生存分析和贝叶斯统计学等从入门到高级的内容。', 'Python统计分析', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (4, '甘迪文', '《Windows黑客编程技术详解》介绍的是黑客编程的基础技术,涉及用户层下的Windows编程和内核层下的Rootkit编程。本书分为用户篇和内核篇两部分,用户篇包括11章,配套49个示例程序源码;内核篇包括7章,配套28个示例程序源码。本书介绍的每个技术都有详细的实现原理,以及对应的示例代码(配套代码均支持32位和64位Windows 7、Windows 8.1及Windows 10系统),旨在帮助初学者建立起黑客编程技术的基础。', 'Windows黑客编程技术详解', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (5, '科里•奥尔索夫', '本书作者是一名自学成才的程序员,经过一年的自学,掌握了编程技能并在eBay找到了一份软件工程师的工作。本书是作者结合个人经验写作而成,旨在帮助读者从外行成长为一名专业的Python程序员。', 'Python编程无师自通——专业程序员的养成', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (6, '威廉·史密斯', '本书由浅入深地详细讲解了计算机存储使用的多种数据结构。本书首先讲解了初级的数据结构(如表、栈、队列和堆等),具体包括它们的工作原理、功能实现以及典型的应用程序等;然后讨论了数据结构,如泛型集合、排序、搜索和递归等;最后介绍了如何在日常应用中使用这些数据结构。', '程序员学数据结构', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (7, '张鑫旭', '本书从前端开发人员的需求出发,以“流”为线索,从结构、内容到美化装饰等方面,全面且深入地讲解前端开发人员必须了解和掌握的大量的CSS知识点。同时,作者结合多年的从业经验,通过大量的实战案例,详尽解析CSS的相关知识与常见问题。作者还为本书开发了专门的配套网站,进行实例展示、问题答疑。', 'CSS世界', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (8, '理查德·格里姆斯', '作为一门广为人知的编程语言,C++已经诞生30多年了,这期间也出现并流行过许多种编程语言,但是C++是经得起考验的。如此经典的编程语言,值得每一位编程领域的新人认真学习,也适合有经验的程序员细细品味。', 'C++编程自学宝典', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (9, '萨沙·戈德斯汀', '本书详细解释了影响应用程序性能的Windows、CLR和物理硬件的内部结构,并为读者提供了衡量代码如何独立于外部因素执行操作的知识和工具。书中提供了大量的C#代码示例和技巧,将帮助读者zui大限度地提高算法和应用程序的性能,提高个人竞争优势,使用更低的成本获取更多的用户。', '.NET性能优化', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (10, '李伟', '《C++模板元编程实战:一个深度学习框架的初步实现》以一个深度学习框架的初步实现为例,讨论如何在一个相对较大的项目中深入应用元编程,为系统性能优化提供更多的可能。', 'C++模板元编程实战:一个深度学习框架的初步实现', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (11, 'Ben Klemens 克莱蒙', '本书展现了传统C语言教科书所不具有相关技术。全书分', 'C程序设计新思维(第2版)', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (12, '王云', '本书遵循由浅入深、循序渐进的原则,讲解单片机开发经典案例。本书以YL51单片机开发板为平台,通过案例逐个讲解开发板上各个器件模块的使用及其编程方法,包括单片机最小系统、数码管显示原理、中断与定时器、数模\\模数转换工作原理、LCD液晶显示、串行口通信、步进电机驱动原理、PWM脉宽调制与直流电机等内容。', '51单片机C语言程序设计教程', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (13, '胡振波', '本书是一本介绍通用CPU设计的入门书,以通俗的语言系统介绍了CPU和RISC-V架构,力求为读者揭开CPU设计的神秘面纱,打开计算机体系结构的大门。', '手把手教你设计CPU——RISC-V处理器篇', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (14, '克劳斯·福勒', '本书旨在通过实际的Python 3.0代码示例展示Python与数学应用程序的紧密联系,介绍将Python中的各种概念用于科学计算的方法。', 'Python 3.0科学计算指南', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (15, '路彦雄', '《文本上的算法 深入浅出自然语言处理》结合-作者多年学习和从事自然语言处理相关工作的经验,力图用生动形象的方式深入浅出地介绍自然语言处理的理论、方法和技术。本书抛弃掉繁琐的证明,提取出算法的核心,帮助读者尽快地掌握自然语言处理所必需的知识和技能。', '文本上的算法——深入浅出自然语言处理', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (16, '胡世杰', '本书从云存储的需求出发讲述对象存储的原理,循序渐进地建立起一个分布式对象存储的架构,并且将软件实现出来。全书共8章,分别涉及对象存储简介、可扩展分布式系统、元数据服务、数据校验和去重、数据冗余处理、断点续传、数据压缩和数据维护等。本书选择用来实现分布式对象存储软件的编程语言是当前流行的Go语言。', '分布式对象存储——原理、架构及Go语言实现', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (17, '徐子珊', '《趣题学算法》适于作为程序员的参考书,高校各专业学生学习“数据结构”“算法设计分析”“程序设计”等课程的扩展读物,也可以作为上述课程的实验或课程设计的材料,还可以作为准备参加国内或国际程序设计赛事的读者的赛前训练材料。', '趣题学算法', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (18, '鲁什迪·夏姆斯', '现如今,数据科学已经成为一个热门的技术领域,它涵盖了人工智能的各个方面,例如数据处理、信息检索、机器学习、自然语言处理、数据可视化等。而Java作为一门经典的编程语言,在数据科学领域也有着杰出的表现。', 'Java数据科学指南', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (19, '罗炳森', '结构化查询语言(Structured Query Language,SQL)是一种功能强大的数据库语言。它基于关系代数运算,功能丰富、语言简洁、使用方便灵活,已成为关系数据库的标准语言。', 'SQL优化核心思想', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (20, '弗兰克·D.卢娜', 'Direct3D是微软公司DirectX SDK集成开发包中的重要组成部分,是编写高性能3D图形应用程序的渲染库,适用于多媒体、娱乐、即时3D动画等广泛和实用的3D图形计算领域。', 'DirectX 12 3D 游戏开发实战', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (21, '巴阿尔丁•阿扎米', 'Kibana是广泛地应用在数据检索和数据可视化领域的ELK中的一员。本书专门介绍Kibana,通过不同的用例场景,带领读者全面体验Kibana的可视化功能。', 'Kibana数据可视化', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (22, '郝佳', '《Spring源码深度解析(第2版)》从核心实现、企业应用和Spring Boot这3个方面,由浅入深、由易到难地对Spring源码展开了系统的讲解,包括Spring 整体架构和环境搭建、容器的基本实现、默认标签的解析、自定义标签的解析、bean的加载、容器的功能扩展、AOP、数据库连接JDBC、整合MyBatis、事务、SpringMVC、远程服务、Spring消息、Spring Boot体系原理等内容。', 'Spring源码深度解析(第2版)', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (23, 'Jon Bentley', '书的内容围绕程序设计人员面对的一系列实际问题展开。作者JonBentley以其独有的洞察力和创造力,引导读者理解这些问题并学会解决方法,而这些正是程序员实际编程生涯中到关重要的。', '编程珠玑(第2版•修订版)', 1);
+INSERT INTO spring.book (id, author, description, name, status) VALUES (24, 'Mickey W. Mantle', '这是一本系统阐述面对混乱而容易失控的技术开发团队时,如何管理、建设和强化团队,成功交付开发成果的大作。两位作者Mickey W. Mantle和Ron Lichty以合起来近70年的开发管理经验为基础,通过深刻的观察和分析,找到了软件开发管理的核心问题——人的管理,并围绕如何真正理解程序员、找到合适的程序员、与程序员沟通这几个核心话题,一步步展开,扩展到如何以人为本地进行团队建设、管理和项目管理。', '告别失控:软件开发团队管理必读', 1);
diff --git a/src/main/resources/spy.properties b/src/main/resources/spy.properties
new file mode 100644
index 0000000..9a6af54
--- /dev/null
+++ b/src/main/resources/spy.properties
@@ -0,0 +1,10 @@
+driverlist=com.mysql.cj.jdbc.Driver
+module.log=com.p6spy.engine.logging.P6LogFactory
+appender=com.p6spy.engine.spy.appender.Slf4JLogger
+#自定义日志格式
+logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat
+#格式:%(currentTime)|%(executionTime)|%(category)|connection%(connectionId)|%(sqlSingleLine)
+customLogMessageFormat=%(category)|conn%(connectionId)|%(sqlSingleLine)
+databaseDialectDateFormat=yyyy-MM-dd HH:mm:ss
+databaseDialectTimestampFormat=yyyy-MM-dd HH:mm:ss
+dateformat=yyyy-MM-dd HH:mm:ss
diff --git a/src/test/java/cn/allms/community/MxCommunityApplicationTests.java b/src/test/java/com/example/demorest/DemoRestApplicationTests.java
similarity index 52%
rename from src/test/java/cn/allms/community/MxCommunityApplicationTests.java
rename to src/test/java/com/example/demorest/DemoRestApplicationTests.java
index 0a1e495..8e44d1c 100644
--- a/src/test/java/cn/allms/community/MxCommunityApplicationTests.java
+++ b/src/test/java/com/example/demorest/DemoRestApplicationTests.java
@@ -1,13 +1,13 @@
-package cn.allms.community;
+package com.example.demorest;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
-class MxCommunityApplicationTests {
+class DemoRestApplicationTests {
- @Test
- void contextLoads() {
- }
+ @Test
+ void contextLoads() {
+ }
}