1、什么是日志?
运行程序打印日志数据需要导入日志实现相关依赖,如下;
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
进行配置文件编写(logback.xml),具体参数可访问logback官网进行学习:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- appender:在什么地方进行日志输出,ConsoleAppender:控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- %logger{36}:日志信息最多36个字符,超过了会以简写形式展示-->
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- level:日志输出的最低级别
日志输出级别(优先级高到低):
error: 错误 - 系统的故障日志
warn: 警告 - 存在风险或使用不当的日志
info: 一般性消息
debug: 程序内部用于调试信息
trace: 程序运行的跟踪信息
-->
<root level="debug">
<appender-ref ref="console"/>
</root>
</configuration>
2、动态SQL
动态SQL实例:
<select id="dynamicSQL" parameterType="java.util.Map" resultType="com.imooc.mybatis.entity.Goods">
select * from t_goods
<where>
<if test="categoryId != null">
and category_id = #{categoryId}
</if>
<if test="currentPrice != null">
and current_price < #{currentPrice}
</if>
</where>
</select>
测试:
@Test
public void testDynamicSQL() throws Exception{
SqlSession session = null;
try {
session = MyBatisUtils.openSession();
HashMap param = new HashMap();
param.put("categoryId",44);
param.put("currentPrice",500);
//查询条件
List<Goods> list = session.selectList("goods.dynamicSQL", param);
for (Goods g : list) {
System.out.println(g.getTitle()+":"+
g.getCategoryId()+":"+g.getCurrentPrice());
}
} catch (Exception e) {
throw e;
} finally {
MyBatisUtils.closeSession(session);
}
}
}
3、MyBatis二级缓存
3.1 一级缓存测试案例:
测试代码:
@Test
public void testLvlCache(){
SqlSession session = null;
try {
session = MyBatisUtils.openSession();
Goods goods = session.selectOne("goods.selectById", 1603);
Goods goods1 = session.selectOne("goods.selectById", 1603);
System.out.println(goods.hashCode()+":"+goods1.hashCode());
} catch (Exception e) {
e.printStackTrace();
} finally {
MyBatisUtils.closeSession(session);
}
try {
session = MyBatisUtils.openSession();
Goods goods = session.selectOne("goods.selectById", 1603);
session.commit();//commit提交时对该namespace缓存强制清空
Goods goods1 = session.selectOne("goods.selectById", 1603);
System.out.println(goods.hashCode()+":"+goods1.hashCode());
} catch (Exception e) {
e.printStackTrace();
} finally {
MyBatisUtils.closeSession(session);
}
}
运行结果:
结论(注意结果hashcode的值):
①在一级缓存中,在同一个session对象中,相同的sql操作(如果没有commit),返回的结果的哈希值相同。
②在一级缓存中,同一个session对象的相同sql操作之间如果有commit提交操作,则相同sql操作的返回结果的哈希值不相同。
③在一级缓存中,不同session对象的相同sql操作,其返回结果的哈希值也不相同。
3.2 二级缓存测试案例:
开启二级缓存方式(在goods.xml编写,注意位置):
<mapper namespace="goods">
<!-- 开启了二级缓存 -->
<cache eviction="LRU" flushInterval="600000" size="512" readOnly="true"/>
测试代码:
@Test
public void testLv2Cache() {
SqlSession session = null;
try {
session = MyBatisUtils.openSession();
Goods goods = session.selectOne("goods.selectById", 1603);
System.out.println(goods.hashCode() + ":");
} catch (Exception e) {
e.printStackTrace();
} finally {
MyBatisUtils.closeSession(session);
}
try {
session = MyBatisUtils.openSession();
Goods goods = session.selectOne("goods.selectById", 1603);
session.commit();//commit提交时对该namespace缓存强制清空
System.out.println(goods.hashCode() + ":");
} catch (Exception e) {
e.printStackTrace();
} finally {
MyBatisUtils.closeSession(session);
}
}
执行结果:
结论(注意结果hashcode的值以及缓存命中率):
①在二级缓存中,在同一个namespace中,相同的sql操作(如果没有commit),返回的结果的哈希值相同。
②运行结果中有缓存命中率,其值越高,说明缓存的利用率越高,程序运行速度也越快。
3.3 二级缓存常用属性:
(1)eviction是缓存的清除策略,当缓存对象数量达到上线后,自动触发对应算法对缓存对象清除。
1.LRU - 最近最久未使用:移出最长时间不被使用的对象。
2.FIFO - 先进先出:按对象进入缓存的顺序来移除他们。
3.SOFT - 软引用:移除基于垃圾收集器状态和软引用规则的对象。
4.WEAK - 弱引用:更积极的移除基于垃圾收集器状态和弱引用规则的对象。
(2)flushInterval 代表间隔多长时间自动清空缓存,单位毫秒,600000毫秒 =10分钟
(3)size 缓存存储上限,用于保存对象或集合(1个集合算一个对象)的数量上限
(4)readOnly 设置为true,代表返回只读缓存,每次从缓存取出的是缓存对象本身,这种执行效率较高;设置为false,代表每次取出的缓存对象的"副本",每一次取出的对象都是不同的,这种安全性较高。
(5)userCache="false"代表不使用缓存
(6)flushCache="true"在sql执行后强制清空缓存