1. 程式人生 > >Hibernate 和 MyBatis 實現方式的區別

Hibernate 和 MyBatis 實現方式的區別

Hibernate 和 MyBatis 都是持久層框架,都會涉及資料庫,所以先定義一個數據庫表,先從程式碼編寫角度對比兩者。

新建一個 POJO 類,和表的欄位對應起來。

package com.learn.chapter1.pojo;
implements java.io.Serializable;

public class Role implements Serializable{
    private Integer id;
    private String roleName;
    private String note;
    /*下面是setter和getter方法,可自動生成,此處略去不寫*/
}

一、Hibernate 實現

    Hibernate 基本不需要編寫 SQL 就可通過對映關係來操作資料庫,是一種全表對映的體現。Hibernate 是將 POJO 和資料庫表對應的對映檔案。

Hibernate 對映檔案

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.learn.chapter1.pojo.Role" table="t_role">
        <id name="id" type="java.lang.Integer">
            <column name="id"/>
            <generator class="identity"/>
        </id>
        <property name="roleName" type="string">
            <column name="role_name" length="60" not-null="true"/>
        </property>
        <property name="note" type="string">
            <column name="note" length="512"/>
        </property>
    </class>
</hibernate-mapping>

首先對 POJO 和表 t_role 進行了對映配置,把兩者對映起來。然後對 POJO 進行操作,從而影響 t_role 表的資料,比如對其增、刪、改、查可按照下述程式碼操作。

Hibernate 通過 Session 操作資料庫資料

Session session = null;
Transaction tx = null;
try{
    //開啟Session
    session = HibernateUtil.getSessionFactory().openSession();
    //事務
    tx = session.beginTransaction();
    //POJO
    Role role = new Role();
    role.setId(1);
    role.setRoleName("rolename1");
    role.setNote("note1");
    session.save(role);//儲存
    Role role2 = (Role)session.get(Role.class,1);//查詢
    role2.setNote("修改備註");
    session.update(role2);//更新
    System.out.println(role2.getRoleName());
    session.delete(role2);//刪除
    tx.commit();//提交事務
}catch(Exception e){
    if(tx != null && tx.isActive()){
        tx.rollback();//回滾事務
    }
    e.printStackTrace();
}finally{
    if(session != null && session.isOpen()){
        session.close();    
    }
}

二 、MyBatis 實現

MyBatis 對映檔案

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.learn.chapter1.mapper.RoleMapper">
    <resultMap id="roleMap" type="com.learn.chapter1.pojo.ROle">
        <id property="id" column="id"/>
        <result property="roleName" column="role_name"/>
        <result property="note" column="note"/>
    </resultMap>

    <select id="getRole" resultMap="roleMap">
        select id,role_name,note from t_role where id = #{id}
    </select>
    
    <delete id="deleteRole" parameterType="int">
        delete from t_role where id = #{id}
    </delete>
    
    <insert id="insertRole" parameterType="com.learn.chapter1.pojo.Role">
        insert into t_role(role_name,note) value (#{roleName},#{note})
    </insert>

    <update id="updateRole" parameterType="com.learn.chapter1.pojo.Role">
        update t_role set role_name = #{roleName},note = #{note} where id = #{id}
    </update>
</mapper>

        這裡的 resultMap 元素用於定義對映規則,而實際上 MyBatis 在滿足一定的規則下,完成自動對映,而增、刪、改、查對應著 insert、delete、update、select 四個元素。

        注意,mapper 元素中的 namespace 屬性,它要和一個介面中的全限定名保持一致,而裡面的 SQL 的 id 也需要和介面定義的方法完全保持一致,定義 MyBatis 對映檔案。

MyBatis 介面檔案

package com.learn.chapter1.mapper;
import com.learn.chapter1.pojo.Role;

public interface RoleMapper{
    public Role getRole(Integer id);
    public int deleteRole(Integer id);
    public int insertRole(Role role);
    public int updateRole(Role role);
}

只需要定義介面檔案,不需要實現類。

MyBatis 對角色類的增、刪、改、查

SqlSession sqlSession = null;
try{
    sqlSession = MyBatisUtil.getSqlSession();
    RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
    Role role = roleMapper.getRole(1);//查詢
    System.out.println(role.getRoleName());
    role.setRoleName("update_role_name");
    roleMapper.updateRole(role);//更新
    Role role2 = new Role();
    role2.setNote("note2");
    role2.setRoleName("role2");
    roleMapper.insertRole(role);//插入
    roleMapper.deleteRole(5);//刪除
    sqlSession.commit();//提交事務
}catch(Exception e){
    e.printStackTrace();
    if(sqlSession != null){
        sqlSession.rollback();//回滾事務
    }
}finally{//關閉連線
    if(sqlSession != null){
        sqlSession.close();
    }
}

三、Hibernate 和 MyBatis 的區別

     Hiberante 和 MyBatis 的增、刪、改、查,對於業務邏輯層來說大同小異,對於對映層而言 Hibernate 的配置不需要介面和 SQL,相反 MyBaits 是需要的。對於 Hibernate 而言,不需要編寫大量的 SQL,就可以完全對映,同時提供了日誌、快取、級聯(級聯比 MyBatis 強大)等特性,此外還提供了 HQL(Hibernate Query Language)對POJO 進行操作,使用十分方便,但是它也有致命的缺陷。由於無需 SQL,當多表關聯超過 3 個的時候,通過 Hibernate 的級聯就會造成太多效能的丟失。

    MyBatis 可以自由書寫 SQL、支援動態 SQL、處理列表、動態生成表名、支援儲存過程。這樣就可以靈活地定義查詢語句,滿足各類需求和效能優化的需要。MyBatis 也有缺陷。首先他要編寫 SQL 和對映規則,其工作量稍大於 Hibernate。其次,它支援的工具也很有限,不能像 Hibernate 那樣有許多的外掛可以幫助生成對映程式碼和關聯關係,而即使使用生成工具,往往也需要開發者進一步簡化,MyBatis 通過手工編碼,工作量相對大些。所以對於效能要求不太苛刻的系統 ,比如管理系統等推薦使用 Hibernate ;而對於效能要求高、響應快、靈活的系統則推薦使用 Mybatis。