因為他是指出專案中的jackson問題
所以~我回去找dependency看看哪邊用到
可以發現左下角 spring-security-oauth2-autoconfigure 使用的2.2.13 release版本
使用到這個有資安問題的jar包
我嘗試性做升級到目前最新的版本如下
為2.6.1版本
當我升級過後
可以發現原本使用到有資安問題的jar檔
已經沒有在使用
*很多在更新版本的時候, 已經將有資安問題的引用改掉
*因此, 在學習新技術的時候, 還是盡量能以最新版好點
因為他是指出專案中的jackson問題
所以~我回去找dependency看看哪邊用到
可以發現左下角 spring-security-oauth2-autoconfigure 使用的2.2.13 release版本
使用到這個有資安問題的jar包
我嘗試性做升級到目前最新的版本如下
為2.6.1版本
當我升級過後
可以發現原本使用到有資安問題的jar檔
已經沒有在使用
*很多在更新版本的時候, 已經將有資安問題的引用改掉
*因此, 在學習新技術的時候, 還是盡量能以最新版好點
面向對象設計 目標
1 可擴展性 - 新功能易新增
2 靈活性 - 新增過程中, 不因舊功能僵固而進行困難
(不會改功能A 導致功能B無法使用)
3 可插入性 - 容易把一個類別抽出去, 替換相同介面的類進來使用
判斷軟體設計質量的標準
高內聚, 低耦合
*耦合性: 模塊與模塊, 類與類之間相互聯繫的緊密程度->獨立性弱->如果一個類不存在, 另外一個類就無法運作
*內聚性: 模塊內部, 或是 類內部的元素, 程式區塊, 關聯越緊密, 內聚性越高
*高內聚:軟體模塊由相關性很強的程式碼組成, 只負責一項任務, 不可分割
*低耦合:模塊之間, 類與類之間, 盡可能的獨立存在, 以最低程度的關聯進行協作
------------------------------------------------------------------------
單一職責原則 (Singke-Responsibility Principle)
定義: 一個類只負責一個功能領域中的相應職責, 或可以定義為: 就一個類而言, 應該只有一個引起它變化的原因
高內聚
一個類承擔的責任越多, 它可被復用的可能性就越小, 而且一個類承擔的責任過多, 就相當於將這些職責偶合在一起, 當其中一個職責變化時, 可能會影響到其他職責的運作, 因此要將這些職責進行分離,將不同的職責封裝在不同的類中, 即將不同的變化原因封裝在不同的類中, 如果多個職責總是同時發生變化則可將它們封裝在同一個類中
好處:
1 可降低類的複雜度, 一個類只負責一向職責, 其邏輯肯定比負責多項職責簡單的多
2 複雜度低, 可讀性自然提高
3 可維護性高, 風險低, 如果介面的單一職責好, 一個介面修改指對應相應的實現類有影響, 對其它的介面無影響, 這對系統的擴展性, 維護性都有很大的幫助
範例: 原本CustomerChart類別中包含兩個功能
一個是查找數據庫, 另一個是顯示列表
然而我們今天查找數據庫發生變化, 原本使用mysql改成用mogodb
這樣, 這一個類, 它就不存在了, 它需要進行修改
CustomerChart本身關心顯示列表, 並不關心查找數據庫, 我們可以將這功能撥離
產生一個CutomerDao用來查找數據庫
這樣我們未來設計, 如果改變數據庫, 我們只要在這裡new一個CustomerDao
而CustomerChart本身並不需要進行任何改變, 我們就使CusomerChart實現了單一職責原則
就是他只管它該管的事情, 而不管它不該管的事情
參考:
https://www.youtube.com/watch?v=oKu6q6Nnvdk&list=PLGmd9-PCMLhb16ZxeSy00qUsBazXgJyfM&index=4
https://github.com/iw5420/geroge-design-pattern
*具有多年讀書會經驗
*聽力穩定450分以上(490分2次)
*懂得如何從低分群準備到高分群
*多次考試經驗, 並從準備考試中建構會話基礎 主教多益聽力部分,以及準備方法 每周上課1小時,會出一天份量的回家作業 藉由每周進度,幫助久未接觸英文的工作人 找回英文的熟悉度,並累積英文基礎能力 養成良好的學習模式 本次學生程度為400-600 目前人數:4~6 地點:Teams 線上 時間:周日 晚上8:30 - 10:00 收費:300 聯絡方式 : 站內私訊,或是line: iw5420 教材:由老師提供,也可自行購買課本JSESSIONID 的cookie secure設置確有改變, 如下圖
@Component
public class CookieSecureUtils {
public static Cookie setSecure(Cookie targetCookie) {
targetCookie.setHttpOnly(true);
targetCookie.setSecure(true);
return targetCookie;
}
}
2載入類
@Autowired
private CookieSecureUtils cookieSecureUtils;
2送出cookie前,設置安全
response.addCookie(cookieSecureUtils.setSecure(new Cookie("domain", resultObj.getString("domain"))));
response.addCookie(cookieSecureUtils.setSecure(new Cookie("account", account)));
response.addCookie(cookieSecureUtils.setSecure(new Cookie("lang", request.getParameter("lang"))));
整串的邏輯大約是這樣
1開始載入時 撈取下拉選單,回給前端排列畫面,並產生全域List供篩選使用
2按鈕功能觸發查詢該病患資料
3依照病患id查詢病患該表項資料
4顯示該病患該表項資料
問題
當4顯示資料的時候, 有去使用到1的下拉選單的List
但是發現, 我操作查詢該病患的表項資料速度快的時候,
會發生顯示問題, 開f12發現, 顯示需要的list並沒有撈回來, 他就已經執行篩選顯示
找尋根源問題
一開始推測, getDropdown需要更多的時間, 所以讓他在網頁中載入順序提前,
但是發現, 這還是沒有解決問題
因此, 我做了一個操作
我嘗試在下拉選單組完選單內容的最後印出"finished"字樣
好讓我知道, 什麼時候才把下拉選單組完
此時我發現, 這個finished差不多讓我等了6秒鐘
很明顯, 如果說我整套操作動作在6秒鐘內完成
很有可能會組資料的時候List還沒有準備好
因此
到底為什麼撈取dropdown會需要撈取這麼久呢?
就是這裡的核心問題
我注意到在等待dropdown回傳的過程中,
他在等待account做了很多查詢
我原本以為是權限相關
回去看code發現
原來為了取得帳號名稱
程式查找出整個account內容
因為其權限是eager撈出來的不是lazyload(當初設計上問題)
因此這邊撈出account會再重新把所有權限功能子功能run一遍
整體就是慢在這邊
解法
我使用另一個只撈id和name的Repo function, 準確的撈取我要的資料->帳號名稱
代替原本把account下面所有關聯查出來
大約看到finished在console中, 不到1秒就跑出來了
而證實拖累效能問題的確在這裡
finished!
String medicalId = pbSearch.getMedicalId()==""?null:pbSearch.getMedicalId();
String identityId = pbSearch.getIdentityId()==""?null:pbSearch.getIdentityId();
String fullname = pbSearch.getFullname()==""?"":pbSearch.getFullname();
String mode = pbSearch.getMode();
PageRequest pageRequest = size == 0 ? null: PageRequest.of(--page, size, Sort.by("sysTime").descending());
PagepatientBasicList = patientBasicRepo.findVoByDomainAndMedicalIdOrIdentityIdOrFullnameOrMode(domain
,medicalId, identityId, fullname,mode,pageRequest);
@Query("select new com.ICU.ICUmodule.vo.caseManage.PatientBasicVo(pb.id as id, pb.medicalId as medicalId, pb.identityId as identityId, pb.fullname as fullname, "
+ "pb.telephone as telephone, pb.localDate as localDate, pb.treatment as treatment, pr.mode as mode) "
+ "from patient_basic pb left join patient_returned pr on pb.id=pr.patientBasic.id "
+ "where pb.domain=:doamin and (:medicalId is null or pb.medicalId =:medicalId) and (:identityId is null or pb.identityId =:identityId) and (:fullname is '' or pb.fullname LIKE '%' || :fullname||'%') and (:mode is null or pr.mode =:mode)")
Page findVoByDomainAndMedicalIdOrIdentityIdOrFullnameOrMode(String doamin, String medicalId,
String identityId, String fullname, String mode, Pageable pageRequest);
在一般情況下, 若是要判斷是否為 null 再拉進JPQL裡面做is null or object.xxx = :xxx
然而在模糊查詢的時候, 這裡若為 null 帶入到JPQL LIKE語法, 會產生判斷JPQL語法錯誤問題
因此在這裡LIKE語法是不能帶null, 而要給""字串來做判斷, 這樣JPQL就不會run出問題, 也可以進行模糊查詢及一般查詢
String no = repo.getLastIoNo();
String prefix = new SimpleDateFormat("yyyyMMdd").format(new Date());
prefix = prefix.substring(prefix.length() - 6);
if(no != null && no.matches("^" + prefix + "\\d{3}$")) {
no = String.valueOf(Integer.valueOf(no) + 1);
} else if(no == null || !no.matches("^" + prefix + "\\d{3}$")) {
no = String.format("%s%s", prefix, "001");
} else {
throw new Exception("Create StockIoMaster io_no fail");
}
簡單的說, 這個組成的流水碼最後會變成yyMMdd001, 後面會隨數字變多yyMMdd002, 接續增加
而這組流水碼, 會從001開始, 如果資料庫有取出東西, 且同一prefix的情況, 會自動將序號轉成數字
加一, 這樣就產生一組新的序號在資料庫中
取資料的寫法如下
@Query("select max(m.ioNo) from stock_io_master as m")
String getLastIoNo();
AI 時代的軟體工程:從「代碼寫手」到「系統指揮官」的轉型之路 2026 年,軟體工程正經歷自編譯器發明以來最大的範式轉移。AI 不再只是 IDE 側邊欄的輔助工具,而是進化為具備自主性的 Agent(代理人) ,這場變革正重新定義「工程師」的核心價值。 一、 現狀:AI 普...