1. 程式人生 > >MyBatis框架核心之(一)基本使用

MyBatis框架核心之(一)基本使用

一、MyBatis框架基本使用

一、      MyBatis簡介

1.MyBatis由來

MyBatis 本是apache的一個開源專案iBatis,2010年這個專案由apache software foundation 遷移到了google code,並且改名為MyBatis201311月遷移到Github

iBATIS一詞來源於“internet”“abatis”的組合,是一個基於Java持久層框架。iBATIS提供的持久層框架包括SQLMapsData Access ObjectssDAO

2.應用範圍

MyBatis 是一款優秀的持久層框架,它支援定製化 SQL、儲存過程以及高階對映。MyBatis 避免了幾乎所有的JDBC 程式碼和手動設定引數以及獲取結果集。MyBatis 可以使用簡單的 XML 或註解來配置和對映原生資訊,將介面和 Java 的 POJOs(Plain Old Java Objects,普通的Java物件)對映成資料庫中的記錄

3.主要特點:

·            簡單易學:本身就很小且簡單。沒有任何第三方依賴,最簡單安裝只要兩個jar檔案+配置幾個sql對映檔案易於學習,易於使用,通過文件和原始碼,可以比較完全的掌握它的設計思路和實現。

·            靈活:mybatis不會對應用程式或者資料庫的現有設計強加任何影響。 sql寫在xml裡,便於統一管理和優化。通過sql基本上可以實現我們不使用資料訪問框架可以實現的所有功能,或許更多。

·            解除sql與程式程式碼的耦合:通過提供DAL層,將業務邏輯和資料訪問邏輯分離,使系統的設計更清晰,更易維護,更易單元測試。sql

和程式碼的分離,提高了可維護性。

·            提供對映標籤,支援物件與資料庫的orm欄位關係對映

·            提供物件關係對映標籤,支援物件關係組建維護

·            提供xml標籤,支援編寫動態sql

4.總體流程

1)載入配置並初始化(載入配置檔案)

(2)接收呼叫請求

 (3)處理操作請求(為SQLID和傳入引數物件)

 (A)根據SQLID查詢對應的MappedStatement物件。

(B)根據傳入引數物件解析MappedStatement物件,得到最終要執行的SQL和執行傳入引數。

(C)獲取資料庫連線,根據得到的最終

SQL語句和執行傳入引數到資料庫執行,並得到執行結果。

(D)根據MappedStatement物件中的結果對映配置對得到的執行結果進行轉換處理,並得到最終的處理結果。

(E)釋放連線資源。

(4)返回處理結果將最終的處理結果返回。

二、基本配置

1.引入jar包

核心jar包

Mybatis-3.2.8.jar

相關依賴

<!-- mybatis核心jar -->

<dependency>

<groupId>org.mybatis</groupId>

<artifactId>mybatis</artifactId>

<version>3.2.8</version>

</dependency>

輔助jar包

因為使用mybatis框架後執行過程無法檢視,所以在開發階段為了方便除錯需要使用

debug級別的Log4j將程式碼的執行過程顯示出來,也可以檢視sql語句

slf4j-log4j12.jar

<!-- slf4j-log4j12 依賴 -->

    <dependency>

      <groupId>org.slf4j</groupId>

      <artifactId>slf4j-log4j12</artifactId>

      <version>1.7.5</version>

    </dependency>

mybatis.xml是 Mybatis的大腦,是重要的配置檔案

1).主要配置jdbc環境的配置

configuration 配置

environment環境變數

transactionManager 事務管理器

dataSource 資料來源

2).註冊mapper.xml

<mappers>

<!-- 註冊Mapper.xml檔案 類路徑從src出來 -->

    <mapperresource="cn/et/fuqiang/helloworld/myUserMapper.xml"/>

</mappers>

mybatis  configuration

