延遲加載
延遲加載處理的是N+1性能問題金麸,所謂N+1性能問題指的是映射集合(resultMap)內(nèi)存在級聯(lián)時惭蟋,我們需要的數(shù)據(jù)少于數(shù)據(jù)庫查出來的數(shù)據(jù)刻诊。這樣就會造成數(shù)據(jù)庫多查出來的數(shù)據(jù)白白被浪費(fèi)掉讹挎,同時也加大了數(shù)據(jù)庫那邊的負(fù)擔(dān)谤专,這是我們最不希望看到的躁锡。
Mybatis為此引入了延遲加載。
延遲加載的的過程就是一開始并不取出所有的級聯(lián)數(shù)據(jù)置侍,只有當(dāng)使用到級聯(lián)數(shù)據(jù)時映之,Mybatis才會發(fā)送SQL去取回?cái)?shù)據(jù)拦焚。
//通過配置文件開啟全局延遲加載
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
...
<setting name="lazyLoadingEnabled" value="true"/>
...
</settings>
</configuration>
由于Mybatis在默認(rèn)的情況下是按層級延遲加載的,所以當(dāng)我們使用級聯(lián)中某個層級中的數(shù)據(jù)時杠输,會把該層級上所有的數(shù)據(jù)全部查詢出來.這時就要用到aggressiveLazyLoading配置了.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--開啟全局延遲加載-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--禁用層級自動加載-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
</configuration>
按照上述配置完畢之后赎败,我們就可以完全按需加載數(shù)據(jù)了。
但是又因?yàn)槿绻@么做的話所有的級聯(lián)都需要去發(fā)送多條SQL語句進(jìn)行查詢蠢甲,這樣速度就會變慢僵刮,我們有時候會經(jīng)常將某兩個或者某幾個級聯(lián)放在一條SQL語句進(jìn)行一次查詢,這樣的情況也是最常見的情況鹦牛,我們可以使用局部延遲加載來解決上述問題搞糕。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--禁用全局延遲加載-->
<setting name="lazyLoadingEnabled" value="false"/>
<!--禁用層級自動加載-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
</configuration>
<resultMap id="shopFood" type="com.xyz.pojo.ShopFood">
<id property="id" column="id"/>
<result property="foodName" column="food_name"/>
<result property="shopFoodType" column="shop_food_type"/>
<result property="shopId" column="shop_id"/>
<result property="price" column="price"/>
<result property="oldPrice" column="old_price"/>
<result property="monthlyCounts" column="monthly_counts"/>
<result property="foodImg" column="food_img"/>
<result property="info" column="info"/>
<result property="description" column="description"/>
<result property="grade" column="grade"/>
<!-- 局部延遲加載 -->
<collection fetchType="lazy" property="foodRewardList" column="id" select="findFoodRewardByFoodId"/>
</resultMap>
二級緩存
Mybatis默認(rèn)情況下支持一級緩存,即相對于同一個SqlSession而言蛹批,相同的查詢不在執(zhí)行评矩,直接從緩存中取出結(jié)果岩四。
要想開啟二級緩存,只需在需要開啟二級緩存的那個mapper文件中加上<cache></cache>即可驹吮。另外還需要相關(guān)聯(lián)的POJO都必須是可序列化的,即實(shí)現(xiàn)Serializable接口膏燕。
<?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.ele.mapper.ShopMapper">
<!-- 開啟二級緩存 -->
<cache></cache>
<select id="findById" parameterType="int" resultType="com.ele.pojo.Shop">
select * from shop where id = #{id}
</select>
</mapper>
public class Account implements Serializable {
private Integer id;
private static final long serialVersionUID = 1L;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}