java框架學習日誌-13(Mybatis基本概念和簡單的例子)

在mybatis初次學習Mybatis的時候,遇到了不少問題,雖然阿里雲的視頻有教學,可是視頻教學所使用的軟件和我本身使用的軟件不用,我本身用的數據庫是oracle數據庫,開發環境是idea。並且視頻中只是將mybatis這一部分抽出來說,實際上還須要一些知識儲備,我自己是瞭解了oralce基本的操做後,再開始學習Mybatis的,過程可能會走不少彎路,和遇到不少不理解或者理解錯誤的地方,如今暫時只能囫圇吞棗,等有必定了解後,再回頭看看,總結和更改個人一些認知。java


Mybatis是什麼?mysql

mybatis是基於java持久層的框架,持久層就是把業務數據存儲到硬盤,在斷電或者重啓系統後,仍然能夠讀取這些數據。就好像玩遊戲須要保存進度同樣,否則每次都須要重頭開始玩。java互聯網能夠經過mybatis框架訪問數據庫。程序員


沒有Mybatis以前怎麼訪問數據庫?
在早期,若是須要訪問oracle數據庫,須要專門寫一個程序,若是訪問mysql,又須要專門寫一個程序,後來就有了jdbc(Java DataBase Connectivity,java數據庫鏈接),jdbc是一種用來執行sql語句的java api,能夠爲多種數據庫提供統一的訪問。簡單來講,它能夠與數據庫創建鏈接,發生操做數據庫的語句,處理結果。可是jdbc的工做量也是很大的,並且很很差用,因此出現了ORM(Object relational Mapping,對象關係映射 ),咱們把POJO對象和數據庫表相互映射的框架稱爲ORM,mybatis和hibernate都是ORM框架,並且由於mybatis對jdbc的封裝很好,並且很靈活,因此幾乎能夠徹底取代jdbc。sql


Mybatis的優勢
mybatis有三個優勢:數據庫

  1. 不屏蔽SQL,這樣能夠更加精肯定位SQL語句,能夠對其進行優化和改造。
  2. 提供更強大靈活的映射機制。知足了常常變換的互聯網應用的要求。
  3. 提供了使用Mapper的接口編程,簡化了工做。

除了mybatis,還有其餘框架,好比Hibernate,hibernate與mybatis一樣是java持久層的框架,均可以經過註解或者xml提供映射規則。可是hibernate不須要編寫SQL就能夠經過映射關係去操做數據庫,這樣程序員不須要精通SQL,只須要操做POJO(Plain Ordinary Java Object,簡單的java對象)就能夠操做對應的數據庫的表了,可是這也是缺點,當多表關聯超過3個,hibernate的性能就會丟失,而mybatis能夠自定義SQL,映射關係,因此,他比hibernate更加靈活。可是mybatis也有缺點,由於須要編寫SQL和映射規則,因此工做量比hibernate多。因此若是系統對性能要求不高時,能夠實用hibernate,若是對性能要求高可使用mybatis。apache


Mybatis的核心組件
首先先了解mybatis的核心組件有哪些,而後再去了解這些組件的做用和實現原理。mybatis的核心組件分爲4個部分:編程

  • SqlSessionFactoryBuilder(構造器)——它會根據配置或者代碼生成SqlSessionFactory。
  • SqlSessionFactory(工廠接口)——用來生成SqlSession。
  • SqlSession(會話)——既能夠發送SQl並執行返回結果,也能夠獲取Mapper的接口。
  • SQL Mapper(映射器)——MyBatis新設計存在的組件,由一個java接口和XML文件(或者註解)構成。須要給出對應的SQL和映射規則。負責發送SQL,並返回結果。

Mybatis的配置
開始配置以前,須要準備Mybatis環境,我使用的mybatis版本是3.5.0.而後導入相關jar包。
既然用的mybatis,固然須要mybatis的核心jar包,和lib文件下的jar包,以下圖:


由於鏈接的是oracle數據庫,因此還須要oracle的jar包,個人地址是:H:\app\zheng\product\12.2.0\dbhome_1\jdbc\lib
jar包都導入項目後,才能夠正式開始。c#

1. 建立SqlSessionFactory

首先獲取一個SqlSessionFactory,,Mybatis提供了SqlSessionFactoryBuilder來生成SqlSessionfactory,能夠經過XML配置文件或者java代碼去生成SqlSessionFactory。這裏建議用XML來生成SqlSessionFactory,由於代碼的方式會在須要修改的時候比較麻煩。
在mybaits中,由於這是基礎配置文件(XML有兩類,一類是基礎配置文件,主要是配置上下文參數和運行環境,下面的XML就是基礎配置文件,另外一類就是映射文件,後面會用到),因此取名mybaits.cfg.xml。mybatis說明文檔中XML代碼以下:

大部分地方複製過來就能夠了,只須要改一下數據源的配置,driver填OracleDriver這個驅動器類的全限定名。url的寫法有多種,username,password就是鏈接數據庫用的用戶,和密碼,這裏就不詳細說明了。 <mappers>元素表明引入哪些映射器,咱們後面會用新建一個叫product.mapper.xml的映射文件。因此這裏寫上這個映射文件。稍微改一下XML文件,代碼以下:api

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development"><!--配置環境-->
        <!--數據庫環境-->
        <environment id="development"><!--環境變量-->
            <transactionManager type="JDBC"/><!--事物管理器-->
            <dataSource type="POOLED"><!--數據源-->
                <property name="driver" value="oracle.jdbc.OracleDriver"/>
                <property name="url" value="jdbc:oracle:thin:@//DESKTOP-997L86A:1521/orcl"/>
                <property name="username" value="c##scott"/>
                <property name="password" value="tiger"/>
            </dataSource>
        </environment>
    </environments>
    <!--映射文件-->
    <mappers>
        <mapper resource="product.mapper.xml"/>
    </mappers>
</configuration>

而後是去生成SqlSessionFactory了。說明文檔中寫了能夠用下面的代碼去生成SqlSessionFactory:

固然這裏也須要改一下,把resource換成本身剛纔寫的XML文件就好了。而後我是把這個方法寫在一個getSqlSessionFactory靜態方法裏面的,這樣能夠方法生成SqlSessionFactory。新建MyBatisUtil類,代碼以下:session

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class MyBatisUtil {
    public static SqlSessionFactory getSqlSessionFactory() throws IOException {

        String resource = "mybatis.cfg.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        return sqlSessionFactory;

    }
}
1. 建立SqlSession

而後是建立SqlSession,有了SqlSessionFactory後,建立SqlSession就很簡單了,一行代碼就能夠,咱們一樣把它寫在一個靜態方法裏面,和上面的getSqlSessionFactory()方法放在一塊兒。代碼以下:

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class MyBatisUtil {
    public static SqlSessionFactory getSqlSessionFactory() throws IOException {

        String resource = "mybatis.cfg.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        return sqlSessionFactory;

    }
    public static SqlSession getSqlSession() throws IOException {
        SqlSessionFactory sqlSessionFactory=getSqlSessionFactory();
        return sqlSessionFactory.openSession();
    }
}
1. 建立映射器

以前說過,mybatis中XML有兩類,一個是以前寫的基礎配置文件,還有一個就是接下來的映射器文件。映射文件能夠用XML或者註解實現,這裏咱們一樣推薦使用XML實現,由於若是同時使用XML和註解定義的話,XML會覆蓋掉註解方式。並且當Sql語句比較複雜時,使用註解方式也會下降可讀性,靈活性也不如XML。
映射器的主要就是將SQL查詢到的結果映射爲一個POJO,或者將POJO的數據插入數據庫,因此須要先定義一個POJO。
這是用來測試的Testtable表格,只有一個id和名字。

對應的POJO:

public class Testtable {
    private Integer id;
    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

用XML定義映射器分爲兩個部分:接口和XML。我在看視頻的時候,老師一開始是沒有講接口的,因此這裏就先不使用接口來建立映射器。那麼在有了POJO後,只須要配置一下XML文件就能夠實現映射器了。product.mapper.xml文件以下:

<?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="ProductMapper">
    <select id="selectTesttable_id" parameterType="int" resultType="Testtable">
        select * from Testtable where id = #{id}
    </select>
    <select id="selectTesttable_name" parameterType="String" resultType="Testtable">
        select * from Testtable where name = #{id}
    </select>
</mapper>

<mapper namespace="ProductMapper">所使用的是接口的全限定名,由於沒有接口,因此這裏隨便寫。
<select>元素就是代表查詢語句了,id標識哪一條SQL。
parameterType是傳遞進去的參數類型,好像不寫也能夠。
resultType是返回類型。
#{id}表示傳遞進去的參數。
我這裏寫了兩條SQL語句,分別是查詢條件爲id的selectTesttable_id,和查詢條件爲name的selectTesttable_name。Mybatis提供自動映射,能夠把SQl返回的列名和POJO對應起來,


使用SqlSession發送sql
有了映射器後,就能夠經過SqlSession發送SQL了。代碼以下:

import org.apache.ibatis.session.SqlSession;

import java.io.IOException;

public class Test {
    public static void main(String[] args) throws IOException {

        SqlSession sqlSession=MyBatisUtil.getSqlSession();//獲取SqlSession
        Testtable testtable1=sqlSession.selectOne("ProductMapper.selectTesttable_id",003);//使用ProductMapper配置文件下的selectTesttable_id語句,查詢條件爲where id = 003
        Testtable testtable2=sqlSession.selectOne("ProductMapper.selectTesttable_name","菜刀");//使用ProductMapper配置文件下的selectTesttable_name,查詢條件爲where name = ‘菜刀’
        System.out.println("id="+testtable1.getId()+"名字="+testtable1.getName());
        System.out.println("id="+testtable2.getId()+"名字="+testtable2.getName());
        sqlSession.close();//關閉資源。

    }
}

查詢結果以下

selectOne方法有兩個參數,一個String對象,和一個Object對象,String是由命名空間加SQL id組成的。由此來肯定惟一一條SQL語句,Object由以前的<select>元素中的parameterType肯定的。 selectOne方法會返回一個Testtable類型的對象,書中用了轉換:

Testtable testtable1=(Testtable)sqlSession.selectOne("ProductMapper.selectTesttable_id",003);

可是實際上不用轉換,能夠直接使用。
注意必定要sqlSession.close();關閉資源,若是不關閉,數據庫的鏈接資源很快就會耗費逛,整個系統就會陷入癱瘓。這就是直接用SqlSession發送SQL語句,接下來使用SqlSession去獲取Mapper接口,經過Mapper接口發送語句。


使用Mapper接口發送sql
既然使用Mapper接口發送語句,那麼就須要先定義一個映射器接口。代碼以下

public interface TesttableMapper {
    public Testtable selectTesttable_id(int id);
}

這個方法的名字就是SELECT語句id的名字,參數就是#{id}。
修改product.mapper.xml文件裏的<mapper namespace="ProductMapper">,改爲新建的接口名。<mapper namespace="TesttableMapper">
測試代碼以下:

TesttableMapper testtableMapper=sqlSession.getMapper(TesttableMapper.class);
        Testtable testtable3=testtableMapper.selectTesttable_id(002);
        System.out.println("id="+testtable3.getId()+"  名字="+testtable3.getName());
        sqlSession.close();


注意TesttableMapper這個接口是沒有實現類的,可是mybatis運用了動態代理技術,爲這個接口生成了一個代理對象。使得接口也能運行起來。


兩種發送sql的方式的區別 使用Mapper發送SQl能夠提升可讀性,更能體現業務邏輯testtableMapper.selectTesttable_id(002)的寫法也更符合面向對象的語言。並且使用Mapper,IDE會提示報錯。Sqlsession去發生SQL語言只會在運行期間報錯。如今基本上都是使用Mapper接口編程。

相關文章
相關標籤/搜索