1.日志
用于记录系统操作记录,保存历史数据,诊断问题
1.1.SLF4j与Logback
日志门面:统一的对外接口
pom中插入依赖
ch.qos.logback
logback-classic
1.2.3
resources下面添加logback.xml日志配置文件
[%thread] %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n
2.动态SQL
根据参数数据动态组织SQL
goods.xml:
调用:
@Test
public void testDynamicSQL() throws Exception {
SqlSession session = null;
session = MyBatisUtils.openSession();
Map param = new HashMap();
param.put("category", 44);
param.put("currentPrice", 500);
//可以不加namespace,确保id是唯一即可
List list = session.selectList("goods.dynamicSQL",param);
for (int i = 0; i < list.size(); i++) {
Goods goods = list.get(i);
System.out.println(goods.getTitle());
}
MyBatisUtils.closeSession(session);
}
3.缓存
主要是MyBatis二级缓存
- 一级缓存默认开启,缓存范围SqlSession会话
- 二级缓存手动开启,缓存范围是Mapper Namespace
3.1.二级缓存运行规则
- 二级开启后默认所有查询操作均使用缓存
- 写操作commit提交时对该namespace缓存强制清空
- 配置useCache=false可以不使用缓存
- 配置flushCache=true代表强制清空缓存
一级缓存的测试代码:
@Test
public void testLv1Cache() {
SqlSession session = null;
session = MyBatisUtils.openSession();
Goods goods = session.selectOne("goods.selectById",1603);
Goods goods1 = session.selectOne("goods.selectById",1603);
System.out.println("goods hashCode:" + goods.hashCode() + "-goods1 hashCode:" + goods1.hashCode());
MyBatisUtils.closeSession(session);
SqlSession session1 = null;
session1 = MyBatisUtils.openSession();
Goods goods2 = session1.selectOne("goods.selectById",1603);
Goods goods3 = session1.selectOne("goods.selectById",1603);
System.out.println("goods2 hashCode:" + goods2.hashCode() + "-goods3 hashCode:" + goods3.hashCode());
MyBatisUtils.closeSession(session1);
}
运行结果:
goods hashCode:574268151-goods1 hashCode:574268151
goods2 hashCode:423583818-goods3 hashCode:423583818
可以看到同一个session的hashCode相同,说明是同一个对象,并且debug日志也只会执行一次sql查询,如果在goods和goods1之间插入session.commit()方法,则goods和goods1则会是两个不同的对象。
二级缓存测试代码:
goods.xml中添加
测试代码与一级缓存一样不变
运行结果:
goods hashCode:270095066-goods1 hashCode:270095066
goods2 hashCode:270095066-goods3 hashCode:270095066
说明开启了二级缓存后,不同session也会公用一个缓存数据。
3.2.二级缓存参数说明
二级缓存相关:
...
单条相关:
----------
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})
4.多表级联查询
4.1.一对多查询
商品与商品图片详情就是1对多的关系
开发步骤:
4.1.1.resources下创建goods_detail.xml
4.1.2.goods.xml中配置一对多
4.1.3.mybatis-config.xml中加入应用
加入对goods_detail.xml的引用
4.1.4.调用测试
@Test
public void testOneToMany(){
SqlSession session = null;
session = MyBatisUtils.openSession();
List list = session.selectList("goods.selectOneToMany");
for (int i = 0; i < list.size(); i++) {
Goods goods = list.get(i);
System.out.println(goods.getTitle() + " : " +goods.getGoodsDetails().size());
}
MyBatisUtils.closeSession(session);
}
4.2.多对一查询
商品图片详情与商品是多对一
开发步骤:
4.2.1.mapper.xml配置
goods_detail.xml中添加多对一查询语句和resultMap:
4.2.2.调用
@Test
public void testManyToOne(){
SqlSession session = null;
session = MyBatisUtils.openSession();
List list = session.selectList("goodsDetail.selectManyToOne");
for (int i = 0; i < list.size(); i++) {
GoodsDetail goodsDetail = list.get(i);
if (goodsDetail.getGoods() == null)
continue;
System.out.println(goodsDetail.getGdPicUrl() + " : " + goodsDetail.getGoods().getTitle());
}
MyBatisUtils.closeSession(session);
}
5.分页PageHelper
原理:
- 当前数据查询使用语句
select * from tab limit 0,10
- 总记录数查询
select count(*) from tab
- 程序计算总页数、当前页、上一页下一页码
5.1.PageHelper使用流程
-
maven引入PageHelper与jsqlparser
com.github.pagehelper pagehelper 5.1.10 com.github.jsqlparser jsqlparser 2.0 -
mybatis-config.xml增加Plugin配置
mapper.xml中添加查询sql
- 代码中使用PageHelper.startPage()自动分页
@Test
public void testPageHelper(){
SqlSession session = null;
session = MyBatisUtils.openSession();
PageHelper.startPage(2, 10);
Page 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());
List data = page.getResult();//当前页数据
for (int i = 0; i < data.size(); i++) {
Goods goods = data.get(i);
System.out.println(goods.getTitle());
}
MyBatisUtils.closeSession(session);
}
--结果
总页数:181
总记录数:1810
开始行号:10
当前页码:20
康泰 家用智能胎心仪 分体探头操作方便 外放聆听 与家人分享宝宝心声
6.C3P0连接池
配置流程:
-
maven引入c3p0的引用
com.mchange c3p0 0.9.5.4 -
创建C3P0DataSourceFactory
//C3P0与MyBatis兼容使用的数据源工厂类 public class C3P0DataSourceFactory extends UnpooledDataSourceFactory { public C3P0DataSourceFactory(){ this.dataSource = new ComboPooledDataSource(); } }
mybatis.xml中引入datasource配置
剩下的不便
7.MyBatis批处理
在mapper.xml中使用foreach标签
INSERT INTO t_goods(title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id)
VALUES
(#{item.title}, #{item.subTitle}, #{item.originalCost}, #{item.currentPrice}, #{item.discount}, #{item.isFreeDelivery}, #{item.categoryId})
调用:
@Test
//分别插入
public void testBatchInsert1(){
SqlSession session = null;
session = MyBatisUtils.openSession();
long st = new Date().getTime();
for (int i = 0; i < 1000; 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);
session.insert("goods.insert", goods);
}
session.commit();
long et = new Date().getTime();
System.out.println("执行时间:" + (et - st) + "毫秒");
MyBatisUtils.closeSession(session);
}
@Test
//批量插入
public void testBatchInsert2(){
SqlSession session = null;
session = MyBatisUtils.openSession();
long st = new Date().getTime();
List list = new ArrayList();
for (int i = 0; i < 1000; 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);
list.add(goods);
}
session.insert("goods.batchInsert",list);
session.commit();
long et = new Date().getTime();
System.out.println("执行时间:" + (et - st) + "毫秒");
MyBatisUtils.closeSession(session);
}
分别插入的时间:
执行时间:976毫秒
批处理插入的时间:
执行时间:679毫秒
由此可见批处理的效率很高
批量删除:
DELETE FROM t_goods WHERE goods_id in
#{item}
--调用
@Test
//批量删除
public void testBatchDelete(){
SqlSession session = null;
session = MyBatisUtils.openSession();
long st = new Date().getTime();
List list = new ArrayList();
for (int i = 4670; i <= 4677; i++) {
list.add(i);
}
session.insert("goods.batchDelete",list);
session.commit();
long et = new Date().getTime();
System.out.println("执行时间:" + (et - st) + "毫秒");
MyBatisUtils.closeSession(session);
}
8.注解
mapper可以通过注解方式配置
新建GoodsDAO:
public interface GoodsDAO {
@Select("select * from t_goods where current_price between #{min} and #{max} order by current_price limit 0,#{limit}")
public List selectByPriceRange(@Param("min") Float min, @Param("max") Float max, @Param("limit") Integer limit);
@Insert("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(statement = "select last_insert_id()", before = false, keyProperty = "goodsId", resultType = Integer.class)
int insert(Goods goods);
@Select("select * from t_goods")
//配置返回值map
@Results({
@Result(column = "goods_id", property = "goodsId", id = true),
@Result(column = "current_price", property = "currentPrice")
})
List selectAll();
}
mybatis-config.xml中配置dao
调用:
@Test
public void testSelect(){
SqlSession session = null;
session = MyBatisUtils.openSession();
GoodsDAO goodsDAO = session.getMapper(GoodsDAO.class);
List list = goodsDAO.selectByPriceRange(100f, 500f, 20);
System.out.println(list.size());
MyBatisUtils.closeSession(session);
}
@Test
public void testInsert(){
SqlSession session = null;
session = MyBatisUtils.openSession();
GoodsDAO goodsDAO = session.getMapper(GoodsDAO.class);
Goods goods = new Goods();
goods.setTitle("测试商品");
goods.setSubTitle("测试子标题");
goods.setOriginalCost(200f);
goods.setCurrentPrice(100f);
goods.setDiscount(0.5f);
goods.setIsFreeDelivery(1);
goods.setCategoryId(43);
goodsDAO.insert(goods);
session.commit();
MyBatisUtils.closeSession(session);
}
@Test
public void testSelectAll(){
SqlSession session = null;
session = MyBatisUtils.openSession();
GoodsDAO goodsDAO = session.getMapper(GoodsDAO.class);
List goodsDTOS = goodsDAO.selectAll();
System.out.println(goodsDTOS.size());
MyBatisUtils.closeSession(session);
}