MyBatis

MyBatis概述

  • ORM(Object Relational Mapping)持久層框架的佼佼者
  • 真正實(shí)現(xiàn)了SQL語(yǔ)句與Java代碼的分離
  • 優(yōu)秀的功能 動(dòng)態(tài)SQL, 緩存, 插件-pageHelper等

Mybatis入?yún)⑻幚?/h2>
  • 單參數(shù)Mybatis不做特殊處理, 直接取出參數(shù)賦值給xml文件, 如:#{id}, 當(dāng)傳遞的為單參數(shù)的時(shí)候#{xxx}, Mybatis不會(huì)關(guān)心名稱.
  • 多參數(shù)
    • 默認(rèn)傳遞為多參數(shù)的時(shí)候, Mybatis會(huì)將參數(shù)起名為: arg0, arg1, param1, param2
    • JavaBean傳遞參數(shù)
      • 如果多個(gè)參數(shù)是業(yè)務(wù)邏輯的數(shù)據(jù)模型, 那么可以直接傳入pojo
      • Xml文件中直接通過(guò)#{屬性名}取出對(duì)應(yīng)的值
    • Map接口
      • 如果參數(shù)個(gè)數(shù)比較少, 而且沒(méi)有對(duì)應(yīng)的Javabea n, 可以封裝成Map
      • Xml文件中: #{key}取出map中對(duì)應(yīng)的值
    • 注解@param
      public Person getPersonInfo(@Param("username") String username, @Param("id") Integer id);
      
      如果多個(gè)參數(shù)只使用了一個(gè)@Param, 那么Mybatis會(huì)自動(dòng)啟用默認(rèn)的規(guī)則, 即第二個(gè)參數(shù)為Param1
  • 集合類(lèi)型參數(shù)處理
    • 當(dāng)參數(shù)為Collection接口, 轉(zhuǎn)換為Map, Mapkeycollection
    public Person getPersonByCollection(Collection list);
    
    <select id="getPersonByCollection" resultType="person">
        select * from person where id=#{list[0]}
    </select>
    
    • 如果參數(shù)類(lèi)型為List接口, 除了collection以外, list也可以作為key
    public Person getPersonByCollection(List list);
    
    <select id="getPersonByCollection" resultType="person">
        select * from person where id=#{list[0]}
    </select>
    
    • 如果參數(shù)為數(shù)組, 也會(huì)轉(zhuǎn)換為Map, Mapkeyarray
    public Person getPersonByArray(int[] ids);
    
    <select id="getPersonByArray" resultType="person">
        select * from person where id=#{array[0]}
    </select>
    
    • 以上均可以使用param來(lái)處理
    public Person getPersonByArray(@Param("idsc") int[] ids);
    
    <select id="getPersonByArray" resultType="person">
        select * from person where id=#{idsc[0]}
    </select>
    
  • Mybatis動(dòng)態(tài)SQLforeach
    • 特點(diǎn)
      循環(huán)遍歷集合, 支持?jǐn)?shù)組和List, Set接口, 對(duì)其提供遍歷功能
    • 常用配置
      • collection: 需要遍歷的集合
      • item: 當(dāng)前集合的對(duì)象
      • index: 當(dāng)前遍歷的對(duì)象的索引
      • openclose: 當(dāng)前打開(kāi)和關(guān)閉的字符串
      • separator: 每個(gè)元素的分割符
    • 代碼示例
    // 根據(jù)傳入的id的數(shù)組, 查詢id在數(shù)組里的用戶, 返回一個(gè)List列表
    <select id="getPersonListByIds" resultType="person">
        select * from person where id in
        <foreach collection="array" item="item" index="i" open="(" close=")"  separator=",">
            #{item}
        </foreach>
    </select>
    

