最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis之動(dòng)態(tài)SQL和緩存使用及說(shuō)明

 更新時(shí)間:2026年05月26日 09:34:40   作者:荔枝當(dāng)大佬  
這篇文章主要介紹了MyBatis之動(dòng)態(tài)SQL和緩存使用及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

前言

在這篇文章中荔枝將會(huì)梳理有關(guān)MyBatis動(dòng)態(tài)SQL和MyBatis緩存的相關(guān)知識(shí),同時(shí)也稍微了解了有關(guān)MyBatis中借助MAVEN中的插件管理來(lái)實(shí)現(xiàn)逆向工程。

一、動(dòng)態(tài)SQL

Mybatis框架的動(dòng)態(tài)SQL技術(shù)是一種根據(jù)特定條件動(dòng)態(tài)拼裝SQL語(yǔ)句的功能,它存在的意義是為了解決拼接SQL語(yǔ)句字符串時(shí)的問(wèn)題。

在執(zhí)行SQL查詢時(shí),只有屬性值存在我們才能做相應(yīng)的SQL語(yǔ)句的拼接,因此我們需要?jiǎng)討B(tài)來(lái)拼裝SQL語(yǔ)句。

在JDBC中我們根據(jù)不同的條件拼接SQL語(yǔ)句時(shí)往往需要注意一些預(yù)留處理,而MyBatis的動(dòng)態(tài)SQL特性就極大地簡(jiǎn)化了這一處理過(guò)程。

1.1 if標(biāo)簽

根據(jù)if標(biāo)簽中的test屬性所對(duì)應(yīng)的表達(dá)式?jīng)Q定標(biāo)簽中的內(nèi)容是否需要拼接到SQL中。

<?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="com.crj.mybatis.mapper.DynamicSQLMapper">
<!--    List<Emp> getEmpByCondition(Emp emp);-->
    <select id="getEmpByCondition" resultType="Emp">
        select * from t_emp where 1=1
        <if test="empName != null and empName != ''">
            and emp_name = #{empName}
        </if>
        <if test="age != null and age != ''">
            and age = #{age}
        </if>
        <if test="sex != null and sex != ''">
            and sex = #{sex}
        </if>
    </select>
</mapper>

這段實(shí)例demo中,我們需要在select語(yǔ)句中添加一個(gè)恒成立的條件1=1,這是為了防止SQL語(yǔ)句在某些屬性不存在時(shí)出現(xiàn)的拼接錯(cuò)誤。動(dòng)態(tài)SQL的特性其實(shí)類似一種按需加載的過(guò)程,彈性拼接起SQL語(yǔ)句。if標(biāo)簽中的test屬性其實(shí)就是if標(biāo)簽中的SQL語(yǔ)句段拼接的條件,滿足這個(gè)條件才能拼接在原有的查詢SQL語(yǔ)句中。

1.2 where標(biāo)簽

where標(biāo)簽可以輔助我們動(dòng)態(tài)生成SQL語(yǔ)句中的where關(guān)鍵字,當(dāng)where后面有內(nèi)容時(shí),where標(biāo)簽會(huì)幫助我們自動(dòng)生成where關(guān)鍵字,同時(shí)會(huì)去掉內(nèi)容前多余的and和or關(guān)鍵字,此時(shí)就無(wú)需我們手動(dòng)添加where關(guān)鍵字和恒成立的條件了;當(dāng)where后面沒(méi)有內(nèi)容時(shí),此時(shí)不會(huì)生成where關(guān)鍵字。

<!--    List<Emp> getEmpByCondition(Emp emp);-->
    <select id="getEmpByCondition" resultType="Emp">
        select * from t_emp
        <where>
            <if test="empName != null and empName != ''">
                and emp_name = #{empName}
            </if>
            <if test="age != null and age != ''">
                and age = #{age}
            </if>
            <if test="sex != null and sex != ''">
                and sex = #{sex}
            </if>
        </where>
    </select>

1.3 trim標(biāo)簽

