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

MyBatis之動態(tài)SQL和緩存使用及說明

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

前言

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

一、動態(tài)SQL

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

在執(zhí)行SQL查詢時,只有屬性值存在我們才能做相應(yīng)的SQL語句的拼接,因此我們需要動態(tài)來拼裝SQL語句。

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

1.1 if標(biāo)簽

根據(jù)if標(biāo)簽中的test屬性所對應(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>

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

1.2 where標(biāo)簽

where標(biāo)簽可以輔助我們動態(tài)生成SQL語句中的where關(guān)鍵字,當(dāng)where后面有內(nèi)容時,where標(biāo)簽會幫助我們自動生成where關(guān)鍵字,同時會去掉內(nèi)容前多余的and和or關(guān)鍵字,此時就無需我們手動添加where關(guān)鍵字和恒成立的條件了;當(dāng)where后面沒有內(nèi)容時,此時不會生成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)容時,屬性功能正常;若標(biāo)簽沒有內(nèi)容時, trim不會有任何效果。

幾個屬性:

  • 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)簽組合起來相當(dāng)于if...else if...else的結(jié)構(gòu),如果所有的when條件都不滿足,則會執(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)簽簡單來說就是一個循環(huán),可以被用來執(zhí)行批量操作,foreach標(biāo)簽有五種屬性:

  • collection:設(shè)置需要循環(huán)的數(shù)組或集合
  • item:循環(huán)出來的單個對象
  • sqparator:循環(huán)體之間的分隔符
  • open:循環(huán)的所有內(nè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片段,它可以用來記錄常用的sql執(zhí)行語句。通過include標(biāo)簽來引用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 一級緩存

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

一級緩存失效的四種情況:

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

手動清空緩存:

sqlSession.clearCache();

2.2 二級緩存

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

二級緩存開啟的條件:

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

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

public class Emp implements Serializable 

二級緩存失效的情況:

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

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

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

eviction屬性:緩存回收策略

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

默認(rèn)的是LRU。

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

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

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

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

readOnly屬性:只讀,true/false

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

2.3 MyBatis緩存查詢順序

首先先查詢二級緩存,因為二級緩存中可能會有其他程序已經(jīng)查出來的數(shù)據(jù),可以拿來直接使用。

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

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

三、MyBatis的逆向工程(MBG)

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

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

  • Java實體類
  • Mapper接口
  •  MapperB映射文件 

在使用逆向工程之前首先應(yī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ū)動-->
        <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ān)配置-->
    <build>
        <!--構(gòu)建過程用到的插件-->
        <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ù)庫連接池c3p0-->
                    <dependency>
                        <groupId>com.mchange</groupId>
                        <artifactId>c3p0</artifactId>
                        <version>0.9.2</version>
                    </dependency>
                    <!--mysql驅(qū)動-->
                    <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
    -->
    <!-- 是否去除自動生成的注釋 true:是 : false:否 -->
    <context id="DB2Tables" targetRuntime="MyBatis3Simple">
        <!-- 數(shù)據(jù)庫連接 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/mybatis"
                        userId="root"
                        password="123456">
        </jdbcConnection>
        <!--
            javaBean的生成策略
            生成model模型,對應(yīng)的包路徑,以及文件存放路徑(targetProject),targetProject可以指定具體的路徑
            也可以使用“MAVEN”來自動生成,這樣生成的代碼會在target/generatord-source目錄下
        -->
        <javaModelGenerator targetPackage="com.crj.mybatis.pojo" targetProject=".\src\main\java">
            <!--是否能夠使用子包-->
            <property name="enableSubPackages" value="true" />
            <!-- 從數(shù)據(jù)庫返回的值被清理前后的空格  -->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!--
            SQL映射文件的生成策略
            對應(yīng)的mapper.xml文件
        -->
        <sqlMapGenerator targetPackage="com.crj.mybatis.mapper" targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>
        <!-- 對應(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>

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

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

總結(jié)

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

相關(guān)文章

  • Java Predicate接口定義詳解

    Java Predicate接口定義詳解

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

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

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

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

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

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

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

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

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

    SpringBoot如何配置文件properties和yml

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

    使用JAVA命令運行JAR包以及日志輸出詳解

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

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

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

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

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

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

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

最新評論

黔南| 林芝县| 博罗县| 阜南县| 康马县| 汶上县| 江阴市| 邵阳市| 兴业县| 汽车| 阿拉善盟| 封开县| 日喀则市| 成安县| 南宫市| 德州市| 固始县| 玛曲县| 阿拉尔市| 文安县| 乌鲁木齐县| 汉沽区| 辽阳市| 元江| 垣曲县| 孝义市| 江北区| 镇赉县| 澜沧| 兴山县| 长海县| 灵寿县| 武隆县| 杨浦区| 万宁市| 忻州市| 巩留县| 巍山| 长海县| 原阳县| 锡林浩特市|