文章目錄
- 前言
- 1. 數據庫表結構
- 2. MyBatis Mapper XML
- 3. Java 實體類
- 4. 技術點解析
- 5. 執行效果
- 6. 優化建議
前言
提示:這里可以添加本文要記錄的大概內容:
以下是一個結合 SQL 別名、子查詢、MyBatis 字段映射和代碼復用的完整案例,以用戶管理系統為例:
場景描述:
查詢用戶信息時需同時顯示:
- 基礎用戶信息
- 所屬部門名稱
- 最近3個月的訂單數量
- 使用代碼復用優化重復SQL片段
1. 數據庫表結構
用戶表(User)
部門表(Department)
訂單表(Order)
2. MyBatis Mapper XML
<!-- 結果映射 -->
<resultMap id="userResultMap" type="UserDTO"><id property="userId" column="user_id"/><result property="username" column="username"/><result property="departmentName" column="department_name"/><result property="orderCount" column="order_count"/><result property="createTime" column="create_time"/>
</resultMap><!-- 定義可復用的基礎字段 -->
<sql id="baseUserColumns">u.id AS user_id,u.username,u.create_time
</sql><!-- 定義部門關聯字段 -->
<sql id="deptColumns">d.dept_name AS department_name
</sql><!-- 復合查詢 -->
<select id="selectUserWithStats" resultMap="userResultMap">SELECT <!-- 復用基礎字段 --><include refid="baseUserColumns"/>,<!-- 復用部門字段 --><include refid="deptColumns"/>,<!-- 使用子查詢和別名 -->(SELECT COUNT(*) FROM order o WHERE o.user_id = u.idAND o.order_time >= DATE_SUB(NOW(), INTERVAL 3 MONTH)) AS order_countFROM user uLEFT JOIN department d ON u.dept_id = d.idWHERE u.id = #{userId}
</select>
3. Java 實體類
public class UserDTO {private Long userId; // 映射 user_idprivate String username; // 直接映射private String departmentName; // 映射 department_nameprivate Integer orderCount; // 映射 order_countprivate Date createTime; // 映射 create_time// getters/setters
}
4. 技術點解析
- SQL 別名(Alias)
u.id AS user_id,d.dept_name AS department_name
- 解決字段名沖突
- 實現數據庫蛇形命名到Java駝峰命名的轉換
- 子查詢封裝
(SELECT COUNT(*) ...) AS order_count
- 將復雜統計邏輯封裝在子查詢中
- 避免多次查詢數據庫
- MyBatis字段映射
<resultMap id="userResultMap" type="UserDTO"><id property="userId" column="user_id"/><result property="departmentName" column="department_name"/></resultMap>
- 實現數據庫字段到對象屬性的映射
- 處理命名差異問題
- SQL代碼復用
<include refid="baseUserColumns"/><include refid="deptColumns"/>
- 統一管理公共字段
- 修改時只需改動一處
5. 執行效果
當調用selectUserWithStats
方法查詢用戶 ID 時:
獲取某個特定用戶的基本信息及其最近3個月的訂單活動情況
生成的SQL:
SELECT u.id AS user_id,u.username,u.create_time,d.dept_name AS department_name,(SELECT COUNT(*) FROM order o WHERE o.user_id = u.idAND o.order_time >= DATE_SUB(NOW(), INTERVAL 3 MONTH)) AS order_count
FROM user u
LEFT JOIN department d ON u.dept_id = d.id
WHERE u.id = #{id}
下面是對這段SQL子查詢語句每一行的詳細解釋:
(SELECT COUNT(*) FROM order o WHERE o.user_id = u.idAND o.order_time >= DATE_SUB(NOW(), INTERVAL 3 MONTH)) AS order_count
- 這用于計算特定用戶在過去3個月內生成的訂單數量。它從
order
表(別名為o
)中計數所有滿足條件的記錄:user_id
與外部查詢中的用戶ID相匹配,且order_time
在當前時間(NOW()
)起往前推3個月的時間范圍內。結果被命名為order_count
。
查詢結果映射:
UserDTO{userId=1001, username="張三", departmentName="技術部", orderCount=5, createTime=2023-01-15
}
6. 優化建議
- 性能優化:為
order.user_id
和order_time
字段添加索引 - 子查詢優化:大數據量時可改為LEFT JOIN查詢
- 動態SQL:添加
<if>
條件實現動態字段控制 - 分頁支持:添加LIMIT語句配合PageHelper插件
這個案例完整展示了復雜查詢場景下,如何通過MyBatis的特性實現清晰、可維護的SQL編寫。