若標(biāo)簽中有內(nèi)容時(shí),屬性功能正常;若標(biāo)簽沒(méi)有內(nèi)容時(shí), trim不會(huì)有任何效果。

幾個(gè)屬性:

  • prefix:將trim標(biāo)簽中內(nèi)容前面添加指定內(nèi)容
  • suffix:將trim標(biāo)簽中內(nèi)容后面添加指定內(nèi)容
  • prefixOverrides:將trim標(biāo)簽中內(nèi)容前面去掉指定內(nèi)容
  • suffixOverrides:將trim標(biāo)簽中內(nèi)容后面去掉指定內(nèi)容
<!--    List<Emp> getEmpByCondition(Emp emp);-->
    <select id="getEmpByCondition" resultType="Emp">
        select * from t_emp
        <trim prefix="where" suffixOverrides="and|or">
            <if test="empName != null and empName != ''">
                 emp_name = #{empName} and
            </if>
            <if test="age != null and age != ''">
                age = #{age} and
            </if>
            <if test="sex != null and sex != ''">
               sex = #{sex}
            </if>
        </trim>
    </select>

1.4 choose、when、otherwise標(biāo)簽

choose和when標(biāo)簽組合起來(lái)相當(dāng)于if...else if...else的結(jié)構(gòu),如果所有的when條件都不滿足,則會(huì)執(zhí)行otherwise中的條件。

<!--    List<Emp> getEmpByChoose(Emp emp);-->
    <select id="getEmpByChoose" resultType="Emp">
        select * from t_emp
        <where>
            <choose>
                <when test="empName != null and empName != ''">
                    emp_name = #{empName}
                </when>
                <when test="age != null and age != ''">
                    age = #{age}
                </when>
                <when test="sex != null and sex != ''">
                    sex = #{sex}
                </when>
                <otherwise>
                    did = 1
                </otherwise>
            </choose>
        </where>
    </select>

1.5 foreach標(biāo)簽

foreach標(biāo)簽簡(jiǎn)單來(lái)說(shuō)就是一個(gè)循環(huán),可以被用來(lái)執(zhí)行批量操作,foreach標(biāo)簽有五種屬性:

  • collection:設(shè)置需要循環(huán)的數(shù)組或集合
  • item:循環(huán)出來(lái)的單個(gè)對(duì)象
  • sqparator:循環(huán)體之間的分隔符
  • open:循環(huán)的所有內(nèi)容開(kāi)頭的內(nèi)容
  • close:循環(huán)的所有內(nèi)容結(jié)束的內(nèi)容
<!--    int deleteMoreByArray(Integer[] eids);-->
    <delete id="deleteMoreByArray">
        delete * from t_emp where eid in
        <foreach collection="eids" item="eid" separator="," open="(" close=")">
            #{eid}
        </foreach>
    </delete>

1.5 sql標(biāo)簽

sql標(biāo)簽又成為SQL片段,它可以用來(lái)記錄常用的sql執(zhí)行語(yǔ)句。通過(guò)include標(biāo)簽來(lái)引用SQL片段。

    <sql id="emColumns">eid,emp_name,age,sex,email</sql>
    <select id="getEmpByChoose" resultType="Emp">
        select <include refid="emColumns"></include> from t_emp      
    </select>

二、MyBatis的緩存

2.1 一級(jí)緩存

MyBatis的一級(jí)緩存是SqlSession級(jí)別的,通過(guò)同一個(gè)SqlSession查詢的數(shù)據(jù)會(huì)被緩存,下次查詢相同的數(shù)據(jù)就會(huì)從緩存中直接獲取而不會(huì)從數(shù)據(jù)庫(kù)中重新訪問(wèn)。一級(jí)緩存是默認(rèn)開(kāi)啟的

一級(jí)緩存失效的四種情況:

  • 不同的SqlSession對(duì)應(yīng)不同的一級(jí)緩存
  • 同一個(gè)SqlSession但是查詢條件不同
  • 同一個(gè)SqlSessioni兩次查詢期間執(zhí)行了任何一次增刪改操作
  • 同一個(gè)SqlSession兩次查詢期間手動(dòng)清空了緩存 

