Java框架之MyBatis 07-動態SQL-緩存機制-逆向工程-分頁插件

来源:https://www.cnblogs.com/Open-ing/archive/2020/01/25/12232989.html
-Advertisement-
Play Games

MyBatis 今天大年初一,你在學習!不學習做什麼,鬥地主...人都湊不齊。學習吧,學習使我快樂!除了詩和遠方還有責任,我也想擔當,我也想負責,可臣妾做不到啊,怎麼辦?你說怎麼辦,為啥人家能做到你做不到,因為人家比你多做了那麼一點點。哪一點點?就那麼一點點,只要你也多做那麼一點點,不就做到了!.. ...


MyBatis

  今天大年初一,你在學習!不學習做什麼,鬥地主...人都湊不齊。學習吧,學習使我快樂!除了詩和遠方還有責任,我也想擔當,我也想負責,可臣妾做不到啊,怎麼辦?你說怎麼辦,為啥人家能做到你做不到,因為人家比你多做了那麼一點點。哪一點點?就那麼一點點,只要你也多做那麼一點點,不就做到了!...就那麼一點點呀,我回顧SE去了。萬丈高樓平地起,基礎打的牢,怕什麼狂風暴雨

MyBatis 動態SQL

  MyBatis為瞭解決通過一些不確定性的條件進行SQL語句的拼接操作的問題, 提供了動態SQL. 具體來說,就是提供了一些標簽 <if> <where> <trim> <set> <choose> <foreach> 等.寫出可擴展SQL語句

  MyBatis 採用功能強大的基於 OGNL 的表達式來簡化操作

  OGNL( Object Graph Navigation Language )對象圖導航語言,這是一種強大的表達式語言,通過它可以非常方便的來操作對象屬性。 類似於EL表達式,例:

    訪問對象屬性:              person.name

    調用方法:                     person.getName()

    調用靜態屬性/方法:     @java.lang.Math@PI    

    調用構造方法:              new com.bean.Person(‘admin’).name

    運算符:                         +,-*,/,%

    邏輯運算符:                  in,not in,>,>=,<,<=,==,!=

    註意:xml中特殊符號如”,>,<等這些都需要使用轉義字元

 標簽

   1) <if>:用於完成簡單的判斷.只有一個屬性 test 用於判斷條件是否成立

   2) <where>:在SQL語句中添加WHERE關鍵字, 作用:去掉 where 後面第一個條件前面的 and / or 。

    <select id="getBook" resultType="main.beans.Book">
        SELECT id,title,author,price
        FROM books
        <where>
            <if test="id != null"> and id= #{id}</if>
            <if test="title != null"> and title = #{title}</if>
        </where>
    </select>

   3) <trim> : 可以在條件判斷完的SQL語句的前後 添加內容 或者去掉指定的內容. 去掉第一個或最後一個

    prefix: 添加首碼  prefixOverrides: 去掉首碼

    suffix: 添加尾碼  suffixOverrides: 去掉尾碼

    <delete id="deleteBook">
        DELETE FROM books
        <trim prefix="WHERE" suffixOverrides="and">
            <if test="id != null">id = #{id} and</if>
            <if test="title != null">itle = #{title} and</if>
        </trim >
    </delete>

   4) <set>  :在修改的操作中, 去掉SQL語句中多出的逗號,即在sql語句中最後句可能多出的逗號

    <update id="updateBook">
        UPDATE books
        <set>
            <if test="title != null">title = #{title},</if>
            <if test="author != null">author = #{author},</if>
        </set>
        where id = #{id}
    </update>

  5) <sql> 標簽是用於抽取可重用的sql片段,將使用頻繁的SQL片段抽取出來,不僅僅只提取整條sql語句,欄位也可以提取

    id:指定被提取的 sql 片段唯一標識被引用

    引用:在任何需要插入此 sql 片段的語句中使用 <include refid="id標識"></include> 引入即可

    <sql id="bookFields">
        id,title,author,price,sales,stock,img_path
    </sql>
    <insert id="insertBook" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO books (<include refid="bookFields"></include>)
        VALUES(#{id},#{title},#{author},#{price},#{sales},#{stock},#{imgPath})
    </insert>

  6) <choose> <when> <otherwise> : 用於分支判斷,最終只會滿足其中的一個分支.  類似於 switch case 語句. 

    <select id="selectBookPrice" resultType="main.beans.Book">
        SELECT <include refid="bookFields"></include>
        FROM books
        <where>
            <choose>
                <when test="id != null">id = #{id}</when>
                <otherwise>price > #{price}</otherwise>
            </choose>
        </where>
    </select>

  7) <foreach>: 主要用於迴圈迭代

      collection: 要迭代的集合

      item: 當前從集合中迭代出的元素賦值的變數

      open: 開始字元

      close:結束字元

      separator: 指定元素與元素之間的分隔符

      index:

        迭代的是List集合: index表示當前元素的下標

        迭代的Map集合:  index表示當前元素的 key

  註意:此操作屬於批量操作需在 properties 配置的 url 中添加 allowMultiQueries=true 開啟批處理

    <select id="getBooks" resultType="main.beans.Book">
        SELECT <include refid="bookFields"></include>
        FROM books where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")" >
            #{id}
        </foreach>
    </select>

