MyBatis的適用場景和生命周期


MyBatis使用場景

對比Hibernate和MyBatis是我們常見的話題,Hibernate作為常用的ORM框架,它使用起來簡單易懂,對於SQL語言的封裝,讓對於SQL並不是很熟練的程序員也可以輕松地開發DAO層,IDE也有對應的工具來反向生成,所以開發效率較快,Hibernate也提供了緩存,級聯等高級功能。但是其缺點在於:

1.對於需要SQL優化的場景,如果SQL復雜,Hibernate方法的封裝也派不上用場,還是需要使用原生SQL,而原生SQL返回的是一個Object數組,接下來就是需要我們自己手工完成封裝了。

2.Hibernate是一個全表映射的框架,所以更新和查詢時,如果我們只需要操作表中某些字段,就無法做到。

3.不能有效支持存儲過程

所以Hibernate適用於場景不復雜的,對於性能要求並不高的場景。

可以說MyBatis是一個半映射的框架,它也支持緩存,級聯等操作,缺點就在於需要你提供映射規則和SQL,工作量比Hibernate要大。MyBatis雖然開發不如Hibernate效率高,但是其靈活,可SQL優化的特點很吸引人,正因為此,在於大數據,高並發移動互聯網項目中較為常用。

MyBatis的組件

SqlSessionFactoryBuilder(構造器):它可以根據配置來獲得SqlSessionFactory

SqlSessionFactory(工廠接口):依靠接口創建SqlSession

我們這里再對比一下Mybatis與Hibernate之間創建session工廠所使用方法的不同:

Hibernate中創建方法

Configuration cfg=new Configuration().configure("hibernate.cfg.xml");   //加載hibernate配置文件
SessionFactory sessionFactory=cfg.buidSessionFactory();

Mybatis中創建方法

String resource="mybatis-config.xml";
InputStream  inputStream=Resources.getResourceAsStream(resource);  //加載mybatis配置文件
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);

SqlSession:是一個既可以發送SQL去查詢並返回結果,也可以用來獲得Mapper接口

hibernate和Mybatis都是使用Session工廠中的方法來創建會話的,巧合的是這兩者的方法名都為openSession

SQL Mapper:它是一個MyBatis較為推薦的方式,通過寫接口替代傳統DAO開發的方式。它是由Java接口和XML文件(或注解)構成

生命周期

SqlSessionFactoryBuilder的作用就是構建SqlSessionFactory,可以使用XML或注解的方式構建一個或多個SqlSessionFactory,構建成功之后,就失去了存在的意義,應該將其回收,所以,將其生命周期限制在方法局部中。

SqlSessionFactory是用來構建SqlSession的,如果我們多次創建同一個SqlSessionFactory,在每一次創建的時候,都會打開使用數據庫資源,那么連接資源很快就會被耗盡,所以應該使用單例模式來構建。類比於Hibernate,Hibernate也是通過SessionFactory來構建Session的,都應該是使用了工廠模式。

SqlSession相當於JDBC中的Connection,其是線程不安全的,所以在多線程的時候需要當心,在操作數據庫的時候需要注意隔離級別,數據庫鎖等問題。它在每次使用過后應該及時關閉,長期存在,就會減少數據庫連接資源,對系統性能影響很大。

Mapper是一個接口,沒有實現類,它的作用是發送SQL查詢,並返回結果,或者是通過SQL修改數據庫中的記錄,所以應該存在於一個SqlSession的事務方法范圍中。

SqlSessionFactory應該是單例的

SqlSessionFactory應該是單例的,所以我們就寫一個單例的工廠工具類,在以后與Spring整合之后就不在需要了,那時我們是在applicationContext.xml文件中配置了SqlSessionFactoryBean作為SessionFactory的。

import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class SQLSessionFactoryUtil {
    
    //SqlSessionFactory對象
    private static SqlSessionFactory sqlSessionFactory;
    //當前類的Class對象作為線程鎖
    private static final Class CLADD_LOCK=SqlSessionFactory.class;
    
    /**
     * 私有化構造
     */
    private SQLSessionFactoryUtil() {}
    
    /**
     * 構建SQLSessionFactory
     */
    public static SqlSessionFactory initSqlSessionFactory() {
        //MyBatis配置文件
        String resource="mybatis-config.xml";
        InputStream inputStream=null;
        try {
            inputStream=Resources.getResourceAsStream(resource);
        }catch (Exception e) {
            e.printStackTrace();
        }
        synchronized (CLADD_LOCK) {           //加上線程鎖,避免在多線程環境下多次初始化造成對象不唯一
          if(sqlSessionFactory==null) {
              sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
          }    
        }
        return sqlSessionFactory;
    }
    
    /**
     * 打開sqlsession
     */
    public static SqlSession openSqlSession() {
        if(sqlSessionFactory==null) {
            initSqlSessionFactory();
        }
        return sqlSessionFactory.openSession();
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM