【全栈开发】从0开始搭建一个图书管理系统【一】框架搭建
前言
现在流行降本增笑,也就是不但每个人都要有事干不能闲着,更重要的是每个人都要通过报功的方式做到平日的各项工作异常饱和,实现1.5人的支出干2人的活计。单纯的数据库开发【肤浅的Sql Boy】竞争异常激烈早就内卷的吃不饱饭了,而随着各家云厂商的倒贴钱推动上云计算资质不那么聪颖的大数据平台开发人员也岌岌可危,前端早就没有单独的岗位了,也就剩纯后端开发还能喝口汤,再加上近期DeepSeek
等工具的流行,只能干单一工作的单细胞人员好日子还在后头。。。
历史的车轮总是滚滚向前,科学技术的进步是领导阶级们的红利不是普通员工的。。。这就要求普通员工们看清形势放弃幻想,加强自我学习实现与时俱进,能胜任至少2个工种,才能不被K8S
是常识且DevOPs
盛行的行业淘汰。
笔者将以图书管理系统
抛砖引玉,展示大数据平台开发学徒工们需要的后端及前端能力【不要问我为神马是图书管理系统
,有的业务不能讲的太明白!!!】。2025年,一个精通大数据平台开发及数仓开发,精通离线跑批脚本性能调优,可兼任后端开发、简单的前端开发、压力/功能/接口测试的资深大数据学徒工,20K以内还是没那么艰难的。
选型
现在绝大多数项目已经不搞传统C/S了,清一色B/S,Spring
已经成为事实上的标准,大数据平台开发学徒工普遍有Java SE
基础,故笔者以Spring Boot3
+Vue3
为主要框架进行开发。那么很多组件的选择也就是不必解释的常识了:
JDK:>=17
ORM:MyBatis/MyBatis-plus
DB:MySQL>=8/MariaDB
安全:Spring Security
调度:XXL Job
如果规模体量变大,需要改微服务及容器编排,那就是另一回事了。。。缺失的依赖可以后续慢慢集成,大家都是资深学徒工了要有触类旁通的悟性。
初始化SpringBoot3
构建后端首先要到官网查看下最新版本及推荐版本:
https://start.spring.io/
截至20250220,推荐的是3.4.2。
可以在这里选择要集成的依赖,也可以后续自行修改pom.xml
。笔者选择一个比较稳定的LTS版本。
生成后导入,配置基本的Maven,等待拉取基础的依赖。
依赖POM
经过了好久的排错,终于选好了兼容的依赖版本,真是不容易。。。
主POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><modules><module>library-admin</module><module>library-common</module><module>library-logging</module><module>library-system</module></modules><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.2</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.zhiyong</groupId><artifactId>library</artifactId><version>0.0.1-SNAPSHOT</version><name>library</name><description>Demo project for Spring Boot3</description><url/><licenses><license/></licenses><developers><developer/></developers><scm><connection/><developerConnection/><tag/><url/></scm><properties><java.version>17</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><maven.test.skip>true</maven.test.skip><fastjson.version>1.2.83</fastjson.version><log4j2.version>2.20.0</log4j2.version><disruptor.version>3.4.2</disruptor.version><mybatis-plus.version>3.5.10</mybatis-plus.version><druid.version>1.2.23</druid.version><mysql-connector.version>8.0.33</mysql-connector.version><hutool.version>5.8.11</hutool.version><mapstruct.version>1.5.5.Final</mapstruct.version><xxl.job.version>2.4.0</xxl.job.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-autoconfigure</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>${log4j2.version}</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>${log4j2.version}</version></dependency><dependency><groupId>com.lmax</groupId><artifactId>disruptor</artifactId><version>${disruptor.version}</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version><exclusions><exclusion><artifactId>mybatis-spring</artifactId><groupId>org.mybatis</groupId></exclusion></exclusions></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-jsqlparser</artifactId><version>${mybatis-plus.version}</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>3.0.4</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-extension</artifactId><version>${mybatis-plus.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency><dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct</artifactId><version>${mapstruct.version}</version></dependency><dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>${mapstruct.version}</version><scope>provided</scope></dependency><dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>${xxl.job.version}</version></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>com.zhiyong</groupId><artifactId>library-admin</artifactId><version>${version}</version></dependency><dependency><groupId>com.zhiyong</groupId><artifactId>library-common</artifactId><version>${version}</version></dependency><dependency><groupId>com.zhiyong</groupId><artifactId>library-system</artifactId><version>${version}</version></dependency><dependency><groupId>com.zhiyong</groupId><artifactId>library-logging</artifactId><version>${version}</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-3-starter</artifactId><version>${druid.version}</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-j</artifactId><version>${mysql-connector.version}</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>${hutool.version}</version></dependency></dependencies></dependencyManagement></project>
也就是说子模块有4个:
library-admin
library-common
library-logging
library-system
不懂的可以参照若依
。。。
library-admin
这部分主要是放置启动类、打包配置、主要的业务VO等。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>library</artifactId><groupId>com.zhiyong</groupId><version>0.0.1-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>library-admin</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties><dependencies><dependency><groupId>com.zhiyong</groupId><artifactId>library-common</artifactId></dependency><dependency><groupId>com.zhiyong</groupId><artifactId>library-system</artifactId></dependency><dependency><groupId>com.zhiyong</groupId><artifactId>library-logging</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><dependency><groupId>cn.xuyanwu</groupId><artifactId>spring-file-storage</artifactId><version>1.0.3</version><scope>compile</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-3-starter</artifactId></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-core</artifactId></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-web</artifactId></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId></dependency></dependencies><profiles><profile><id>dev</id><properties><package.environment>dev</package.environment></properties><activation><activeByDefault>true</activeByDefault></activation></profile><profile><id>test</id><properties><package.environment>test</package.environment></properties></profile><profile><id>prod</id><properties><package.environment>prod</package.environment></properties></profile></profiles><build><finalName>library-spring-boot3</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><finalName>${project.build.finalName}-${project.version}</finalName></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals><configuration><outputDirectory>ci</outputDirectory><executable>true</executable></configuration></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><configuration><skipTests>true</skipTests></configuration></plugin></plugins></build></project>
这样后续就会打出Jar
包而不是传统的War
包。容器化部署时要更方便些。它要依赖其它所有子模块!!!
library-common
这里主要是放公用的工具类、全局异常/自定义异常类等,以便别的模块复用:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>library</artifactId><groupId>com.zhiyong</groupId><version>0.0.1-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>library-common</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties><dependencies><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-3-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><dependency><groupId>com.aliyun</groupId><artifactId>dysmsapi20170525</artifactId><version>2.0.24</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>18.0</version></dependency><dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId><version>1.6.2</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency><dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.4.0</version></dependency><dependency><groupId>nl.basjes.parse.useragent</groupId><artifactId>yauaa</artifactId><version>6.11</version></dependency></dependencies></project>
这样就搭建好了一个常见的公用模块依赖。它无需依赖其它子模块,但是其它子模块都要依赖它。
library-logging
这个模块主要记录系统的日志:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>library</artifactId><groupId>com.zhiyong</groupId><version>0.0.1-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>library-logging</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties><dependencies><dependency><groupId>com.zhiyong</groupId><artifactId>library-common</artifactId></dependency></dependencies></project>
依赖公用的子模块即可。
library-system
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>library</artifactId><groupId>com.zhiyong</groupId><version>0.0.1-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>library-system</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties><dependencies><dependency><groupId>com.zhiyong</groupId><artifactId>library-common</artifactId></dependency><dependency><groupId>com.zhiyong</groupId><artifactId>library-logging</artifactId></dependency><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.5.5</version></dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.9.0</version></dependency><dependency><groupId>cn.xuyanwu</groupId><artifactId>spring-file-storage</artifactId><version>1.0.3</version></dependency><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.16.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency></dependencies></project>
这里放一些系统功能。
主模块
Main入口
调整到library-admin
模块下:
package com.zhiyong.admin;import cn.xuyanwu.spring.file.storage.spring.EnableFileStorage;
import com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceAutoConfigure;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication(scanBasePackages = {"com.zhiyong.*"})
@MapperScan("com.zhiyong.**.mapper")
@EnableFileStorage
//@EnableAutoConfiguration(exclude={DruidDataSourceAutoConfigure.class})
public class LibraryApplication {public static void main(String[] args) {SpringApplication.run(LibraryApplication.class, args);}}
主配置文件
spring:application:name: libraryprofiles:active: devservlet:multipart:enabled: truemax-file-size: 50MBmax-request-size: 50MBmvc:hiddenmethod:filter:enabled: truejackson:time-zone: GMT+8date-format: yyyy-MM-dd HH:mm:ssserver:servlet:context-path: '/api/library'mybatis-plus:global-config:banner: falsedb-config:id-type: autotable-underline: truemapper-locations: classpath:mapper/*.xmlconfiguration:use-generated-keys: truelog-impl: org.apache.ibatis.logging.stdout.StdOutImplcall-setters-on-nulls: truesms:accessKeyId:accessKeySecret:regionId: cn-hangzhousignName:templateCode:jwt:tokenHeader: Authorizationkey: library-secrettokenHead: 'Bearer '
这样就在application.yml
指定了通用配置。为了让层次更清晰,不建议使用properties
,Idea
自己可以调整好缩进,不会有多一个空格少一个空格的问题。
dev配置文件
spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverdruid:url: jdbc:mysql://127.0.0.1:3306/library_1?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=trueusername: rootpassword: xxxxxxinitial-size: 5min-idle: 15max-active: 30remove-abandoned-timeout: 180max-wait: 300000time-between-eviction-runs-millis: 60000min-evictable-idle-time-millis: 300000max-evictable-idle-time-millis: 900000stat-view-servlet:enabled: trueloginUsername: adminloginPassword: xxxxxxallow:web-stat-filter:enabled: truesession-stat-enable: truesession-stat-max-count: 1000url-pattern: /*filters: stat,wall,slf4jfilter:stat:enabled: truedb-type: mysqllog-slow-sql: trueslow-sql-millis: 2000file-storage:default-platform: minio-1thumbnail-suffix: ".min.jpg"local-plus:- platform: local-plus-1enable-storage: trueenable-access: truedomain: "http://127.0.0.1:xxxx/api/library/"base-path: library/uploadFile/path-patterns: /api/library/**storage-path: /minio:- platform: minio-1enable-storage: trueaccess-key: xxxxxxxxxsecret-key: xxxxxxxxxxxxxxxxxxxxxend-point: http://xx.xx.xx.xx:9000bucket-name: librarydomain: http://xx.xx.xx.xx:9000/library/base-path:aliyun-oss:- platform: aliyun-oss-1enable-storage: trueaccess-key:secret-key:end-point: oss-cn-hangzhou.aliyuncs.combucket-name: library-oss-picdomain: https://library-oss-pic.oss-cn-hangzhou.aliyuncs.com/base-path:data:redis:host: 127.0.0.1port: 6379database: 0timeout: 1800000password:lettuce:pool:max-wait: -1max-idle: 32min-idle: 5max-active: 1000server:port: xxxx
这样就可以覆盖已有配置为开发环境配置。
验证
由于已经解决了依赖版本冲突的问题,在建好所需的数据库后,可以启动验证:
Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath in order to avoid potential conflicts. ____ _ __ _ _/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/ ___)| |_)| | | | | || (_| | ) ) ) )' |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot :: (v3.4.2)2025-02-27 22:06:32 2405 [background-preinit] [INFO ] org.hibernate.validator.internal.util.Version [] - HV000001: Hibernate Validator 8.0.2.Final
2025-02-27 22:06:32 2457 [main] [INFO ] com.zhiyong.admin.LibraryApplication [] - Starting LibraryApplication using Java 17.0.7 with PID 38052 (E:\study\library\proj\library-admin\target\classes started by zhiyong in E:\study\library\proj)
2025-02-27 22:06:32 2461 [main] [INFO ] com.zhiyong.admin.LibraryApplication [] - The following 1 profile is active: "dev"
2025-02-27 22:06:34 4355 [main] [INFO ] org.springframework.data.repository.config.RepositoryConfigurationDelegate [] - Multiple Spring Data modules found, entering strict repository configuration mode
2025-02-27 22:06:34 4358 [main] [INFO ] org.springframework.data.repository.config.RepositoryConfigurationDelegate [] - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2025-02-27 22:06:34 4515 [main] [INFO ] org.springframework.data.repository.config.RepositoryConfigurationDelegate [] - Finished Spring Data repository scanning in 135 ms. Found 0 Redis repository interfaces.
2025-02-27 22:06:35 5819 [main] [INFO ] org.springframework.boot.web.embedded.tomcat.TomcatWebServer [] - Tomcat initialized with port 8888 (http)
2025-02-27 22:06:35 5839 [main] [INFO ] org.apache.coyote.http11.Http11NioProtocol [] - Initializing ProtocolHandler ["http-nio-8888"]
2025-02-27 22:06:35 5841 [main] [INFO ] org.apache.catalina.core.StandardService [] - Starting service [Tomcat]
2025-02-27 22:06:35 5842 [main] [INFO ] org.apache.catalina.core.StandardEngine [] - Starting Servlet engine: [Apache Tomcat/10.1.34]
2025-02-27 22:06:35 5993 [main] [INFO ] org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/api/library] [] - Initializing Spring embedded WebApplicationContext
2025-02-27 22:06:35 5993 [main] [INFO ] org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext [] - Root WebApplicationContext: initialization completed in 3213 ms
Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath in order to avoid potential conflicts
2025-02-27 22:06:35 6131 [main] [INFO ] com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceAutoConfigure [] - Init DruidDataSource
2025-02-27 22:06:36 6944 [main] [INFO ] com.alibaba.druid.pool.DruidDataSource [] - {dataSource-1} inited
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
Get /172.30.16.1 network interface
Get network interface info: name:eth23 (Hyper-V Virtual Ethernet Adapter)
Initialization Sequence datacenterId:14 workerId:5
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@41581c3f] was not registered for synchronization because synchronization is not active
JDBC Connection [ConnectionProxyImpl{connectedTime=2025-02-27 22:06:36.613, closeCount=0, lastValidateTimeMillis=2025-02-27 22:06:36.615}] will not be managed by Spring
此时环境就绪,再验证下Druid
连接池:
http://localhost:xxxx/api/library/druid/datasource.html
当看到熟悉的监控界面时,说明后端环境及数据库环境就绪!!!接下来就可以进行后端开发!!!
转载请注明出处:https://lizhiyong.blog.csdn.net/article/details/145915249