承接上篇基礎配置,本文深入講解 MyBatis 企業級開發核心特性:外部化資料庫配置、全局設定與類型別名、Mapper 批量掃描、動態 SQL 標籤靈活構建查詢條件、以及封裝複雜查詢參數的最佳實踐。
將資料庫連接參數剝離至獨立屬性文件,便於多環境切換與維護:
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis jdbc.username=root jdbc.password=root
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 載入外部屬性文件 -->
<properties resource="db.properties" />
<!-- 全局配置參數:二級緩存、延遲加載等,謹慎調優 -->
<!-- <settings><setting name="" value=""/></settings> -->
<!-- 類型別名:簡寫全限定類名 -->
<typeAliases>
<!-- 單個定義:<typeAlias type="cn.itcast.mybatis.po.User" alias="user"/> -->
<!-- 批量掃描包下所有 POJO,別名為類名(大小寫不敏感) -->
<package name="com.mybatis.bean"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- Mapper 映射文件註冊三種方式 -->
<mappers>
<!-- 方式一:resource 引用單個 XML,需在 XML 中指定 namespace 為 Mapper 接口全限定名 -->
<!-- <mapper resource="sqlmap/UserMapper.xml" /> -->
<!-- 方式二:class 直接指定 Mapper 接口,約定:XML 與接口同目錄同名 -->
<!-- <mapper class="cn.itcast.mybatis.mapper.UserMapper"/> -->
<!-- 方式三(推薦):批量掃描包,同樣遵循 XML 與接口同目錄同名約定 -->
<package name="com.mybatis.mapper"/>
</mappers>
</configuration>
public interface UserMapper {
User findUserById(int id) throws Exception;
List<User> findUserList(String name) throws Exception;
Integer insertUser(User user) throws Exception;
void deleteUser(int id) throws Exception;
void updateUser(User user) throws Exception;
// 封裝查詢條件的多種方式
List<User> findUserByBean(User user) throws Exception;
List<User> findUserByMap(Map<String, Object> map) throws Exception;
List<User> findUserByCustom(QueryVo queryVo) throws Exception;
// 動態更新:僅更新非空字段
void updateUserSet(User user) throws Exception;
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.UserMapper">
<!-- SQL 片段:抽取可復用的查詢條件 -->
<sql id="query_for_user">
<if test="user != null">
<if test="user.name != null and user.name != ''">
and name like '%${user.name}%'
</if>
<if test="user.sex != null and user.sex != ''">
and sex = #{user.sex}
</if>
</if>
<if test="ids != null">
<foreach collection="ids" separator="or" item="item" open="and (" close=")">
id = #{item}
</foreach>
</if>
</sql>
<select id="findUserById" parameterType="int" resultType="User">
SELECT * FROM USER WHERE id = #{id}
</select>
<select id="findUserList" parameterType="String" resultType="User">
select * from user where name like '%${value}%'
</select>
<insert id="insertUser" parameterType="User">
<selectKey keyProperty="id" order="AFTER" resultType="Integer">
select LAST_INSERT_ID()
</selectKey>
insert into user(name,age,sex) values(#{name},#{age},#{sex})
</insert>
<delete id="deleteUser" parameterType="int">
delete from user where id=#{id}
</delete>
<update id="updateUser" parameterType="User">
update user set name=#{name},age=#{age},sex=#{sex} where id=#{id}
</update>
<!-- POJO 封裝查詢 -->
<select id="findUserByBean" parameterType="User" resultType="User">
select * from user where name like '%${name}%' and sex = #{sex}
</select>
<!-- Map 封裝查詢 -->
<select id="findUserByMap" parameterType="hashmap" resultType="User">
select * from user where name like '%${name}%' and age >= #{age}
</select>
<!-- QueryVo 封裝查詢:引用 SQL 片段 + <where> 標籤智能處理 AND/OR -->
<select id="findUserByCustom" parameterType="QueryVo" resultType="User">
select * from user
<where>
<include refid="query_for_user"/>
</where>
</select>
<!-- 動態更新:<set> 標籤智能處理逗號 -->
<update id="updateUserSet" parameterType="User">
update user
<set>
<if test="name != null and name != ''">
name = #{name},
</if>
<if test="age != null and age != '' and age != 0">
age = #{age},
</if>
<if test="sex != null and sex != ''">
sex = #{sex},
</if>
</set>
where id = #{id}
</update>
</mapper>
| 標籤 | 作用 | 關鍵屬性 |
|---|---|---|
<where> | 智能插入 WHERE 關鍵字,自動去除首個 AND/OR | 無 |
<set> | 智能插入 SET 關鍵字,自動去除尾部逗號 | 無 |
<if> | 條件判斷 | test:OGNL 表達式 |
<foreach> | 集合遍歷,構建 IN 條件等 | collection、item、separator、open、close |
<include> | 引用 <sql> 片段 | refid |
<choose>/<when>/<otherwise> | 互斥分支選擇(類似 switch) | test |
<trim> | 通用字串修飾,可替代 where/set | prefix、suffix、prefixOverrides、suffixOverrides |
QueryVo.java - 查詢條件封裝類,支援多條件組合:
public class QueryVo {
private User user; // 基本查詢條件
private UserCustom uc; // 擴展查詢條件
private List<Integer> ids; // ID 列表,用於 IN 查詢
// Getter/Setter 省略
}
UserCustom.java - 擴展實體類(命名慣例:XxxCustom),繼承 User 新增業務字段:
public class UserCustom extends User {
private String youngOrOld; // 年齡段標識:年輕/年長
// Getter/Setter 省略
}
select * from ${tableName}、動態排序欄位 order by ${column}、資料庫函數參數 to_date('${date}', 'yyyy-MM-dd')parameterMap 已廢棄,勿使用resultMap 複雜場景才用,簡單映射 resultType 即可Map 類型需硬編碼 Key,維護性差,建議返回實體或 DTO完整代碼已上傳 GitHub:https://github.com/leechenxiang/mybatis002-dynamic-proxy
掌握動態 SQL 與參數封裝,是 MyBatis 從「能用」到「好用」的關鍵躍遷。下一篇將講解 MyBatis 與 Spring 深度整合、Mapper 動態代理機制原理、緩存架構設計等進階主題。