Mybatis批量插入數(shù)據(jù)

  • 借助foreach標(biāo)簽使用insert into table values()
 // 根據(jù)傳入的id的數(shù)組, 查詢id在數(shù)組里的用戶, 返回一個(gè)List列表
 <insert id="addPersons">
     insert into person(username, email, gender) values
     <foreach collection="persons" item="item" index="i"   separator=",">
         (#{item.username}, #{item.email}, #{item.gender})
     </foreach>
 </insert >
  • 借助ExecutorBatch批量添加, 可與Spring框架整合

Mybatis攔截器與分頁(yè)

  • Mybatis四大對(duì)象
    • ParamterHandler: 處理SQL的參數(shù)對(duì)象
    • ResultSetHandler: 處理SQL的返回結(jié)果集
    • StatementHandler: 數(shù)據(jù)庫(kù)的處理對(duì)象, 用于執(zhí)行SQL
    • Executor: Mybatis的執(zhí)行器, 用于執(zhí)行增刪改查
  • Mybatis插件原理
    • Mybatis的插件借助于責(zé)任鏈的模式進(jìn)行對(duì)攔截的處理
    • 使用動(dòng)態(tài)代理對(duì)目標(biāo)對(duì)象進(jìn)行包裝, 達(dá)到攔截的目的
    • 作用于Mybatis的作用于對(duì)象之上
  • Interceptor
// 攔截目標(biāo)對(duì)象的目標(biāo)方法
public Object intercept(Invocation invocation) throws Throwable {
    System.out.println("攔截的目標(biāo)對(duì)象" + invocation.getTarget());
    Object object = invocation.proceed();
    return object;
}
// 包裝目標(biāo)對(duì)象, 為目標(biāo)對(duì)象創(chuàng)建代理對(duì)象的
public Object plugin(Object o) {
    System.out.println("將要包裝的目標(biāo)對(duì)象" + o);
    return Plugin.wrap(o, this);
}
// 設(shè)置屬性, 在配置文件中聲明攔截器, 初始化的屬性
public void setProperties(Properties properties) {
      System.out.println("插件配置的初始化參數(shù)" + properties);
}
  • 分頁(yè)
    • 分頁(yè)的分類(lèi): 內(nèi)存分頁(yè)和物理分頁(yè)
    • Mysql自帶的Limit關(guān)鍵字
  • PageHelper
// 獲取第一頁(yè) 數(shù)量為10個(gè)
Page<Object> page = PageHelper.startPage(1, 10);
// 從數(shù)據(jù)庫(kù)進(jìn)行查詢
List<Person> persons = personMapper.getAllPersons();
// 獲取導(dǎo)航頁(yè)面, 經(jīng)常用于頁(yè)面底部顯示導(dǎo)航123....10頁(yè)
PageInfo pageInfo = new PageInfo(persons, navigatePages: 9)

page.getPageNum(); // 獲取當(dāng)前的頁(yè)面
page.getTotal(); // 獲取總共多少頁(yè)
page.getPageSize; // 獲取一頁(yè)有多少數(shù)量

pageInfo.isIsFirstPage(); // 是否是第一頁(yè)
pageInfo.getPages(); // 總共多少頁(yè)
// PageInfo pageInfo = new PageInfo(persons, navigatePages: 9) 輸出nums為1, 2, 3,4,5,6,7,8,9
int [] nums = pageInfo.getNavigatepageNums(); // 獲取頁(yè)面

  • Mybatis分頁(yè)應(yīng)用
public ServerResponse getProductList(int pageNum, int pageSize) {
        // mybatis pageHelper的使用
        // 1. startPage->start
        PageHelper.startPage(pageNum, pageSize);
        // 2. 填充sql查詢邏輯
        List<Product> productList = productMapper.selectProductList();
        List<ProductListVo> productListVos = new ArrayList<ProductListVo>();
        for (Product product : productList) {
            ProductListVo productListVo = assembleProduct(product);
            productListVos.add(productListVo);
        }
        // 3. pageHelper->收尾
        PageInfo pageResult = new PageInfo(productList);
        pageResult.setList(productListVos);
        return ServerResponse.createBySuccess(pageResult);
    }

Mybaitis自動(dòng)生成Mapper映射文件和dao層實(shí)體類(lèi)

1. 在pom.xml文件里新增Mybatis的generator

  <build>
    <finalName>項(xiàng)目名</finalName>
    <plugins>
      <plugin>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-maven-plugin</artifactId>
        <version>1.3.2</version>
        <configuration>
          <verbose>true</verbose>
          <overwrite>true</overwrite>
        </configuration>
      </plugin>
    </build>

2.在resources包下面添加generator.properties和generatorConfig.xml, 其中g(shù)enerator.properties是數(shù)據(jù)庫(kù)配置文件

generator.properties
db.initialSize = 20
db.maxActive = 50
db.maxIdle = 20
db.minIdle = 10
db.maxWait = 10
db.defaultAutoCommit = true
db.minEvictableIdleTimeMillis = 3600000

db.driverLocation=/Volumes/ruirui/mysql-connector/mysql-connector-java-5.0
 .8-bin.jar // 不能有中文路徑
db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/bos?characterEncoding=utf-8
db.username=root
db.password=root
generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <!--導(dǎo)入屬性配置-->
    <properties resource="generator.properties"/>

    <!--指定特定數(shù)據(jù)庫(kù)的jdbc驅(qū)動(dòng)jar包的位置-->
    <classPathEntry location="${db.driverLocation}"/>

    <context id="default" targetRuntime="MyBatis3">

        <!-- optional,旨在創(chuàng)建class時(shí),對(duì)注釋進(jìn)行控制 -->
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>

        <!--jdbc的數(shù)據(jù)庫(kù)連接 -->
        <jdbcConnection
                driverClass="${db.driverClassName}"
                connectionURL="${db.url}"
                userId="${db.username}"
                password="${db.password}">
        </jdbcConnection>


        <!-- 非必需,類(lèi)型處理器,在數(shù)據(jù)庫(kù)類(lèi)型和java類(lèi)型之間的轉(zhuǎn)換控制-->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>


        <!-- Model模型生成器,用來(lái)生成含有主鍵key的類(lèi),記錄類(lèi) 以及查詢Example類(lèi)
            targetPackage     指定生成的model生成所在的包名
            targetProject     指定在該項(xiàng)目下所在的路徑
        -->
        <!--<javaModelGenerator targetPackage="com.mmall.pojo" targetProject=".\src\main\java">-->
        <javaModelGenerator targetPackage="com.mmall.pojo" targetProject="./src/main/java">
            <!-- 是否允許子包,即targetPackage.schemaName.tableName -->
            <property name="enableSubPackages" value="false"/>
            <!-- 是否對(duì)model添加 構(gòu)造函數(shù) -->
            <property name="constructorBased" value="true"/>
            <!-- 是否對(duì)類(lèi)CHAR類(lèi)型的列的數(shù)據(jù)進(jìn)行trim操作 -->
            <property name="trimStrings" value="true"/>
            <!-- 建立的Model對(duì)象是否 不可改變  即生成的Model對(duì)象不會(huì)有 setter方法,只有構(gòu)造方法 -->
            <property name="immutable" value="false"/>
        </javaModelGenerator>

        <!--mapper映射文件生成所在的目錄 為每一個(gè)數(shù)據(jù)庫(kù)的表生成對(duì)應(yīng)的SqlMap文件 -->
        <!--<sqlMapGenerator targetPackage="mappers" targetProject=".\src\main\resources">-->
        <sqlMapGenerator targetPackage="mappers" targetProject="./src/main/resources">
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>

        <!-- 客戶端代碼,生成易于使用的針對(duì)Model對(duì)象和XML配置文件 的代碼
                type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper對(duì)象
                type="MIXEDMAPPER",生成基于注解的Java Model 和相應(yīng)的Mapper對(duì)象
                type="XMLMAPPER",生成SQLMap XML文件和獨(dú)立的Mapper接口
        -->

        <!-- targetPackage:mapper接口dao生成的位置 -->
        <!--<javaClientGenerator type="XMLMAPPER" targetPackage="com.mmall.dao" targetProject=".\src\main\java">-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.mmall.dao" targetProject="./src/main/java">
            <!-- enableSubPackages:是否讓schema作為包的后綴 -->
            <property name="enableSubPackages" value="false" />
        </javaClientGenerator>


        <!-- tableName:數(shù)據(jù)庫(kù)表名 -->
        <!-- domainObjectName:對(duì)應(yīng)于數(shù)據(jù)庫(kù)表的javaBean類(lèi)名即pojo -->
        <!-- columnOverride :重新設(shè)置該屬性, 在本案例中, 設(shè)置格式為VARCHAR; -->
        <table tableName="mmall_product" domainObjectName="Product" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false">
            <columnOverride column="detail" jdbcType="VARCHAR" />
            <columnOverride column="sub_images" jdbcType="VARCHAR" />
        </table>
        <table tableName="mmall_user" domainObjectName="User"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" />
    </context>
</generatorConfiguration>

3. 自動(dòng)生成

點(diǎn)擊左邊欄的Maven, 如果沒(méi)有點(diǎn)擊View=>Tool Window=> Maven


Mybatis自動(dòng)生成

有一個(gè)哥們私聊我, 在項(xiàng)目進(jìn)行到一半, 如何自動(dòng)生成新的pojo和mapper, 只需要將其他的注釋掉, 僅保留需要生成的部分代碼即可.

MyBatis工作原理與工作流程

MyBatis工作原理與工作流程
  • sql語(yǔ)句和數(shù)據(jù)庫(kù)配置信息保存在配置文件中
  • Mybatis運(yùn)行的時(shí)候, 將配置信息存儲(chǔ)在Configuration對(duì)象里
  • 在創(chuàng)建SqlSession對(duì)象提供屬性
    • Configuration對(duì)象
    • dirty: true sql語(yǔ)句執(zhí)行完畢以后 可以事務(wù)提交
      false sql語(yǔ)句執(zhí)行發(fā)送錯(cuò)誤 事務(wù)進(jìn)行回滾
    • Executor執(zhí)行器對(duì)象:
      • 創(chuàng)建Statement對(duì)象,在創(chuàng)建過(guò)程中依靠MapperStatement對(duì)象賦值內(nèi)容與sql占位符進(jìn)行綁定
  • SqlSession.commit(): 根據(jù)此時(shí)dirty屬性決定提交和回滾
  • SqlSession.close()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容