【全棧開發】從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