使用 Hibernate Criteria 查詢 `username`、`password` 時,輸入 `zhangsan`/`123` 仍能查到資料庫儲存的 `ZhangSan`/`123`,原因是 MySQL 資料表/欄位採用 **`utf8_general_ci`(ci = case-insensitive)排序規則**,導致比較預設不分大小寫。
ALTER TABLE `user` MODIFY `username` VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_bin;
ALTER TABLE `user` MODIFY `password` VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_bin;
`utf8_bin` 二進位比較,嚴格區分大小寫。
// HQL
from User where binary username = :name and binary password = :pwd
// Criteria (Hibernate 5.2+)
criteria.add(Restrictions.eq("username", username).ignoreCase(false));
// 或
criteria.add(Restrictions.sqlRestriction("binary username = ?", username, StandardBasicTypes.STRING));
查詢回傳實體後,在 Java 代碼中用 `equals` 再次比對密碼,雙重保險。
**資料庫層面改 `utf8_bin` 最乾淨**,避免應用層到處加 `binary` 或 `ignoreCase(false)`,且能統一規範所有查詢行為。修改前請評估現有資料是否有大小寫衝突(如 `Admin` vs `admin`),若有需先清理資料。