知識點:算法
1 級緩存使用場景sql
2 級緩存使用場景數據庫
訂單表與會員表是存在一對多的關係 爲了儘量減小join 查詢,進行了分階段查詢,即先查詢出訂單表,在根據member_id 字段查詢出會員表,最後進行數據整合 。若是訂單表中存在重複的member_id,就會出現不少不必的重複查詢。 針對這種狀況myBatis 經過1緩存來實現,在同一次查詢會話中若是出現相同的語句及參數,就會從緩存中取出不在走數據庫查詢。1級緩存只能做用於查詢會話中 因此也叫作會話緩存。apache
LabelMapper mapper = session.getMapper(LabelMapper.class);
Label label = mapper.getById(23);
Label label2 = mapper.getById(23);
Label label3 = sqlSessionFactory.openSession().getMapper(LabelMapper.class).getById(23);
Label label4 = session.getMapper(Label2Mapper.class).getById(23);
System.out.println(label == label2);
System.out.println(label3 == label2);
System.out.println(label4 == label2);
複製代碼
>mapper.findById(1) dao方法
>org.apache.ibatis.session.defaults.DefaultSqlSession#selectList()
>org.apache.ibatis.executor.CachingExecutor#query()
>org.apache.ibatis.executor.BaseExecutor#query() 142L
>org.apache.ibatis.cache.impl.PerpetualCache#getObject 55L
複製代碼
>mapper.findById(1) dao方法
>org.apache.ibatis.session.defaults.DefaultSqlSession#selectList()
>org.apache.ibatis.executor.CachingExecutor#query()
>org.apache.ibatis.executor.BaseExecutor#query() 142L
>org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
>org.apache.ibatis.cache.impl.PerpetualCache#putObject
複製代碼
>org.apache.ibatis.session.defaults.DefaultSqlSession#clearCache
>org.apache.ibatis.executor.CachingExecutor#clearLocalCache
>org.apache.ibatis.executor.BaseExecutor#clearLocalCache
>org.apache.ibatis.cache.impl.PerpetualCache#clear
複製代碼
提問:在查詢時另外一個會話併發去修改查詢的數據,一級緩存是否會生效?若是生效是否就會致使數據不正確?緩存
業務系統中存在不少的靜態數據如,字典表、菜單表、權限表等,這些數據的特性是不會輕易修改但又是查詢的熱點數據。一級緩存針對的是同一個會話當中相同SQL,並不適合這情熱點數據的緩存場景。爲了解決這個問題引入了二級緩存,它脫離於會話以外。bash
@CacheNamespace()
public interface LabelMapper {
@Select("select * from t_label where id =#{id}")
Label getById(Integer id);
}
複製代碼
屬性說明:session
@CacheNamespace(
implementation = PerpetualCache.class, // 緩存實現 Cache接口 實現類
eviction = LruCache.class,// 緩存算法
flushInterval = 60000, // 刷新間隔時間 毫秒
size = 1024, // 最大緩存引用對象
readWrite = true, // 是否可寫
blocking = false // 是否阻塞
)
複製代碼
>org.apache.ibatis.session.defaults.DefaultSqlSession#selectList() 147L
>org.apache.ibatis.executor.CachingExecutor#query()81L
>org.apache.ibatis.executor.CachingExecutor#query()95L
>org.apache.ibatis.executor.CachingExecutor#flushCacheIfRequired() 164L //清除緩存
複製代碼
>org.apache.ibatis.cache.TransactionalCacheManager#getObject
>org.apache.ibatis.cache.decorators.TransactionalCache#getObject
>org.apache.ibatis.cache.decorators.SynchronizedCache#getObject
>org.apache.ibatis.cache.decorators.LoggingCache#getObject
>org.apache.ibatis.cache.decorators.SerializedCache#getObject
>org.apache.ibatis.cache.decorators.ScheduledCache#getObject
>org.apache.ibatis.cache.decorators.LruCache#getObject
>org.apache.ibatis.cache.impl.PerpetualCache#getObject
複製代碼
org.apache.ibatis.executor.CachingExecutor#close
>org.apache.ibatis.cache.TransactionalCacheManager#commit
>org.apache.ibatis.cache.decorators.TransactionalCache#flushPendingEntries
>org.apache.ibatis.cache.decorators.SynchronizedCache#putObject
>org.apache.ibatis.cache.decorators.LoggingCache#putObject
>org.apache.ibatis.cache.decorators.SerializedCache#putObject
>org.apache.ibatis.cache.decorators.ScheduledCache#putObject
>org.apache.ibatis.cache.decorators.LruCache#putObject
>org.apache.ibatis.cache.impl.PerpetualCache#putObject
複製代碼
基本命令使用mybatis
if
choose (when, otherwise)
trim (where, set)
foreach
複製代碼
示例說明:併發
<trim prefix="where" prefixOverrides="and|or">
<if test="id != null">
and id = #{id}
</if>
<if test="name != null">
and name = #{name}
</if>
</trim>
複製代碼
prefix="where" // 前綴
prefixOverrides="and|or" // 前綴要替換的詞
suffix="" // 添加後綴
suffixOverrides="" // 後綴要替換的詞
複製代碼
在where 包裹的SQL前會自動添加 where 字符 並去掉首尾多佘的 and|or 字符 至關於下配置:app
<trim prefix="where" prefixOverrides="and|or" suffixOverrides="and|or">
複製代碼
在set包裹的SQL前會自動添加 set 字符並去掉首尾多佘的 , 字符。
在同一個mapper 多個statement 存在多個相同的sql 片斷時,能夠經過元素聲明,在經過 元素進行引用。
聲明sql 段
<sql id="files">
id ,name ,createTime
</sql>
複製代碼
引用
<include refid="files" />
複製代碼
有時須要進行一些額外 邏輯運行,經過 聲明元素,並在其value 屬性中添加運算腳本,以下示例 自動給likeName 加上了% 分號,而後就能夠用#{likeName} 來使用帶%分號的like 運算。
<bind name="likeName" value="'%'+ _parameter.getName() +'%'"></bind>
複製代碼
_databaseid 數據庫標識ID _parameter 當前參數變理
以上的if trim where 等邏輯符都是 myBatis 自帶的XMLLanguageDriver 所提供的解釋語言,除非此以外 咱們還可使用 MyBatis-Velocity 或 mybatis-freemarker 等外部 解釋器來編寫動態腳本。
mybatis-freemarker 使用
引入mybatis 包:
<dependency>
<groupId>org.mybatis.scripting</groupId>
<artifactId>mybatis-freemarker</artifactId>
<version>1.1.2</version>
</dependency>
複製代碼
添加sql 語句
<select id="selectByIds"
resultType="com.tuling.mybatis.dao.User"
lang="org.mybatis.scripting.freemarker.FreeMarkerLanguageDriver">
select * from user
where id in(${ids?join(',')})
</select>
複製代碼
添加接口方法
List<User> selectByIds(@Param("ids") List<Integer> ids);
複製代碼