MyBatis 緩存機制

    MyBatis 包含一個非常強大的查詢緩存特性,它可以非常方便地配置和定製。緩存可以極大的提升查詢效率

    MyBatis系統中預設定義了兩級緩存:一級緩存、二級緩存

    預設情況下,只有一級緩存(SqlSession級別的緩存,也稱為本地緩存)開啟。

    二級緩存需要手動開啟和配置,他是基於namespace級別的緩存。為了提高擴展性。MyBatis定義了緩存介面Cache,支持第三方緩存。

一級緩存

  1) 一級緩存(local cache), 即本地緩存, 作用域預設為sqlSession。每個sqlSession對象都有自己的一級緩存,相互獨立不共用。當  Session flush 或 close 後, 該 Session 中的所有 Cache 將被清空。

  2) 本地緩存不能被關閉, 但可以調用 clearCache() 來清空本地緩存, 或者改變緩存的作用域.

  3) 在mybatis3.1之後, 可以配置本地緩存的作用域. 在 mybatis.xml 中配置

  4) 一級緩存的工作機制,同一次會話期間只要查詢過的數據都會保存在當前SqlSession的一個Map中

     key: hashCode+查詢的SqlId+編寫的sql查詢語句+參數

緩存機制:

  基於相同sqlSession多次查詢,每次查詢都會先從緩存中獲取數據,如果緩存中沒獲取到數據,則從資料庫中獲取數據,之後,將數據存放到一級緩存。

一級緩存的失效問題

  1)不同的SqlSession對應不同的一級緩存

  2)同一個SqlSession但是查詢條件不同

  3)同一個SqlSession兩次查詢期間執行了任何一次增刪改操作
    增刪改操作,會預設清空緩存。

  4)同一個SqlSession兩次查詢期間手動清空了緩存

總結:當同一 SqlSession 多次查詢同一語句時,且中間未有增刪改或手動刷新、關閉、清空 clearCache() 過緩存,便會直接從緩存中取數據。若開啟了二級緩存則會先從二級緩存讀取,若二級緩存里沒有再去一級緩存讀取,如果只想從一級緩存中讀取可在對應 <select> 配置屬性中設置  useCache="false" 來關閉當前二級緩存,註意增刪改不涉及緩存機制

二級緩存

  預設關閉,使用需要滿足三個條件才被開啟

  二級緩存:namespace級別緩存(sqlSessionFacotry)級別的緩存,作用域更廣但是需要在 sqlSessionFacotry 內的 sqlSession 提交或關閉以後才會生效。即才會將 sqlSession 中的緩存存到二級緩存中。

      二級緩存使用的步驟:

    ①   全局配置文件中開啟二級緩存<setting name="cacheEnabled" value="true"/>

    ②   在需要使用二級緩存的映射文件( <mapper> 配置文件)使用 cache 標簽配置緩存<cache />

    ③   註意:POJO需要實現 Serializable 介面

  <cache> 標簽屬性

    ①   eviction=“LRU”:緩存回收策略:預設的是 LRU。

        LRU – 最近最少使用的:移除最長時間不被使用的對象。

        FIFO – 先進先出:按對象進入緩存的順序來移除它們。

        SOFT – 軟引用:移除基於垃圾回收器狀態和軟引用規則的對象。

        WEAK – 弱引用:更積極地移除基於垃圾收集器狀態和弱引用規則的對象。

     ②   flushInterval:刷新間隔,單位毫秒

        預設情況是不設置,也就是沒有刷新間隔,緩存僅僅調用語句時刷新

    ③   size:引用數目,正整數

        代表緩存最多可以存儲多少個對象,太大容易導致記憶體溢出

    ④   readOnly:只讀,預設是 false。雖然設為true能提高效率但是為了安全,因此不需設置此項

    ⑤ type:引入緩存類庫(第三方緩存)

  其他相關屬性設置

    1) 全局setting的 cacheEnable:

       配置二級緩存的開關,一級緩存一直是打開的。

    2) select標簽的 useCache 屬性:

          配置這個 select 是否使用二級緩存。一級緩存一直是使用的

    3) sql標簽的 flushCache 屬性:

       增刪改預設 flushCache=true。sql執行以後,會同時清空一級和二級緩存。

       查詢預設 flushCache=false。

    4) sqlSession.clearCache():只是用來清除一級緩存。

  二級緩存機制

    基於相同sqlSessionFactory下,多次查詢,優先去二級緩存中獲取數據,二級緩存獲取不到數據,去一級緩存中獲取數據,一級緩存中也獲取不到數據,直接去資料庫中查詢數據。

    查詢後,將數據直接存放一級緩存,提交或關閉 sqlSession 時,才將一級緩存中的數據,緩存到二級緩存中。