<?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>

    <!-- 指定jdbc的配置檔案位置 -->

    <propertiesresource="cn/et/fuqiang/helloworld/jdbc.properties"></properties>

       <!-- 設定類別名方便mapper設定返回型別-->

    <typeAliases>

       <!-- 兩種設定返回型別的方法 -->

       <!-- 方法一設定返回型別  type類的路徑     alias 要使用的類別名TypeAliasRegistry.class類中檢視預設設定的類別名 -->

       <typeAliastype="cn.et.fuqiang.helloworld.User"alias="myUser"/>

       <!-- 方法二 使用預設的掃包方式 ,設定要掃包的路徑,mybatis會預設把包下面的所有類,以類名首字母小寫的方式設定別名,

(較為簡單方便) 使用時可以直接以首字母小寫去使用 -->

<package name="cn.fuqiang.entity"/>

    </typeAliases>

    <!-- 配置jdbc環境 -->

    <environmentsdefault="development">

       <environmentid="development">

           <transactionManagertype="JDBC"/>

           <!-- 配置資料庫連線資訊  el表示式${}獲取-->

           <dataSourcetype="POOLED">

              <propertyname="driver"value="${driverClass}"/>

              <propertyname="url"value="${url}"/>

              <propertyname="username"value="${user}"/>

              <propertyname="password"value="${password}"/>

           </dataSource>

       </environment>

    </environments>

    <!-- 設定mapper檔案路徑 -->

    <mappers>

       <!-- 註冊Mapper.xml檔案類路徑從src出來 -->

       <mapperresource="cn/et/fuqiang/helloworld/myUserMapper.xml"/>

    </mappers>

</configuration>

3.Sql語句的配置檔案 Mapper.xml

       1).指定namespace

為這個mapper指定一個唯一的namespacenamespace的值習慣上設定成包名+sql對映檔名,這樣就能夠保證namespace的值是唯一的

例如namespace="me.gacl.mapping.userMapper"就是me.gacl.mapping(包名)+userMapper(userMapper.xml檔案去除字尾)

<mapper namespace="myuser">

……

</mapper>

       2).在mapper標籤中可以寫想要執行的SQL語句主要標籤有

<sql id="" ></sql>

    <resultMaptype="" id=""></resultMap>

    <insertid=""></insert>

    <deleteid=""></delete>

    <updateid=""></update>

    <selectid=""></select>

配置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指定一個唯一的namespacenamespace的值習慣上設定成包名+sql對映檔名,這樣就能夠保證namespace的值是唯一的

例如namespace="me.gacl.mapping.userMapper"就是me.gacl.mapping(包名)+userMapper(userMapper.xml檔案去除字尾)

 -->

<mapper namespace="myuser">

     <!-- select標籤中編寫查詢的SQL語句,設定select標籤的id屬性為getUserid屬性值必須是唯一的,不能夠重複

使用parameterType屬性指明查詢時使用的引數型別,resultType屬性指明查詢返回的結果集型別

    resultType="me.gacl.domain.User"就表示將查詢結果封裝成一個User類的物件返回

    User類就是users表所對應的實體類

     -->

    <!--

根據id查詢得到一個user物件

        parameterType 傳入的引數可以是一個任何型別

     -->

    <selectid="selectUserById"parameterType="int"resultType="java.util.Map">

       select * from myuser where userid=#{id}

    </select>

    <insertid="insertUserByMap"parameterType="java.util.Map">

       <!--selectKey是插入語句,和修改語句中特有的標籤

       keyProperty    key的名字

       order           BEFORE/AFTER  insert語句之前或者之後

       resultType     查詢語句返回的型別

       -->

       <selectKeykeyProperty="userid"order="BEFORE"resultType="int">

          select nvl(max(userid),0)+1 from myuser

       </selectKey>

    <!-- map中獲取值    #{key}獲取對應的值 -->

       insert into myuser(userid,username,userage) values(#{userid},#{username},#{userage})

    </insert>

    <deleteid="deleteUserById"parameterType="java.lang.Integer">

       delete from myuser where userid=#{id}

    </delete>

    <updateid="updateUserByMap">

       update myuser set username=#{username},userage=#{userage} whereuserid=#{userid}

    </update>

    <!-- 練習使用typeAiase標籤(在mybatis配置檔案中使用)  建立類別名設定返回型別   預設的別名在TypeAliasRegistry.class類中檢視-->

    <selectid="selectUserGetUser"resultType="myUser">

        select * from myuser where userid=#{id}

    </select>

</mapper>

下面會常用的標籤詳細的解釋

4.java程式碼執行sql

1).獲取一個可以執行對映檔案這種sql的sqlSession

第一種方法

//mybatis的配置檔案

        String resource = "mybatis.xml";

        //使用類載入器載入mybatis的配置檔案(它也載入關聯的對映檔案)

        InputStream is = 當前類.class.getResourceAsStream(resource);

        //構建sqlSession的工廠

        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);

        //建立能執行對映檔案中sqlsqlSession

        SqlSession session = sessionFactory.openSession();

第二種方法

//mybatis的配置檔案

        String resource = "mybatis.xml";

          //使用MyBatis提供的Resources類載入mybatis的配置檔案(它也載入關聯的對映檔案)

        Reader reader = Resources.getResourceAsReader(resource);

        //構建sqlSession的工廠

        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);

        //建立能執行對映檔案中sqlsqlSession

        SqlSession session = sessionFactory.openSession();

2.執行sql語句的方式

使用session.insert/update/delete/select()執行方法

SqlSession session = getSession();

   session.insert/update/delete/select ();

這只是最基礎的用法,真正的實戰中使用介面對映完成

三、mapper.xml配置檔案中常用的sql標籤

1.select標籤屬性簡介

<select
<!--
    1. id(必須配置)
    id是名稱空間中的唯一識別符號,可被用來代表這條語句
    一個名稱空間(namespace)對應一個dao介面
    這個id也應該對應dao裡面的某個方法(sql相當於方法的實現),因此id應該與方法名一致
   -->
  id="selectUser"

<!--
    2. parapeterType(可選配置,預設由mybatis自動選擇處理)
    將要傳入語句的引數的完全限定名或別名,如果不配置,mybatis會通過ParamterHandler根據引數型別預設選擇合適的typeHandler進行處理
    paramterType 主要指定引數型別,可以是int, short, long, string等型別,也可以是複雜型別(如物件)
   -->
  parapeterType="int"

<!--
    3. resultType(resultType 與 resultMap 二選一配置)
    用來指定返回型別,指定的型別可以是基本型別,也可以是java容器,也可以是javabean
   -->

  resultType="hashmap"

<!--
    4. resultMap(resultType 與 resultMap 二選一配置)
    用於引用我們通過 resultMap 標籤定義的對映型別,這也是mybatis元件高階複雜對映的關鍵
   -->

  resultMap="USER_RESULT_MAP"

<!--
    5. flushCache(可選配置)
    將其設定為true,任何時候語句被呼叫,都會導致本地快取和二級快取被清空,預設值:false
   -->

  flushCache="false"

<!--
    6. useCache(可選配置)
    將其設定為true,會導致本條語句的結果被二級快取,預設值:對select元素為true
   -->

  useCache="true"

<!--
    7. timeout(可選配置)
    這個設定是在丟擲異常之前,驅動程式等待資料庫返回請求結果的秒數,預設值為:unset(依賴驅動)
   -->

  timeout="10000"

<!--
    8. fetchSize(可選配置)
    這是嘗試影響驅動程式每次批量返回的結果行數和這個設定值相等。預設值為:unset(依賴驅動)
   -->

  fetchSize="256"

<!--
    9. statementType(可選配置)
    STATEMENT, PREPARED或CALLABLE的一種,這會讓MyBatis使用選擇Statement, PrearedStatement或CallableStatement,預設值:PREPARED
   -->

  statementType="PREPARED"

<!--
    10. resultSetType(可選配置)
    FORWARD_ONLY,SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE 中的一個,預設值為:unset(依賴驅動)
   -->

  resultSetType="FORWORD_ONLY"

></select>

2.delete標籤

