在 Spring 的 applicationContext.xml 中配置 LocalSessionFactoryBean 時,映射文件的註冊方式直接影響專案的可維護性與擴展性。Spring 提供了 4 種等價但適用場景不同的配置屬性,本文深度解析每種方式的語法、適用場景與最佳實踐。
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<!-- 映射文件配置區域:四選一或組合使用 -->
</bean>
特點:指定 classpath 下具體映射文件路徑,最直觀、最常用。
<!-- 單個文件 -->
<property name="mappingResources" value="userTest.hbm.xml"/>
<!-- 單個文件(value 標籤寫法) -->
<property name="mappingResources">
<value>petclinic.hbm.xml</value>
</property>
<!-- 多個文件(List 寫法) -->
<property name="mappingResources">
<list>
<value>/edu/fjnu/hotelsys/domain/User.hbm.xml</value>
<value>/edu/fjnu/hotelsys/domain/Hotel.hbm.xml</value>
<value>/edu/fjnu/hotelsys/domain/Room.hbm.xml</value>
</list>
</property>
優點:顯式聲明,易於審計、版本控制審查變更
缺點:文件增多時維護負擔重,易出現路徑拼寫錯誤
適用場景:映射文件較少(< 20)、需精確控制加載順序、團隊偏好顯式配置
特點:可指定任意文件路徑(非限 classpath),支援 Spring 資源前綴與 Ant 風格通配符。
<!-- 絕對路徑 / 相對路徑 -->
<property name="mappingLocations">
<value>/WEB-INF/petclinic.hbm.xml</value>
</property>
<!-- classpath 前綴 -->
<property name="mappingLocations">
<value>classpath:/com/company/domain/petclinic.hbm.xml</value>
</property>
<!-- 通配符批量匹配:* 單級,** 多級 -->
<property name="mappingLocations">
<value>classpath:/com/company/domain/maps/*.hbm.xml</value>
</property>
<!-- 多路徑組合 -->
<property name="mappingLocations">
<list>
<value>classpath:/com/moduleA/**/*.hbm.xml</value>
<value>classpath:/com/moduleB/**/*.hbm.xml</value>
</list>
</property>
優點:靈活支援文件系統、JAR 內、War 內等任意資源;通配符劇減配置量
缺點:通配符匹配順序不確定,可能影響依賴關系的映射加載
適用場景:模塊化專案、映射文件分散在多模塊、需掃描整包目錄
特點:指定目錄,Spring 自動遞歸掃描該目錄下所有 *.hbm.xml 文件。
<!-- 文件系統路徑 -->
<property name="mappingDirectoryLocations">
<list>
<value>WEB-INF/HibernateMappings</value>
</list>
</property>
<!-- classpath 路徑 -->
<property name="mappingDirectoryLocations">
<list>
<value>classpath:/com/company/domain/</value>
</list>
</property>
優點:零配置新增映射文件,約定優於配置
缺點:無法控制加載順序;可能誤掃描非映射 XML 文件導致啟動失敗
適用場景:映射文件集中存放、約定目錄結構、微服務模塊獨立映射目錄
特點:指定包含映射文件的 JAR 包路徑,適用於跨專案復用映射定義。
<property name="mappingJarLocations">
<list>
<value>file:/opt/libs/hibernate-mappings-1.0.jar</value>
<value>classpath:/lib/domain-mappings.jar</value>
</list>
</property>
優點:實現映射定義的二進制復用,領域模型獨立打包分發
缺點:調試困難、版本升級需重新打包、JAR 衝突風險
適用場景:多專案共享核心領域模型、商業組件庫、插件化架構
| 屬性 | 路徑類型 | 通配符 | 遞歸掃描 | 典型用例 | 維護成本 |
|---|---|---|---|---|---|
| mappingResources | classpath 相對路徑 | 不支援 | 否 | 少量固定映射 | 高(手工維護列表) |
| mappingLocations | 任意資源路徑 | 支援 *、** | 否(單層*) | 模塊化、通配符批量 | 中 |
| mappingDirectoryLocations | 目錄路徑 | 隱式 *.hbm.xml | 是 | 約定目錄、零配置新增 | 低 |
| mappingJarLocations | JAR 文件路徑 | 不適用 | JAR 內掃描 | 跨專案共享模型 | 低(但升級成本高) |
<property name="mappingLocations">
<list>
<!-- 核心模塊:精確控制 -->
<value>classpath:/com/core/domain/**/*.hbm.xml</value>
<!-- 業務模塊:約定目錄 -->
<value>classpath:/com/biz/**/mappings/*.hbm.xml</value>
<!-- 共享庫:JAR 形式 -->
<value>classpath*:/shared-domain-*.jar</value>
</list>
</property>
關鍵建議:
EntityName.hbm.xml,與實體類同包或固定 mappings 子包@Entity 註解,可改用 annotatedClasses 或 packagesToScan,完全擺脫 XML 映射文件<!-- 註解掃描方式(Hibernate 3.2+ / Spring 3.0+) -->
<property name="packagesToScan">
<list>
<value>com.company.domain</value>
<value>com.company.module*.domain</value>
</list>
</property>
<!-- 或指定具體註解類 -->
<property name="annotatedClasses">
<list>
<value>com.company.domain.User</value>
<value>com.company.domain.Order</value>
</list>
</property>
掌握這 4 種配置方式的本質差異,能根據專案規模、模塊化程度、團隊習慣選擇最適配的映射註冊策略,在維護性與啟動性能間找到最佳平衡點。