一、MyBatis日志管理
-
什么是日志
a. 日志文件是用于记录系统操作事件的记录文件或文件集合
b. 日志保存历史数据,是诊断问题以及理解系统活动的重要依据 -
实现
1. 首先引入依赖
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
2. 在resources下创建logback.xml文件,加入限制条件
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%thread] %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!--
日志输出级别(优先级高到低):
error: 错误 - 系统的故障日志
warn: 警告 - 存在风险或使用不当的日志
info: 一般性消息
debug: 程序内部用于调试信息
trace: 程序运行的跟踪信息
-->
<root level="debug">
<appender-ref ref="console"/>
</root>
</configuration>
三、MyBatis动态SQL
- 动态SQL是指根据参数数据动态组织SQL的技术
<select id="dynamicSQL" parameterType="java.util.Map" resultType="com..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>
三、MyBatis二级缓存
-
一级缓存默认开启,缓存范围SqlSession会话
-
二级缓存手动开启,属于范围Mapper 的 Namespace
-
二级缓存运行规则
a. 二级开启后默认所有查询操作均使用缓存
b. 写操作commit提交时对该namespace缓存强制清空
c. 配置useCache=false可以不用缓存
d. 配置flushCache=true代表强制清空缓存 -
配置 xml文件里加入以下代码
<!--开启了二级缓存
eviction是缓存的清除策略,当缓存对象数量达到上限后,自动触发对应算法对缓存对象清除
1.LRU – 最近最久未使用:移除最长时间不被使用的对象。
O1 O2 O3 O4 .. O512
14 99 83 1 893
2.FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
3.SOFT – 软引用:移除基于垃圾收集器状态和软引用规则的对象。
4.WEAK – 弱引用:更积极的移除基于垃圾收集器状态和弱引用规则的对象。
-->
<cache eviction="LRU" flushInterval="600000" size="512" readOnly="true"/>
<!--flushCache="true"在sql执行后强制清空缓存-->
如:
<insert id="insert" parameterType="com.imooc.mybatis.entity.Goods" flushCache="true">
INSERT INTO t_goods(title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id)
VALUES (#{title} , #{subTitle} , #{originalCost}, #{currentPrice}, #{discount}, #{isFreeDelivery}, #{categoryId})
<!--<selectKey resultType="Integer" keyProperty="goodsId" order="AFTER">-->
<!--select last_insert_id()-->
<!--</selectKey>-->
</insert>
四、分页插件PageHelper
- PageHelper使用流程
a. maven引入PageHelper与jsqlparser
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>2.0</version>
</dependency>
b. mybatis-config.xml增加Plugin配置
<!--启用Pagehelper分页插件-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!--设置数据库类型-->
<property name="helperDialect" value="mysql"/>
<!--分页合理化-->
<property name="reasonable" value="true"/>
</plugin>
</plugins>
c. 代码中使用PageHelper.startPage()自动分页
@Test
/**
* PageHelper分页查询
*/
public void testSelectPage() throws Exception {
SqlSession session = null;
try {
session = MyBatisUtils.openSession();
/*startPage方法会自动将下一次查询进行分页*/
PageHelper.startPage(2,10);
Page<Goods> page = (Page) session.selectList("goods.selectPage");
System.out.println("总页数:" + page.getPages());
System.out.println("总记录数:" + page.getTotal());
System.out.println("开始行号:" + page.getStartRow());
System.out.println("结束行号:" + page.getEndRow());
System.out.println("当前页码:" + page.getPageNum());
List<Goods> data = page.getResult();//当前页数据
for (Goods g : data) {
System.out.println(g.getTitle());
}
System.out.println("");
} catch (Exception e) {
throw e;
} finally {
MyBatisUtils.closeSession(session);
}
}
五、MyBatis批处理
- 直接上代码
测试类
1. 插入
@Test
public void testBatchInsert() throws Exception {
SqlSession session = null;
try {
long st = new Date().getTime();
session = MyBatisUtils.openSession();
List list = new ArrayList();
for (int i = 0; i < 10000; i++) {
Goods goods = new Goods();
goods.setTitle("测试商品");
goods.setSubTitle("测试子标题");
goods.setOriginalCost(200f);
goods.setCurrentPrice(100f);
goods.setDiscount(0.5f);
goods.setIsFreeDelivery(1);
goods.setCategoryId(43);
//insert()方法返回值代表本次成功插入的记录总数
list.add(goods);
}
session.insert("goods.batchInsert", list);
session.commit();//提交事务数据
long et = new Date().getTime();
System.out.println("执行时间:" + (et - st) + "毫秒");
// System.out.println(goods.getGoodsId());
} catch (Exception e) {
if (session != null) {
session.rollback();//回滚事务
}
throw e;
} finally {
MyBatisUtils.closeSession(session);
}
}
mapper.xml配置
<!--INSERT INTO table-->
<!--VALUES ("a" , "a1" , "a2"),("b" , "b1" , "b2"),(....)-->
<insert id="batchInsert" parameterType="java.util.List">
INSERT INTO t_goods(title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id)
VALUES
<foreach collection="list" item="item" index="index" separator=",">
(#{item.title},#{item.subTitle}, #{item.originalCost}, #{item.currentPrice}, #{item.discount}, #{item.isFreeDelivery}, #{item.categoryId})
</foreach>
</insert>
2.删除
@Test
public void testBatchDelete() throws Exception {
SqlSession session = null;
try {
long st = new Date().getTime();
session = MyBatisUtils.openSession();
List list = new ArrayList();
list.add(1920);
list.add(1921);
list.add(1922);
session.delete("goods.batchDelete", list);
session.commit();//提交事务数据
long et = new Date().getTime();
System.out.println("执行时间:" + (et - st) + "毫秒");
// System.out.println(goods.getGoodsId());
} catch (Exception e) {
if (session != null) {
session.rollback();//回滚事务
}
throw e;
} finally {
MyBatisUtils.closeSession(session);
}
}
mapper.xml配置
<!--in (1901,1902)-->
<delete id="batchDelete" parameterType="java.util.List">
DELETE FROM t_goods WHERE goods_id in
<foreach collection="list" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</delete>