手動(dòng)清空緩存:

sqlSession.clearCache();

2.2 二級(jí)緩存

二級(jí)緩存是SqlSessionFactory級(jí)別,通過(guò)同一個(gè)SqlSessionFactory創(chuàng)建的SqlSessioni查詢的結(jié)果會(huì)被緩存;此后若再次執(zhí)行相同的查詢語(yǔ)句,結(jié)果就會(huì)從緩存中獲取。

二級(jí)緩存開(kāi)啟的條件:

  1. 在核心配置文件中,設(shè)置全局配置屬性cacheEnabled="true",默認(rèn)為true,不需要設(shè)置
  2. 在映射文件中設(shè)置標(biāo)簽<cache />
  3. 二級(jí)緩存必須在SqlSession關(guān)閉或提交之后有效 sqlSession.close() | sqlSession.commit()
  4. 查詢的數(shù)據(jù)所轉(zhuǎn)換的實(shí)體類類型必須實(shí)現(xiàn)序列化的接口

實(shí)體類實(shí)現(xiàn)序列化接口

public class Emp implements Serializable 

二級(jí)緩存失效的情況:

兩次查詢之間執(zhí)行了任意的增刪改,會(huì)使一級(jí)和二級(jí)緩存同時(shí)失效。

二級(jí)緩存的相關(guān)配置

在二級(jí)緩存的開(kāi)啟條件中,我們發(fā)現(xiàn)<cache />標(biāo)簽是可以配置一些屬性的,具體如下

eviction屬性:緩存回收策略

  • LRU(Least Recently Used)-最近最少使用的:移除最長(zhǎng)時(shí)間不被使用的對(duì)象。
  • FIFO(First in First out)-先進(jìn)先出:按對(duì)象進(jìn)入緩存的順序來(lái)移除它們。
  • SOFT-軟引用:移除基于垃圾回收器狀態(tài)和軟引用規(guī)則的對(duì)象。
  • WEAK-弱引用:更積極地移除基于垃圾收集器狀態(tài)和弱引用規(guī)則的對(duì)象。

默認(rèn)的是LRU。

flushlnterval屬性:刷新間隔,單位毫秒

默認(rèn)情況是不設(shè)置,也就是沒(méi)有刷新間隔,緩存僅僅調(diào)用增刪改語(yǔ)句時(shí)刷新

size屬性:引用數(shù)目,正整數(shù)

代表緩存最多可以存儲(chǔ)多少個(gè)對(duì)象,太大容易導(dǎo)致內(nèi)存溢出

readOnly屬性:只讀,true/false

  • true:只讀緩存;會(huì)給所有調(diào)用者返回緩存對(duì)象的相同實(shí)例。因此這些對(duì)象不能被修改。這提供了很重要的性能優(yōu)勢(shì)。
  • false:讀寫(xiě)緩存;會(huì)返回緩存對(duì)象的拷貝(通過(guò)序列化)。這會(huì)慢一些,但是安全,因此默認(rèn)是flse。

2.3 MyBatis緩存查詢順序

首先先查詢二級(jí)緩存,因?yàn)槎?jí)緩存中可能會(huì)有其他程序已經(jīng)查出來(lái)的數(shù)據(jù),可以拿來(lái)直接使用。

如果二級(jí)緩存沒(méi)有命中,再查詢一級(jí)緩存;如果一級(jí)緩存也沒(méi)有命中,則查詢數(shù)據(jù)庫(kù)。

注意在sqlSession關(guān)閉之后,一級(jí)緩存中的數(shù)據(jù)會(huì)寫(xiě)入二級(jí)緩存

三、MyBatis的逆向工程(MBG)

正向工程:先創(chuàng)建ava實(shí)體類,由框架負(fù)責(zé)根據(jù)實(shí)體類生成數(shù)據(jù)庫(kù)表。Hibernate是支持正向工程的。

逆向工程:先創(chuàng)建數(shù)據(jù)庫(kù)表,由框架負(fù)責(zé)根據(jù)數(shù)據(jù)庫(kù)表,反向生成如下資源:

  • Java實(shí)體類
  • Mapper接口
  •  MapperB映射文件 