<delete

id   id(必須配置)
    id是名稱空間中的唯一識別符號,可被用來代表這條語句
    一個名稱空間(namespace)對應一個dao介面
    這個id也應該對應dao裡面的某個方法(sql相當於方法的實現),因此id應該與方法名一致
   -->
 

    parameterType=""

parapeterType(可選配置,預設由mybatis自動選擇處理)
    將要傳入語句的引數的完全限定名或別名,如果不配置,mybatis會通過ParamterHandler根據引數型別預設選擇合適的typeHandler進行處理
    paramterType 主要指定引數型別,可以是int, short, long, string等型別,也可以是複雜型別(如物件)

databaseId=""

取值範圍oracle|mysql等,表示資料庫廠家,元素內部可通過`<if test="_databaseId = 'oracle'">`來為特定資料庫指定不同的sql語句

    lang=""

    statementType="STATEMENT"

statementType(可選配置)
    STATEMENT, PREPARED或CALLABLE的一種,這會讓MyBatis使用選擇Statement, PrearedStatement或CallableStatement,預設值:STATEMENT
 

    timeout=""

timeout(可選配置)
    這個設定是在丟擲異常之前,驅動程式等待資料庫返回請求結果的秒數,預設值為:unset(依賴驅動)
 

    flushCache="true"

flushCache(可選配置)
    將其設定為true,任何時候語句被呼叫,都會導致本地快取和二級快取被清空,預設值:fals

    parameterMap=""

     ></delete>

3.inert標籤

<insertid="saveUserByMap"

parameterType,入參的全限定類名或類型別名

keyColumn,設定資料表自動生成的主鍵名。對特定資料庫(如PostgreSQL),若自動生成的主鍵不是第一個欄位則必須設定

keyProperty,預設值unset,用於設定getGeneratedKeys方法或selectKey子元素返回值將賦值到領域模型的哪個屬性中

useGeneratedKeys,取值範圍true|false(預設值),設定是否使用JDBCgetGenereatedKeys方法獲取主鍵並賦值到keyProperty設定的領域模型屬性中。MySQLSQLServer執行auto-generated key field,因此當資料庫設定好自增長主鍵後,可通過JDBCgetGeneratedKeys方法獲取。但像Oralce等不支援auto-generated key field的資料庫就不能用這種方法獲取主鍵了

statementType,取值範圍STATEMENT,PREPARED(預設值),CALLABLE

flushCache,取值範圍true(預設值)|false,設定執行該操作後是否會清空二級快取和本地快取

timeout預設為unset(依賴jdbc驅動器的設定),設定執行該操作的最大時限,超時將拋異常

databaseId,取值範圍oracle|mysql等,表示資料庫廠家,元素內部可通過`<if test="_databaseId = 'oracle'">`來為特定資料庫指定不同的sql語句

> 

</insert>

4.update標籤

<updateid=""

parameterType,入參的全限定類名或類型別名

keyColumn,設定資料表自動生成的主鍵名。對特定資料庫(如PostgreSQL),若自動生成的主鍵不是第一個欄位則必須設定

keyProperty,預設值unset,用於設定getGeneratedKeys方法或selectKey子元素返回值將賦值到領域模型的哪個屬性中

useGeneratedKeys,取值範圍true|false(預設值),設定是否使用JDBCgetGenereatedKeys方法獲取主鍵並賦值到keyProperty設定的領域模型屬性中。MySQLSQLServer執行auto-generated key field,因此當資料庫設定好自增長主鍵後,可通過JDBCgetGeneratedKeys方法獲取。但像Oralce等不支援auto-generated key field的資料庫就不能用這種方法獲取主鍵了

statementType,取值範圍STATEMENT,PREPARED(預設值),CALLABLE

flushCache,取值範圍true(預設值)|false,設定執行該操作後是否會清空二級快取和本地快取

timeout,預設為unset(依賴jdbc驅動器的設定),設定執行該操作的最大時限,超時將拋異常