EhCache第三方緩存

  EhCache 是一個純Java的進程內緩存框架,具有快速、精幹等特點,是Hibernate中預設的CacheProvider

  整合EhCache緩存的步驟:

    ① 導入ehcache包,以及整合包,日誌包

      ehcache-core-2.6.8.jar、mybatis-ehcache-1.0.3.jar

      slf4j-api-1.6.1.jar、slf4j-log4j12-1.6.2.jar

    ② 編寫 ehcache.xml 配置文件

    ③ 配置 cache 標簽

      <cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>

   第三方緩存的使用機制,同二級緩存一樣也需要 setting 的 cacheEnable 設置為 true 並且實現序列化介面 Serializable 

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
 <!-- 磁碟保存路徑 -->
 <diskStore path="F:\code\mysql\ehcache" />
 <defaultCache 
   maxElementsInMemory="1000" 
   maxElementsOnDisk="10000000"
   eternal="false" 
   overflowToDisk="true" 
   timeToIdleSeconds="120"
   timeToLiveSeconds="120" 
   diskExpiryThreadIntervalSeconds="120"
   memoryStoreEvictionPolicy="LRU">
 </defaultCache>
</ehcache>

 MyBatis 逆向工程

  MyBatis Generator: 簡稱MBG,是一個專門為MyBatis框架使用者定製的代碼生成器,可以快速的根據表生成對應的映射文件,介面,以及bean類。支持基本的增刪改查,以及QBC風格的條件查詢。但是表連接、存儲過程等這些複雜sql的定義需要我們手工編寫

Mybatis使用逆向工程步驟
  1.加入逆向工程相關的jar包.

    mybatis-generator-core-1.3.2.jar

  2.配置逆向工程的配置文件: mbg.xml ==> 生成的版本 、 javaBean、Mapper介面、映射文件的生成策略 、 分析的表 .

    mbg.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>
    <!--
            targetRuntime: 執行生成的逆向工程的版本
                  MyBatis3Simple: 生成基本的CRUD
                  MyBatis3: 生成帶條件的CRUD
   -->
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <!--        資料庫連接設置-->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/bookstore?allowMultiQueries=true"
                        userId="root"
                        password="12345">
        </jdbcConnection>
        <!-- javaBean的生成策略 bean的存放路徑-->
        <javaModelGenerator targetPackage="main.beans" targetProject=".\src">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!-- SQL映射文件的生成策略 mapper.xml文件路徑-->
        <sqlMapGenerator targetPackage="main.mapper" targetProject=".\conf">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
        <!-- Mapper介面的生成策略 mapper介面路徑-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="main.mapper" targetProject=".\src">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
        <!-- 逆向分析的表 表名對應的javaBean名-->
        <table tableName="books" domainObjectName="Book"></table>
        <table tableName="users" domainObjectName="User"></table>
    </context>