在使用逆向工程之前首先應(yīng)該配置好項(xiàng)目依賴

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.crj</groupId>
    <artifactId>MyBatis_MBG</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <!--依賴MyBatis核心包-->
    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--mysql驅(qū)動(dòng)-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.3</version>
        </dependency>
        <!--log4j日志-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>
    <!--控制Maven在構(gòu)建過(guò)程中相關(guān)配置-->
    <build>
        <!--構(gòu)建過(guò)程用到的插件-->
        <plugins>
            <!--具體插件-->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.0</version>
                <!--插件的依賴-->
                <dependencies>
                    <!--逆向工程的核心依賴-->
                    <dependency>
                        <groupId>org.mybatis.generator</groupId>
                        <artifactId>mybatis-generator-core</artifactId>
                        <version>1.3.2</version>
                    </dependency>
                    <!--數(shù)據(jù)庫(kù)連接池c3p0-->
                    <dependency>
                        <groupId>com.mchange</groupId>
                        <artifactId>c3p0</artifactId>
                        <version>0.9.2</version>
                    </dependency>
                    <!--mysql驅(qū)動(dòng)-->
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>5.1.8</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
</project>

逆向工程配置文件:

<?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:執(zhí)行生成的逆向工程的版本
            MyBatis3Simple:生成基本的CRUD
            MyBatis:生成帶條件的CRUD
    -->
    <!-- 是否去除自動(dòng)生成的注釋 true:是 : false:否 -->
    <context id="DB2Tables" targetRuntime="MyBatis3Simple">
        <!-- 數(shù)據(jù)庫(kù)連接 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/mybatis"
                        userId="root"
                        password="123456">
        </jdbcConnection>
        <!--
            javaBean的生成策略
            生成model模型,對(duì)應(yīng)的包路徑,以及文件存放路徑(targetProject),targetProject可以指定具體的路徑
            也可以使用“MAVEN”來(lái)自動(dòng)生成,這樣生成的代碼會(huì)在target/generatord-source目錄下
        -->
        <javaModelGenerator targetPackage="com.crj.mybatis.pojo" targetProject=".\src\main\java">
            <!--是否能夠使用子包-->
            <property name="enableSubPackages" value="true" />
            <!-- 從數(shù)據(jù)庫(kù)返回的值被清理前后的空格  -->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!--
            SQL映射文件的生成策略
            對(duì)應(yīng)的mapper.xml文件
        -->
        <sqlMapGenerator targetPackage="com.crj.mybatis.mapper" targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>
        <!-- 對(duì)應(yīng)的Mapper接口類文件的生成策略 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.crj.mybatis.mapper" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>
        <!-- 逆向分析的表 -->
        <table tableName="t_emp" domainObjectName="Emp"/>
        <table tableName="t_dept" domainObjectName="Dept"/>
    </context>
</generatorConfiguration>

測(cè)試類中我們這樣來(lái)進(jìn)行條件查詢:

EmpExample example = new EmpExample();
//這里可以借助example.createCriteria().and開(kāi)頭的方法來(lái)設(shè)置查詢條件
example.createCriteria().andEmpNameEqualTo("荔枝");
mapper.selectByExample(example);

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java Predicate接口定義詳解

    Java Predicate接口定義詳解

    Predicate是Java中的一個(gè)函數(shù)式接口,它代表一個(gè)判斷邏輯,接收一個(gè)輸入?yún)?shù),返回一個(gè)布爾值,這篇文章主要介紹了Java Predicate接口的定義及示例代碼,需要的朋友可以參考下
    2025-04-04
  • Java線程調(diào)度之線程休眠用法分析

    Java線程調(diào)度之線程休眠用法分析

    這篇文章主要介紹了Java線程調(diào)度之線程休眠用法,較為詳細(xì)的分析了Java線程休眠的功能與實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-06-06
  • Jar啟動(dòng)實(shí)現(xiàn)從指定目錄中讀取配置文件過(guò)程

    Jar啟動(dòng)實(shí)現(xiàn)從指定目錄中讀取配置文件過(guò)程

    本文介紹了Spring Boot項(xiàng)目中如何將配置文件外置,不在JAR包中打包,而是從指定目錄加載配置文件的方法,通過(guò)修改啟動(dòng)參數(shù)實(shí)現(xiàn)靈活修改配置
    2026-05-05
  • SpringBoot實(shí)現(xiàn)固定和動(dòng)態(tài)定時(shí)任務(wù)的三種方法

    SpringBoot實(shí)現(xiàn)固定和動(dòng)態(tài)定時(shí)任務(wù)的三種方法

    定時(shí)器是我們項(xiàng)目中經(jīng)常會(huì)用到的,本文主要介紹了SpringBoot實(shí)現(xiàn)固定和動(dòng)態(tài)定時(shí)任務(wù)的三種方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • javaweb實(shí)現(xiàn)app掃碼登錄功能

    javaweb實(shí)現(xiàn)app掃碼登錄功能

    這篇文章主要為大家詳細(xì)介紹了javaweb實(shí)現(xiàn)app掃碼登錄功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • SpringBoot如何配置文件properties和yml

    SpringBoot如何配置文件properties和yml

    這篇文章主要介紹了SpringBoot如何配置文件properties和yml問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 使用JAVA命令運(yùn)行JAR包以及日志輸出詳解

    使用JAVA命令運(yùn)行JAR包以及日志輸出詳解

    這篇文章主要給大家介紹了關(guān)于使用JAVA命令運(yùn)行JAR包以及日志輸出的相關(guān)資料,文中通過(guò)代碼示例介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用java具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • SpringBoot3實(shí)現(xiàn)統(tǒng)一結(jié)果封裝的示例代碼

    SpringBoot3實(shí)現(xiàn)統(tǒng)一結(jié)果封裝的示例代碼

    Spring Boot進(jìn)行統(tǒng)一結(jié)果封裝的主要目的是提高開(kāi)發(fā)效率、降低代碼重復(fù)率,并且提供一致的API響應(yīng)格式,從而簡(jiǎn)化前后端交互和錯(cuò)誤處理,所以本文給大家介紹了SpringBoot3實(shí)現(xiàn)統(tǒng)一結(jié)果封裝的方法,需要的朋友可以參考下
    2024-03-03
  • Java如何根據(jù)根據(jù)IP地址獲取省市

    Java如何根據(jù)根據(jù)IP地址獲取省市

    這篇文章主要為大家詳細(xì)介紹了兩種在Java中獲取IP地址對(duì)應(yīng)地理位置信息的方法,分別是使用ip2region庫(kù)和GeoIP庫(kù),感興趣的小伙伴可以了解下
    2025-01-01
  • Spring Eureka 未授權(quán)訪問(wèn)漏洞修復(fù)問(wèn)題小結(jié)

    Spring Eureka 未授權(quán)訪問(wèn)漏洞修復(fù)問(wèn)題小結(jié)

    項(xiàng)目組使用的 Spring Boot 比較老,是 1.5.4.RELEASE ,最近被檢測(cè)出 Spring Eureka 未授權(quán)訪問(wèn)漏洞,這篇文章主要介紹了Spring Eureka 未授權(quán)訪問(wèn)漏洞修復(fù)問(wèn)題小結(jié),需要的朋友可以參考下
    2024-04-04

最新評(píng)論

秦安县| 望谟县| 施秉县| 万宁市| 山西省| 彩票| 兴安盟| 平阴县| 荔浦县| 邢台县| 沭阳县| 郧西县| 潜江市| 烟台市| 宣恩县| 泰和县| 桐乡市| 嘉兴市| 彩票| 清涧县| 曲阳县| 墨江| 象州县| 新邵县| 三原县| 佳木斯市| 寿光市| 凤凰县| 华安县| 双柏县| 桐梓县| 临海市| 衡阳市| 海淀区| 大竹县| 教育| 信丰县| 宜黄县| 高安市| 柘城县| 揭阳市|