MyBatis自學筆記

引入mybatis後的代碼結構

mapper.xml-->dao接口-->service-->Controller

Dao接口的實現類對象由sqlSession.getMapper(接口名.class)動態構建出來

什麼是mybatis:

MyBatis是支持普通SQL查詢,存儲過程和高級映射的優秀持久層框架。MyBatis消除了幾乎所有的JDBC代碼和參數的手工設置以及結果集的檢索。MyBatis使用簡單的XML或註解用於配置和原始映射,將接口和Java的POJOs(Plan Old Java Objects,普通的Java對象)映射成數據庫中的記錄.
 

 

關於映射文件

總的配置文件


Configuration.xml: 是 mybatis 用來建立 sessionFactory 用的,裏面主要包含了數據庫連接相關東西,還有 java 類所對應的別名,比如 <typeAlias alias(別名)="User" type="com.yihaomen.mybatis.model.User"/> 這個別名非常重要,你在 具體的類的映射中,比如User.xml 中 resultType 就是對應這裏的。要保持一致,當然這裏的 resultType 還有另外單獨的定義方式,後面再說。類的映射配置文件需要在這裏註冊

Mapper映射文件:裏面主要是定義各種SQL 語句,以及這些語句的參數,以及要返回的類型等.

配置順序:

在配置mybatis-config.xml時,其中的節點是有順序的,配置順序依次爲:

properties/settings/typeAliases/typeHandlers/objectFactory/objectWrapperFactory/plugins/environments/databaseIdProvider/mappers
 

nameSpace

namespase有三種綁定方式,一般用綁定接口的方式。

命名:namespace的值習慣上設置成包名+sql映射文件名,這樣就能夠保證namespace的值是唯一的。

在大型項目中,可能存在大量的SQL語句,這時候爲每個SQL語句起一個唯一的標識(ID)就變得並不容易了。爲了解決這個問題,在MyBatis中,可以爲每個映射文件起一個唯一的命名空間,這樣定義在這個映射文件中的每個SQL語句就成了定義在這個命名空間中的一個ID。只要我們能夠保證每個命名空間中這個ID是唯一的,即使在不同映射文件中的語句ID相同,也不會再產生衝突了。

在mybatis中,映射文件中的namespace是用於綁定Dao接口的,即面向接口編程。

當你的namespace綁定接口後,你可以不用寫接口實現類,mybatis會通過該綁定自動

幫你找到對應要執行的SQL語句

假設定義了IArticeDAO接口

public interface IArticleDAO

{

   List<Article> selectAllArticle();

}

對於映射文件如下:

<mapper namespace="IArticleDAO">

       <select id="selectAllArticle" resultType="article">//article爲Java類

                  SELECT t.* FROM T_article t WHERE t.flag = '1' ORDER BY t.createtime DESC

      </select>

請注意接口中的方法與映射文件中的SQL語句的ID一一對應 。

則在代碼中可以直接使用IArticeDAO面向接口編程而不需要再編寫實現類。

 

別名的使用:

MyBatis中如果每次配置類名都要寫全稱也太不友好了,我們可以通過在主配置文件中配置別名,就不再需要指定完整的包名了。

用法:

自定義別名:

 

在SqlMapConfig.xml(MyBatis核心配置文件中的配置)中配置:   

<typeAliases>

        <!-- 定義單個類的別名,這裏別名爲user,在parameterType和resultType裏面用的時候,不區分大小寫,User,user,UsER,UseR都可以 -->

        <typeAlias type="cn.domarvel.entity.User" alias="user"/>

        <!-- 批量定義別名(常用),這裏別名爲類名User,在parameterType和resultType裏面用的時候,不區分大小寫,User,user,UsER,UseR都可以,

        注意:

            這裏不支持通配符,比如:“*”,“_”,“?”

         -->

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

    </typeAliases>

但是如果每一個實體類都這樣配置還是有點麻煩這時我們可以直接指定package的名字, mybatis會自動掃描指定包下面的javabean,並且默認設置一個別名,默認的名字爲: javabean 的首字母小寫的非限定類名來作爲它的別名(其實別名是不去分大小寫的)。也可在javabean 加上註解@Alias 來自定義別名, 例如: @Alias(student)

