項目開發日志:技術實踐與成長之路
前言
回顧這幾天的狀態,熱情總是比我想象中更快被消耗完。比起茫然徘徊的小丑,我更希望自己是對著風車沖鋒的瘋子。
今天繼續深入項目的實際業務。
狀態好點的時候,再看自己EMO時寫的東西,尬死我了,你真的是要尬死我😰。
日程
5.11
那天忘記記錄了,不過我沒有偷懶。
5.12
寫了一個下午,不用想建表,不用想接口文檔就是爽,昨天的我,你的苦沒有白吃!十點半,把業務需求寫得七七八八了,估計后天就能開始做前端。
5.13
我就不該看別人的什么感人愛情小故事😭只有對比別人的幸福的時候才能深刻感覺到自己的破防。(還不知道把耳機丟哪里了,隔幾個月就要為藍牙耳機行業做貢獻😫)。被token驗證卡了,想用AOP,但是實際實現起來特別特別麻煩,先看看能不能弄出來吧。
5.16
有幾天沒有寫blog了,我覺得日常性的記錄最好還是寫寫吧。今天去當了一個會議的觀眾,我果然還是暈會議桌。前端在寫了,在寫了,快的話明天能寫完,然后就是修修界面。最好周日能把DOCKERFILE跑出來。
5.17
emmmmm,昨晚上又熬夜了,最近太太太懶散了。下午,前端基本跑完,然后要一個個微調了。wc,我好像有不少作業沒寫啊😰。改了一晚上,改得差不多了,明天想想數據加密的問題。
5.18
嘗試了一下做數據加密,感覺開銷很大,對原理也不是太明白,先掛到分支,把這個版本的服務器給部署了先。
5.19
昨天的部署沒有成功,今天又弄了一天,總算成功了,還是有點小成就感的。但是錯過了學科作業,還不能補交,拖延癥發力了。警鐘長鳴:能及時完成的事情要及時完成(指寫blog,今天linux部署docker的部分就沒有記到)。
學習內容
省流
- 表與實際業務的分析
- 事務中獲取自增id
- InvocationTargetException
- MySQL的tinyint(1)細節
- maven的聚合jar打包
1. 表與實際業務的分析
經過思考,我覺得以混合劃分法來劃分接口文檔比較合理。以下是學生和教師接口文檔的劃分:
學生接口文檔
- 課程相關
- 獲取課程列表
- 獲取課程詳情
- 練習相關
- 獲取練習列表
- 獲取練習詳情
- 提交練習答案
- 做題相關
- 獲取題目詳情
- 保存臨時答案
- 提交最終答案
教師接口文檔
- 練習管理
- 創建練習
- 修改練習
- 復用練習
- 刪除練習
- 查詢練習列表
- 題目管理
- 添加新題目
- 從題庫選擇題目
- 刪除題目
- 批改相關
- 獲取待批改列表
- 獲取學生答題詳情
- 提交批改結果
- 發送提醒通知
所以按照這樣的劃分來書寫接口文檔。
查詢所屬的課程
學生 -> 學生班級關聯 -> 班級 -> 練習班級關聯 -> 練習 -> 課程。這樣看起來是不是特別麻煩,但是我們可以直接生成視圖!視圖是數據庫中的一個虛擬表,不存儲實際數據,實際是一個預定義的查詢。
比如創建學生課程視圖:
CREATE VIEW v_student_courses AS
SELECT u.id AS student_id,u.name AS student_name,c.id AS course_id,c.name AS course_name,s.id AS semester_id,s.name AS semester_name,s.start_time AS semester_start,s.end_time AS semester_end,COUNT(DISTINCT e.id) AS exercise_count
FROM user u
JOIN student_class sc ON u.id = sc.student_id
JOIN exercise_class ec ON sc.class_id = ec.class_id
JOIN exercise e ON ec.exercise_id = e.id
JOIN course c ON e.course_id = c.id
JOIN semester s ON c.semester_id = s.id
WHERE u.role = 0 -- 學生角色
GROUP BY u.id, c.id, s.id;
然后就可以通過對視圖進行查詢:
-- 查詢某學生的所有課程
SELECT * FROM v_student_courses WHERE student_id = 123;
2. 事務中獲取自增id
我之前以為對事務存在一定的誤解,認為事務是同時處理sql語句,其實不是,這更像是將更改保存在了一個緩沖區。對于同一個連接,是可以獲取到上一個插入操作產生的自增id的(盡管它還沒有實際插入表中)。
public static Integer getLastInsertId() throws SQLException, FileNotFoundException {Connection conn = getConnection();boolean isTxActive = ConnectionContext.isActive();try (Statement stmt = conn.createStatement()){ResultSet rs = stmt.executeQuery("SELECT LAST_INSERT_ID()");if (rs.next()) {return rs.getInt(1);}}catch (SQLException e){throw new SQLException("無法獲取最后插入ID");}finally {if (conn != null && !isTxActive) {conn.close();}}return null;
}
3. InvocationTargetException
InvocationTargetException
是反射調用時的“包裝異常”。在通過反射調用方法時,目標方法內部拋出了異常,反射機制會將這個異常封裝成InvocationTargetException
拋出。
private Throwable extractRootCause(Throwable e) {Throwable rootCause = e;while (rootCause instanceof InvocationTargetException && rootCause.getCause() != null) {rootCause = rootCause.getCause();}return rootCause;
}
4. MySQL的tinyint(1)細節
MySQL 驅動(如 mysql-connector-java)會將 tinyint(1) 自動映射為 Boolean。這是 JDBC 的默認行為,tinyint(1) 被識別為“類似布爾值”的類型(0 → false,非 0 → true)。
5. maven的聚合jar打包
配置maven-shade-plugin
插件,將項目及其所有依賴打包成一個單獨的JAR文件。
<build><resources> <!-- 資源文件 默認復制到target/classes --><resource><directory>src/main/resources</directory> </resource><resource><directory>src/main/webapp</directory><targetPath>webapp</targetPath> <!-- 指定復制到webapp --></resource></resources><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.2.4</version><executions><execution><phase>package</phase><goals><goal>shade</goal> <!-- 打包所有依賴 --></goals><configuration><transformers> <!-- 設置 JAR 文件的入口 --><transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>com.anyview.xiazihao.TomcatApplication</mainClass></transformer></transformers><filters> <!-- 過濾簽名 --><filter><artifact>*:*</artifact><excludes><exclude>META-INF/*.SF</exclude><exclude>META-INF/*.DSA</exclude><exclude>META-INF/*.RSA</exclude></excludes></filter></filters></configuration></execution></executions></plugin></plugins>
</build>
結語
這是一個時間跨度非常長的blog(已經算是半個日記了)。以后就算沒有實際內容,也盡量保持這種形式的更新吧。