databaseId,取值範圍oracle|mysql等,表示資料庫廠家,元素內部可通過`<if test="_databaseId = 'oracle'">`來為特定資料庫指定不同的sql語句

    ></update>

5.selectKey標籤

selectKey標籤只在insert標籤和update標籤中存在

作用:在insert元素和update元素中插入查詢語句。

其屬性如下:

keyProperty,預設值unset,用於設定getGeneratedKeys方法或selectKey子元素返回值將賦值到領域模型的哪個屬性中

resultTypekeyPropety所指向的屬性類全限定類名或類型別名

order屬性,取值範圍BEFORE|AFTER,指定是在insert語句前還是後執行selectKey操作

statementType,取值範圍STATEMENT,PREPARED(預設值),CALLABLE

例項在插入的時候oracle沒有自增可以用子查詢或查詢序列

<insertid="saveUserByMap">

       <selectKeykeyProperty="userid"order="BEFORE"resultType="int">

           select nvl(max(userid),0)+1 from myuser

       </selectKey>

       insert into myuser(userid,username,userage) values(#{userid},#{username},#{userage})

    </insert>

6.重用sql標籤

<sqlid="userColumns">id,username,password</sql>

這個 SQL 片段可以被包含在其他語句中

<selectid="selectProjectList"paramertType="int"resultType="hashmap">

  SELECT

      <includerefid="userColumns"/>

  FROM

      t_project_002_project_info

</select>

四、sql語句的編寫與引數的傳遞

Mapper.xml中編寫sql語句

與標準的sql語句一樣

如:Select * fromtablename where column=#{0}/${0}

1.獲取變數

sql語句中獲取引數有多中方式

不能根據索引取值因為el表示式會把索引當運算的數字

el表示式

${} 只能用在形參中指定的名稱來獲取  param1 名字

(獲取值得方法相當於字串的拼接如果是字串的話要用引號)

ognl表示式

#{} 可以根據傳入的變數名來獲取值,也可以根據上面兩種方式(獲取值得方法是防注入的,?會用問號代替)

預設是根據形參的索引從0開始

2.可以設定

parameterType 設定傳入的引數型別

可以不設定直接使用即可

3.如果是查詢語句需要設定返回型別resultType

(在TypeAliasRegistry.class中設定了許多類別名,填寫型別的時候可以直接寫別名)

4.java程式碼傳入變數

//@Test

    public void updateUserByMap() {

       SqlSession session = getSession();

       Map<String,Object> updateMap = new HashMap<String,Object>();

       updateMap.put("userid", 1);

        updateMap.put("username","wfq666");

        updateMap.put("userage", 5858518);

        int update = session.update("updateUserByMap",updateMap);

        System.out.println(update);

        session.commit();

    }

    //@Test

    public void deleteUserById() {

       SqlSession session = getSession();

       int delete = session.delete("deleteUserById", 1);

        System.out.println(delete);

        session.commit();

    }

    //@Test

    public void insertUserByMap() {

       SqlSession session = getSession();

       //建立需要插入的值,key是列名,value 是值

        Map<String,Object> insertMap = new HashMap<String,Object>();

        //新插入資訊只需要寫入使用者名稱和年齡,id使用selectKey標籤新增

        insertMap.put("username","wfq2");

        insertMap.put("userage", 100);

        int insert = session.insert("myuser.insertUserByMap",insertMap);

        System.out.println(insert);

        session.commit();

    }

    //@Test

    public void selectUserById() {

       SqlSession session = getSession();

       /**

         * 對映sql的標識字串,

         * myuser.selectUsermyUserMapper.xml檔案中mapper標籤的namespace屬性的值,

         * getUserselect標籤的id屬性值,通過select標籤的id屬性值就可以找到要執行的SQL

         */

        //執行查詢返回一個唯一user物件的sql

        Map<String,Object> map= session.selectOne("myuser.selectUserById", 1);

        System.out.println(map);

    }

    @Test

    public void selectUserGetUser() {

       SqlSession session = getSession();

        //執行查詢返回一個唯一user