這樣,在Mapper中我們就不用每次配置都寫類的全名了,但是有一個例外,那就是namespace

namespace屬性

<typeAliases>

    <package name="com.domain"/>

</typeAliases>

在MyBatis中,Mapper中的namespace用於綁定Dao接口的,即面向接口編程。

 

它的好處在於當使用了namespace之後就可以不用寫接口實現類,業務邏輯會直接通過這個綁定尋找到相對應的SQL語句進行對應的數據處理

 

以接口的方式編程(即面向接口編程)

接口式編程,我們可以簡單的理解爲Mybatis爲映射文件定義了一個代理接口,以後全部通過這個接口來和映射文件交互,而不再是使用以前方法。映射文件如何知道自己被哪個接口代理呢?這裏就是通過名稱空間來實現的,映射文件的名稱空間再也不是隨心所欲的定義的了,而是要使用代理接口的全限定名作爲其名稱空間。所謂全限定名,就是接口所在的包名加上接口名稱。

// 01查看全部信息getMapper()接口類的方法名要和小配置的id一樣

    @Test

    public void testSelectAll() {

        SqlSession session = factory.openSession();

        //用的是弱類型========實體類.小配置裏面的Id名稱============字符串

        /*List<Dept> list = session.selectList("cn.happy.dao.IDeptDao.getAllDept");

        for (Dept dept : list) {

            System.out.println(dept.getDeptName());

        }*/

   

         // 用getMapper方法HIbernate幫我們在內存中代理出一個接口的實現類======相當於強類型

         //mapper是一個實現類對象

        IDeptDao mapper = session.getMapper(IDeptDao.class);

        List<Dept> list = mapper.getAllDept();

        for (Dept dept : list) {

            System.out.println(dept.getDeptName());

        }

優點:

  • 調用方法明確,因爲我們調用的是接口中的某個具體方法,而不再是通過一個字符串來指定執行映射文件中的某個SQL語句了
  • 傳入參數和返回值都不再是Object了,這樣就可以在代碼編寫階段確保傳入的參數類型是正確的,也不再需要對返回值進行強類型轉換了
  • 最主要的一點,就是將來Mybatis遇到了Spring,更能發揮出接口式編程的強大潛力。

實現數據的增刪改查

resultMap:

可以說是MyBatis的精華所在!

在深入ResultMap標籤前,我們需要了解從SQL查詢結果集到JavaBean或POJO實體的過程。

 

  1. 通過JDBC查詢得到ResultSet對象

 

  2. 遍歷ResultSet對象並將每行數據暫存到HashMap實例中,以結果集的字段名或字段別名爲鍵,以字段值爲值

 

  3. 根據ResultMap標籤的type屬性通過反射實例化領域模型

 

  4. 根據ResultMap標籤的type屬性和id、result等標籤信息將HashMap中的鍵值對,填充到領域模型實例中並返回

不同的xml文件相互引用resultMap

利用命名空間+resultMapID就可以直接引用其他Mapper文件的resultMap,其中resultMapcolumn在本文件中也有用,也可以對應sql語句中的column別名。

對column(字段)和property(屬性)的理解

Column對應數據庫中的字段名,property對應Javabean的屬性

 

 

Select相關屬性:

select元素有很多屬性(這裏說用的比較多的):

 

id:命名空間唯一標識,可以被用來引用這條語句

parameterType:傳入參數的類型

resultType:返回值類型(這裏注意下集合類型,應該是集合可以包含的類型,不能是集合本身),重要:使用resultType或resultMap,但不能同時使用。

resultMap:命名引用外部的resultMap,其名稱要和外部的resultMap元素的ID名稱一致,用於映射其結果到實體類指定對象中

實例:

<select id="getStudent" resultMap="getStudentRM">

  SELECT ID, Name, Age

    FROM TStudent

</select>

<resultMap id="getStudentRM" type="EStudnet">

  <id property="id" column="ID"/>

  <result property="studentName" column="Name"/>

  <result property="studentAge" column="Age"/>

</resultMap>

若數據庫中的字段與javabean中的屬性相同,則:

<resultMap type="com.test" id="testResultMap">

</resultMap>

 

<select id="selectList"  resultMap="testResultMap">

        select * from test1

</select>

子元素說明:

 

id元素 ,用於設置主鍵字段與領域模型屬性的映射關係

result元素 ,用於設置普通字段與領域模型屬性的映射關係

 

那麼什麼時候我們知道使用resultMap,什麼時候又使用resultType呢?

 

①當去select一張表時,可以使用resultType,這些情況下,MyBatis會在幕後自動創建一個ReusltMap,基於屬性名來映射到JavaBean屬性上

②所以在使用resultMap時,就必須要寫上resultMap相對應的xml

③爲了方便我們開發出錯,在沒有特別要求的情況下,column名可以完全和property名稱一致,否則當我們沒有對應上的時候,數據庫匹配不到,會將某某參數值變爲大寫,導致我們本來獲取小寫的參數名,結果沒有獲取到,後臺報錯,得不償失啊!

 

Mapper標籤詳解:

https://blog.csdn.net/Marvel__Dead/article/details/69265316

 

 

目錄結構

Web項目中接口和接口的配置文件在同一個包中

Maven項目中:

爲了實現在maven默認環境下打包時,Mybatis的接口和mapper文件在同一包中,可以通過將接口文件放在src/main/java某個包中,而在src/main/resources目錄中建立同樣的包,這是一種約定優於配置的方式,這樣在maven打包的時候就會將src/main/java和src/main/resources相同包下的文件合併到同一包中。

 

 

MyBatisUtil:

package me.gacl.util;



import java.io.InputStream;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;



public class MyBatisUtil {



    /**

     * 獲取SqlSessionFactory

     * @return SqlSessionFactory

     */

    public static SqlSessionFactory getSqlSessionFactory() {//static 加載類的時候一併加載進去

        String resource = "conf.xml";

//加載文件

        InputStream is = MyBatisUtil.class.getClassLoader().getResourceAsStream(resource);

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

        return factory;

    }

   

    /**

     * 獲取SqlSession

     * @return SqlSession

     */

    public static SqlSession getSqlSession() {

        return getSqlSessionFactory().openSession();

    }

   

    /**

     * 獲取SqlSession

     * @param isAutoCommit

     *         true 表示創建的SqlSession對象在執行完SQL之後會自動提交事務

     *         false 表示創建的SqlSession對象在執行完SQL之後不會自動提交事務,這時就需要我們手動調用sqlSession.commit()提交事務

     * @return SqlSession

     */

    public static SqlSession getSqlSession(boolean isAutoCommit) {

        return getSqlSessionFactory().openSession(isAutoCommit);

    }

}

動態SQL語句:

If語句:

test屬性中做常規判斷,裏面不能寫 < 和 > ,也不能用&&,可以用and、 or 、||

 

 

Test屬性中

SQL語句中

gt

>

&gt;

gte

>=

&gt;=

lt

<

&lt;

lte

<=

&lt;=

模糊查詢:

MySql中要用concat

and name like concat('%',#{name},'%')

引入參數:

一個參數時:(mybatis會自動識別)

若parameterType中爲int、string等Java固有類型,即傳入的參數爲非JavaBean類,則寫xml文件時應用_parameter代替原參數。

多個參數時:

@Select("select * from tb_sender where username=#{username} and password = #{password}")

Sender selectSenderByUsernameAndPassword(@Param("username") String username,@Param("password") String password);

 

MySql數據庫級聯操作:

MySQL支持外鍵的存儲引擎只有InnoDB,在創建外鍵的時候,要求父表必須有對應的索引,子表在創建外鍵的時候也會自動創建對應的索引。在創建索引的時候,可以指定在刪除、更新父表時,對子表進行的相應操作,包括RESTRICT、NO ACTION、SET NULL和CASCADE。其中RESTRICT和NO ACTION相同,是指在子表有關聯記錄的情況下父表不能更新;CASCADE表示父表在更新或者刪除時,更新或者刪除子表對應記錄;SET NULL則是表示父表在更新或者刪除的時候,子表的對應字段被SET NULL。

 

關聯查詢

一對一:

 

 

一對多:

 

 

多對多:

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章