</generatorConfiguration>

  3.執行生成代碼.

    @Test
    public void testMbg() throws Exception {
        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        File configFile = new File("mbg.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,callback, warnings);
        myBatisGenerator.generate(null);
    }

PageHelper 分頁插件

  PageHelper 是MyBatis中非常方便的第三方分頁插件。內部提供了 PageHelper 和 PageInfo 兩個非常強大的類庫。

使用步驟

  1) 導入相關包 pagehelper-5.0.0.jar 和 jsqlparser-0.9.5.jar

  2) 在MyBatis全局配置文件中配置分頁插件,註意標簽位置不可亂序

    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>

  3) 使用:在查詢出集合之前開啟分頁查詢

        Page<Book> page = PageHelper.startPage(3,2 );
        List<Book> books = mapper.selectByExample(bookExample);
        //查詢出當前為第3頁,每頁顯示2條的圖書信息,其還可得到更多頁碼相關值
        books.forEach((book -> System.out.println("book = " + book)));
        PageInfo<Book> info = new PageInfo<>(books,3);
        System.out.println("=============獲取詳細分頁相關的信息=================");
        System.out.println("當前頁: " + info.getPageNum());
        System.out.println("總頁碼: " + info.getPages());
        System.out.println("總條數: " + info.getTotal());
        System.out.println("每頁顯示的條數: " + info.getPageSize());
        System.out.println("是否是第一頁: " + info.isIsFirstPage());
        System.out.println("是否是最後一頁: " + info.isIsLastPage());
        System.out.println("是否有上一頁: " + info.isHasPreviousPage());
        System.out.println("是否有下一頁: " + info.isHasNextPage());
        System.out.println("============分頁邏輯===============");
        int[] nums = info.getNavigatepageNums();
        for (int num : nums) {
            System.out.println("num = " + num);
        } 

  Page對象

    在查詢之前通過PageHelper.startPage(頁碼,條數)設置分頁信息,該方法返回Page對象

  PageInfo對象

    在查詢完數據後,使用PageInfo對象封裝查詢結果,可以獲取更詳細的分頁信息以及可以完成分頁邏輯

SSM配置文件

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 01. 用戶 和 許可權 的基本概念 1.1 基本概念 用戶 是 Linux 系統工作中重要的一環,用戶管理包括 用戶 與 組 管理 在 Linux 系統中,不論是由本機或是遠程登錄系統,每個系統都必須擁有一個賬號,並且對於不同的系統資源擁有不同的使用許可權 在 Linux 中,可以指定 每一個用戶 針 ...
  • 關機/重啟 shutdown 查看或配置網卡信息 ifconfig ping 遠程登錄和複製文件 ssh scp 01. 關機/重啟 序號命令對應英文作用 01 shutdown 選項 時間 shutdown 關機/重新啟動 1.1 shutdown shutdown 命令可以 安全 關閉 或者 重 ...
  • 查看目錄內容 ls 切換目錄 cd 創建和刪除操作 touch rm mkdir 拷貝和移動文件 cp mv 查看文件內容 cat more grep 其他 echo 重定向 > 和 >> 管道 | 01. 查看目錄內容 1.1 終端實用技巧 1> 自動補全 在敲出 文件/目錄/命令 的前幾個字母之 ...
  • 01. 終端命令格式 command [-options] [parameter] 說明: command:命令名,相應功能的英文單詞或單詞的縮寫 [-options]:選項,可用來對命令進行控制,也可以省略 parameter:傳給命令的參數,可以是 零個、一個 或者 多個 [] 代表可選 02. ...
  • 01. 單用戶操作系統和多用戶操作系統(科普) 單用戶操作系統:指一臺電腦在同一時間 只能由一個用戶 使用,一個用戶獨自享用系統的全部硬體和軟體資源 Windows XP 之前的版本都是單用戶操作系統 多用戶操作系統:指一臺電腦在同一時間可以由 多個用戶 使用,多個用戶共同享用系統的全部硬體和軟 ...
  • 01. 操作系統的發展歷史 1.1 Unix 1965 年之前的時候,電腦並不像現在一樣普遍,它可不是一般人能碰的起的,除非是軍事或者學院的研究機構,而且當時大型主機至多能提供30台終端(30個鍵盤、顯示器),連接一臺電腦  為瞭解決數量不夠用的問題 1965 年左後由 貝爾實驗室 加入了 麻省理 ...
  • 1. 操作系統(Operation System,OS) 操作系統作為介面的示意圖  沒有安裝操作系統的電腦,通常被稱為 裸機 如果想在 裸機 上運行自己所編寫的程式,就必須用機器語言書寫程式 如果電腦上安裝了操作系統,就可以在操作系統上安裝支持的高級語言環境,用高級語言開發程式 1.1 操作 ...
  • ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...