首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java ORM 框架實戰指南:Hibernate 與 iBatis 核心用法全解析

     編輯:Java 程式設計入門

ORM(Object-Relational Mapping)框架將資料庫表映射為記憶體對象,極大簡化了資料持久層開發。本文聚焦 Java 生態中最經典的兩大框架——Hibernate 與 iBatis(現 MyBatis 前身),通過完整配置與代碼示例,展示從單表操作到多表關聯的完整用法。

一、Hibernate:全自動 ORM 的重量級選擇

Hibernate 強調「持久化」與「ORM」分離:持久化關注對象生命週期,ORM 關注表對象映射。它使用 POJO 作為 Model,XML 配置映射關係,提供豐富 API 與 HQL 查詢語言。

1. Session 管理工具類

類似 JDBC 的 Connection,Session 需要線程級管理:

public class HibernateSessionManager {
    private static SessionFactory sessionFactory;
    static {
        try {
            sessionFactory = new Configuration()
                .configure("sample/orm/hibernate/hibernate.cfg.xml")
                .buildSessionFactory();
        } catch (Exception ex) { ex.printStackTrace(); }
    }
    private static final ThreadLocal tl = new ThreadLocal<>();

    public static Session currentSession() {
        Session s = tl.get();
        if (s == null) { s = sessionFactory.openSession(); tl.set(s); }
        return s;
    }
    public static void closeSession() {
        Session s = tl.get(); tl.set(null);
        if (s != null) s.close();
    }
}

2. 單表 CRUD 完整示例

實體類:

public class User implements Serializable {
    private int userID; private String userName;
    // getter/setter 省略
}

映射文件 User.hbm.xml:

<hibernate-mapping>
  <class name="sample.orm.hibernate.User" table="user" catalog="test">
    <id name="userID" type="java.lang.Integer">
      <column name="id" /> <generator class="assigned" />
    </id>
    <property name="userName" type="java.lang.String">
      <column name="name" />
    </property>
  </class>
</hibernate-mapping>

全局配置 hibernate.cfg.xml(含連接池、方言、顯示 SQL):

<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/test</property>
<property name="connection.username">root</property>
<property name="connection.password">123</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<mapping resource="sample/orm/hibernate/User.hbm.xml" />

測試代碼:

private static void insertUser() {
    Session s = HibernateSessionManager.currentSession();
    Transaction tx = s.beginTransaction();
    User u = new User(); u.setUserID(6); u.setUserName("Zhang Fei");
    s.save(u); s.flush(); tx.commit();
    HibernateSessionManager.closeSession(); getUser(6);
}
// updateUser、deleteUser、getUser 同理

執行序列 insertUser(); updateUser(6); deleteUser(6); 輸出包含自動生成的 SQL,驗證了透明持久化。

3. 多表關聯:一對多、多對一、多對多

以「排課系統」為例,四張表:Grade、Class、ClassRoom、Schedule(關聯表)。

實體類關鍵字段:

  • Grade:Set<Class> classes(一對多)
  • Class:Grade grade(多對一)+ Set<ClassRoom> classrooms(多對多)
  • ClassRoom:Set<Class> classes(多對多反向)
  • Schedule:僅作關聯表映射,無導航屬性

映射要點(Grade.hbm.xml 片段):

<set name="classes" lazy="true" inverse="true" cascade="all-delete-orphan">
  <key><column name="gradeid"/></key>
  <one-to-many class="sample.orm.hibernate.Class"/>
</set>

Class.hbm.xml 同時聲明 <many-to-one name="grade"> 與 <set name="classrooms" table="schedule"><many-to-many class="ClassRoom" column="classroomid"/></set>。

4. 關聯操作特性演示

  • 延遲加載:Hibernate.initialize(grade.getClasses()) 顯式觸發
  • 級聯新增:session.save(grade) 自動持久化關聯的 Class 集合
  • 級聯修改/刪除:配置 cascade="all-delete-orphan" 後,刪除 Grade 自動刪除其 Class

測試序列 getClass(1); getSchedule(1); insertGrade(); updateGrade1(4); updateGrade2(4); deleteGrade(10); 輸出完整 SQL 鏈,展示 Hibernate 對圖狀對象圖的管理能力。

二、iBatis:基於 SQL 模板的輕量級選擇

iBatis 不自動生成 SQL,而是將 SQL 寫在 XML 模板中,保留對 SQL 的完全控制,適合複雜查詢與存儲過程場景。

1. 實體類

與 Hibernate 示例相同的 User 類,放置於 sample.orm.ibatis 包。

2. SQL Map 配置 User.xml

<sqlMap namespace="User">
  <typeAlias alias="user" type="sample.orm.ibatis.User" />
  <cacheModel id="user-cache" type="OSCache" readOnly="true" serialize="true">...</cacheModel>

  <select id="getUser" parameterClass="java.lang.Integer" resultClass="user" cacheModel="user-cache">
    select id as userID, name as userName from user where id = #userID#
  </select>
  <select id="getAllUser" resultClass="user" cacheModel="user-cache">
    select id as userID, name as userName from user
  </select>
  <update id="updateUser" parameterClass="user">
    update user SET name=#userName# WHERE id = #userID#
  </update>
  <insert id="insertUser" parameterClass="user">
    insert into user (id, name) VALUES (#userID#, #userName#)
  </insert>
  <delete id="deleteUser" parameterClass="java.lang.Integer">
    delete from user where id=#userID#
  </delete>
</sqlMap>

3. 全局配置 SqlMapConfig.xml

<settings cacheModelsEnabled="true" lazyLoadingEnabled="true" ... />
<transactionManager type="JDBC">
  <dataSource type="SIMPLE">
    <property name="JDBC.Driver" value="com.mysql.jdbc.Driver"/>
    <property name="JDBC.ConnectionURL" value="jdbc:mysql://localhost/test"/>
    <property name="JDBC.Username" value="root"/>
    <property name="JDBC.Password" value="123"/>
    <property name="Pool.MaximumActiveConnections" value="10"/> ...
  </dataSource>
</transactionManager>
<sqlMap resource="sample/orm/ibatis/User.xml" />

4. 客戶端調用

public class Sample {
    private SqlMapClient sqlMap;
    private void buildMap() throws IOException {
        Reader reader = Resources.getResourceAsReader("sample/orm/ibatis/SqlMapConfig.xml");
        this.sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
    }
    private void insertUser() throws SQLException, IOException {
        if (sqlMap == null) buildMap();
        sqlMap.startTransaction();
        User u = new User(); u.setUserID(10); u.setUserName("Angel");
        sqlMap.insert("insertUser", u);
        sqlMap.commitTransaction();
        printUserInfo(getUser(10));
    }
    // updateUser、deleteUser、getUser、getAllUser 類似
    public static void main(String[] args) throws Exception {
        Sample s = new Sample();
        s.getAllUser(); s.insertUser(); s.updateUser(); s.deleteUser();
    }
}

輸出結果清晰展示緩存與事務行為:

=====user info=====
ID:1;Name:Zhang San
ID:2;Name:TEST
=====Insert test=====
=====user info=====
ID:10;Name:Angel
=====Update test=====
=====user info=====
ID:10;Name:Devil
=====Delete test=====
=====user info=====
ID:1;Name:Zhang San
ID:2;Name:TEST

三、總結與選型建議

維度HibernateiBatis
映射方式全自動 ORM,對象圖導航手寫 SQL 模板,精準控制
學習曲線陡峭(HQL、延遲加載、鎖策略)平緩(接近 JDBC 思維)
複雜查詢HQL/Criteria 較繁瑣原生 SQL 靈活高效
適用場景標準 CRUD、領域模型豐富的系統報表、批量操作、存儲過程多的系統

實際專案中,兩者常混用:核心業務用 Hibernate 享受領域建模便利,複雜查詢/報表用 iBatis 發揮 SQL 優勢。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved