MyBatis进阶使用
日志管理
依赖使用Logback进行日志管理:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.3.0-alpha5</version>
</dependency>
需在资源文件夹中单独创建日志的配置文件logback.xml,文件名是强制的,程序运行时,logback会查找默认的配置文件logback.xml,从而打印调试信息。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender class="ch.qos.logback.core.ConsoleAppender" name="console">
<encoder>
<pattern>[%thread] %d{H H: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>
动态SQL
用于实现动态SQL的元素主要有:
- if
- choose(when,otherwise)
- trim
- where
- set
- foreach
单独if
避免出现语法错误,需要在此 SQL 语句中, 添加where 1=1 ,是多条件拼接时的小技巧, 后面的条件查询就可以都用 and 了。因为如果后面的if不为空,就会出现where and XX,这不符合语法:
<select id="dynamicSQL" parameterType="java.util.Map" resultType="com.imooc.mybatis.entity.Goods">
select * from t_goods
where 1=1
<if test="categoryId != null">and category_id = #{categoryId} </if>
<!--<表示小于号-->
<if test="currentPrice != null">and current_price < #{currentPrice} </if>
</select>
where+if结合
where语句的作用主要是简化SQL语句中where中的条件判断的:
<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>
set+if结合
set元素主要是用在更新操作的时候,它的主要功能和where元素其实是差不多的:
<update id="update" parameterType="com.imooc.mybatis.entity.Goods">
update t_goods
<!--set 用于配合if用于管理
set 子句.有如下功能:
a) 如果有条件满足, 会添加 set 关键字并执行sql语句
b) 如果第一个条件中有逗号,但后续的条件没有满足的,会自动去尾部逗号。
c) 如果修改条件都不满足就不生产set语句,出现错误,可以使用在set中添加id=#{id}来避免错误
-->
<set>
id=#{id}
<if test="title != null and title !=''">
title = #{title},
</if>
......
<if test="category_id != null and category_id !=''">
category_id = #{categoryId},
</if>
</set>
where goods_id = #{goodsId}
</update>
trim
set 和 where 其实都是 trim 标签的一种类型, 该两种功能都可以使用 trim 标签进行实现。
<trim prefix="where" prefixOverrides="AND |OR"></trim>
表示当 trim 中含有内容时, 添加 where, 且第一个为 and 或 or 时, 会将其去掉。而如果没有内容, 则不添加 where。
<trim prefix="SET" suffixOverrides=","></trim>
表示当 trim 中含有内容时, 添加 set, 且最后的内容为 , 时, 会将其去掉。而没有内容, 不添加 set
二级缓存
MyBatis自带的缓存有一级缓存和二级缓存。 Mybatis的一级缓存是指Session缓存。一级缓存的作用域默认是一个SqlSession。Mybatis默认开启一级缓存。 也就是在同一个SqlSession中,执行相同的查询SQL,第一次会去数据库进行查询,并写到缓存中; 第二次以后是直接去缓存中取。 当执行SQL查询中间发生了增删改的操作,MyBatis会把SqlSession的缓存清空。 下面通过测试来观察,测试方法中在同一个SqlSession 执行两次同样的查询方法,会发现SQL语句只执行了一次,又通过获取hashCode值,发现两次的内存地址是一样的:
@Test
public void testLv1Cache() throws Exception {
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) {
throw e;
} finally {
MyBatisUtils.closeSession(session);
}
}
[main] 13 13:26:27.900 DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
[main] 13 13:26:27.917 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 13 13:26:27.917 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 13 13:26:27.917 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 13 13:26:27.917 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 13 13:26:28.066 DEBUG o.a.i.t.jdbc.JdbcTransaction - Opening JDBC Connection
[main] 13 13:26:29.448 DEBUG o.a.i.d.pooled.PooledDataSource - Created connection 658532887.
[main] 13 13:26:29.448 DEBUG o.a.i.t.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@27406a17]
[main] 13 13:26:29.457 DEBUG goods.selectById - ==> Preparing: select * from t_goods where goods_id=?
[main] 13 13:26:29.608 DEBUG goods.selectById - ==> Parameters: 1603(Integer)
[main] 13 13:26:29.655 DEBUG goods.selectById - <== Total: 1
1621002296:1621002296
[main] 13 13:26:29.663 DEBUG o.a.i.t.jdbc.JdbcTransaction - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@27406a17]
[main] 13 13:26:29.672 DEBUG o.a.i.t.jdbc.JdbcTransaction - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@27406a17]
[main] 13 13:26:29.672 DEBUG o.a.i.d.pooled.PooledDataSource - Returned connection 658532887 to pool.
Process finished with exit code 0
当在测试方法中添加两个SqlSession,可以发现两个SqlSession分别执行了一次SQL语句,且内存地址是不一样的。这就说明了一级缓存只作用于SqlSession。
@Test
public void testLv1Cache() throws Exception {
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){
throw e;
}finally {
MyBatisUtils.closeSession(session);
}
try{
session = MyBatisUtils.openSession();
Goods goods3 = session.selectOne("goods.selectById" , 1603);
Goods goods4 = session.selectOne("goods.selectById" , 1603);
System.out.println(goods3.hashCode() + ":" + goods4.hashCode());
}catch (Exception e){
throw e;
}finally {
MyBatisUtils.closeSession(session);
}
}
[main] 13 13:30:35.994 DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
[main] 13 13:30:36.010 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 13 13:30:36.011 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 13 13:30:36.011 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 13 13:30:36.011 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 13 13:30:36.175 DEBUG o.a.i.t.jdbc.JdbcTransaction - Opening JDBC Connection
[main] 13 13:30:37.534 DEBUG o.a.i.d.pooled.PooledDataSource - Created connection 658532887.
[main] 13 13:30:37.535 DEBUG o.a.i.t.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@27406a17]
[main] 13 13:30:37.542 DEBUG goods.selectById - ==> Preparing: select * from t_goods where goods_id=?
[main] 13 13:30:37.614 DEBUG goods.selectById - ==> Parameters: 1603(Integer)
[main] 13 13:30:37.663 DEBUG goods.selectById - <== Total: 1
1621002296:1621002296
[main] 13 13:30:37.666 DEBUG o.a.i.t.jdbc.JdbcTransaction - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@27406a17]
[main] 13 13:30:37.666 DEBUG o.a.i.t.jdbc.JdbcTransaction - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@27406a17]
[main] 13 13:30:37.666 DEBUG o.a.i.d.pooled.PooledDataSource - Returned connection 658532887 to pool.
[main] 13 13:30:37.667 DEBUG o.a.i.t.jdbc.JdbcTransaction - Opening JDBC Connection
[main] 13 13:30:37.667 DEBUG o.a.i.d.pooled.PooledDataSource - Checked out connection 658532887 from pool.
[main] 13 13:30:37.667 DEBUG o.a.i.t.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@27406a17]
[main] 13 13:30:37.667 DEBUG goods.selectById - ==> Preparing: select * from t_goods where goods_id=?
[main] 13 13:30:37.667 DEBUG goods.selectById - ==> Parameters: 1603(Integer)
[main] 13 13:30:37.669 DEBUG goods.selectById - <== Total: 1
1138697171:1138697171
[main] 13 13:30:37.669 DEBUG o.a.i.t.jdbc.JdbcTransaction - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@27406a17]
[main] 13 13:30:37.670 DEBUG o.a.i.t.jdbc.JdbcTransaction - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@27406a17]
[main] 13 13:30:37.671 DEBUG o.a.i.d.pooled.PooledDataSource - Returned connection 658532887 to pool.
使用session.commit();commit提交时对该namespace缓存强制清空。
@Test
public void testLv1Cache() throws Exception {
SqlSession session = null;
try{
session = MyBatisUtils.openSession();
Goods goods3 = session.selectOne("goods.selectById" , 1603);
session.commit();//commit提交时对该namespace缓存强制清空
Goods goods4 = session.selectOne("goods.selectById" , 1603);
System.out.println(goods3.hashCode() + ":" + goods4.hashCode());
}catch (Exception e){
throw e;
}finally {
MyBatisUtils.closeSession(session);
}
}
[main] 13 13:35:21.063 DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
[main] 13 13:35:21.083 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 13 13:35:21.083 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 13 13:35:21.083 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 13 13:35:21.083 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 13 13:35:21.225 DEBUG o.a.i.t.jdbc.JdbcTransaction - Opening JDBC Connection
[main] 13 13:35:22.517 DEBUG o.a.i.d.pooled.PooledDataSource - Created connection 658532887.
[main] 13 13:35:22.518 DEBUG o.a.i.t.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@27406a17]
[main] 13 13:35:22.523 DEBUG goods.selectById - ==> Preparing: select * from t_goods where goods_id=?
[main] 13 13:35:22.615 DEBUG goods.selectById - ==> Parameters: 1603(Integer)
[main] 13 13:35:22.682 DEBUG goods.selectById - <== Total: 1
[main] 13 13:35:22.688 DEBUG goods.selectById - ==> Preparing: select * from t_goods where goods_id=?
[main] 13 13:35:22.688 DEBUG goods.selectById - ==> Parameters: 1603(Integer)
[main] 13 13:35:22.691 DEBUG goods.selectById - <== Total: 1
899543194:1138697171
[main] 13 13:35:22.692 DEBUG o.a.i.t.jdbc.JdbcTransaction - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@27406a17]
[main] 13 13:35:22.693 DEBUG o.a.i.t.jdbc.JdbcTransaction - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@27406a17]
[main] 13 13:35:22.693 DEBUG o.a.i.d.pooled.PooledDataSource - Returned connection 658532887 to pool.
Mybatis的二级缓存是指mapper映射文件。二级缓存的作用域是同一个namespace下的mapper映射文件内容,多个SqlSession共享。Mybatis需要手动设置启动二级缓存。生命周期和应用同步。
<!--开启了二级缓存
eviction是缓存的清除策略,当缓存对象数量达到上限后,自动触发对应算法对缓存对象清除 。
flushInterval:代表间隔多长时间自动清空缓存,60000毫秒=10分钟。
size:代表缓存上限,用于保存对象的数量上限。
readOnly:true表示返回只读缓存,每次取出的都是缓存对象本身,执行效率高;false表示返回缓存对象的副本,可写。
1.LRU – 最近最久未使用:移除最长时间不被使用的对象。O1 O2 O3 O4 .. O51214 99 83 1 893
2.FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
3.SOFT – 软引用:移除基于垃圾收集器状态和软引用规则的对象。
4.WEAK – 弱引用:更积极的移除基于垃圾收集器状态和弱引用规则的对象。 -->
<cache readOnly="true" size="512" flushInterval="600000" eviction="LRU"/>
下面来测试一下,发现两次会话的内存地址相同,且程序只执行了一次SQL语句:
@Test
public void testLv2Cache() throws Exception {
SqlSession session = null;
try{
session = MyBatisUtils.openSession();
Goods goods = session.selectOne("goods.selectById" , 1603);
System.out.println(goods.hashCode());
}catch (Exception e){
throw e;
}finally {
MyBatisUtils.closeSession(session);
}
try{
session = MyBatisUtils.openSession();
Goods goods = session.selectOne("goods.selectById" , 1603);
System.out.println(goods.hashCode());
}catch (Exception e){
throw e;
}finally {
MyBatisUtils.closeSession(session);
}
}
[main] 13 13:39:00.372 DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
[main] 13 13:39:00.387 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 13 13:39:00.388 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 13 13:39:00.388 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 13 13:39:00.388 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 13 13:39:00.543 DEBUG goods - Cache Hit Ratio [goods]: 0.0
[main] 13 13:39:00.549 DEBUG o.a.i.t.jdbc.JdbcTransaction - Opening JDBC Connection
[main] 13 13:39:01.918 DEBUG o.a.i.d.pooled.PooledDataSource - Created connection 1961002599.
[main] 13 13:39:01.919 DEBUG o.a.i.t.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@74e28667]
[main] 13 13:39:01.923 DEBUG goods.selectById - ==> Preparing: select * from t_goods where goods_id=?
[main] 13 13:39:01.969 DEBUG goods.selectById - ==> Parameters: 1603(Integer)
[main] 13 13:39:02.010 DEBUG goods.selectById - <== Total: 1
2144665602
[main] 13 13:39:02.014 DEBUG o.a.i.t.jdbc.JdbcTransaction - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@74e28667]
[main] 13 13:39:02.015 DEBUG o.a.i.t.jdbc.JdbcTransaction - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@74e28667]
[main] 13 13:39:02.015 DEBUG o.a.i.d.pooled.PooledDataSource - Returned connection 1961002599 to pool.
[main] 13 13:39:02.015 DEBUG goods - Cache Hit Ratio [goods]: 0.5
2144665602
部分不想要使用缓存的SQL元素,可以使用useCache="false"属性来关闭缓存。
若想执行完SQL后立马清除缓存,可以使用flushCache="true"属性。
多表级联查询
多对一:association
如下图所示,t_goods_detail里多条记录对应一个goods_id,现在想查询t_goods_detail数据以及其关联的商品信息。
<resultMap id="rmGoodsDetail" type="com.imooc.mybatis.entity.GoodsDetail">
<id property="gdId" column="gd_id"/>
<result property="goodsId" column="goods_id"/>
<association property="goods" column="goods_id" select="goods.selectById"/>
</resultMap>
<select id="selectManyToOne" resultMap="rmGoodsDetail">
select * from t_goods_detail limit 0,20
</select>
package com.imooc.mybatis.entity;
/**
* @Auther 徐士成
* @Date 2021-06-23 14:30
*/
public class GoodsDetail {
private Integer gdId;
private Integer goodsId;
private String gdPicUrl;
private Integer gdOrder;
private Goods goods;
public Integer getGdId() {
return gdId;
}
public void setGdId(Integer gdId) {
this.gdId = gdId;
}
public Integer getGoodsId() {
return goodsId;
}
public void setGoodsId(Integer goodsId) {
this.goodsId = goodsId;
}
public String getGdPicUrl() {
return gdPicUrl;
}
public void setGdPicUrl(String gdPicUrl) {
this.gdPicUrl = gdPicUrl;
}
public Integer getGdOrder() {
return gdOrder;
}
public void setGdOrder(Integer gdOrder) {
this.gdOrder = gdOrder;
}
public Goods getGoods() {
return goods;
}
public void setGoods(Goods goods) {
this.goods = goods;
}
@Override
public String toString() {
return "GoodsDetail{" +
"gdId=" + gdId +
", goodsId=" + goodsId +
", gdPicUrl='" + gdPicUrl + '\'' +
", gdOrder=" + gdOrder +
", goods=" + goods +
'}';
}
}
@Test
public void testManyToOne() throws Exception {
SqlSession session = null;
try {
session = MyBatisUtils.openSession();
List<GoodsDetail> list = session.selectList("goods.selectManyToOne");
for(GoodsDetail gd:list) {
System.out.println(gd.getGdPicUrl() + ":" + gd.getGoods().getTitle());
}
} catch (Exception e) {
throw e;
} finally {
MyBatisUtils.closeSession(session);
}
}
一对多: collection
根据上面的多对一,反推一个商品就对应多条t_goods_detail表中的数据,那么如何将数据映射到goods中?这里需要在goods类中新增一个List
<select resultType="com.imooc.mybatis.entity.GoodsDetail" parameterType="Integer" id="selectByGoodsId">
select * from t_goods_detail where goods_id = #{value}
</select>
<resultMap id="rmGoods1" type="com.imooc.mybatis.entity.Goods">
<!-- 映射goods对象的主键到goods_id字段 -->
<id column="goods_id" property="goodsId"/>
<!--collection的含义是,在 select * from t_goods limit 0,1 得到结果后,对所有Goods对象遍历得到goods_id字段值, 并代入到goodsDetail命名空间的findByGoodsId的SQL中执行查询, 将得到的"商品详情"集合赋值给goodsDetails List对象. -->
<collection column="goods_id" property="goodsDetails" select="goods.selectByGoodsId"/>
</resultMap>
<select id="selectOneToMany" resultMap="rmGoods1">select * from t_goods limit 0,10 </select>
@Test
public void testOneToMany() throws Exception {
SqlSession session = null;
try {
session = MyBatisUtils.openSession();
List<Goods> list = session.selectList("goods.selectOneToMany");
for(Goods goods:list) {
System.out.println(goods.getTitle() + ":" + goods.getGoodsDetails().size());
}
} catch (Exception e) {
throw e;
} finally {
MyBatisUtils.closeSession(session);
}
}
PageHelper分页
在pom.xml配置文件中添加PageHelper相关依赖:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.1</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>4.0</version>
</dependency>
在mybatis-config配置拦截器插件:
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库,helperdialect:配置使用哪种数据库语言,不配置的话pageHelper也会自动检测。-->
<property name="helperDialect" value="mysql"/>
<!--分页合理化,reasonable:在启用合理化时,如果 pageNum<1,则会查询第一页;如果 pageNum>pages,则会查询最后一页-->
<property name="reasonable" value="true"/>
</plugin>
</plugins>
<select resultType="com.imooc.mybatis.entity.Goods" id="selectPage">
select * from t_goods where current_price < 1000
</select>
@Test
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);
}
}
[main] 11 11:32:51.477 DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
[main] 11 11:32:51.542 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 11 11:32:51.542 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 11 11:32:51.543 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 11 11:32:51.543 DEBUG o.a.i.d.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[main] 11 11:32:51.841 DEBUG SQL_CACHE - Cache Hit Ratio [SQL_CACHE]: 0.0
[main] 11 11:32:51.946 DEBUG goods - Cache Hit Ratio [goods]: 0.0
[main] 11 11:32:51.956 DEBUG o.a.i.t.jdbc.JdbcTransaction - Opening JDBC Connection
[main] 11 11:32:53.159 DEBUG o.a.i.d.pooled.PooledDataSource - Created connection 2053996178.
[main] 11 11:32:53.159 DEBUG o.a.i.t.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@7a6d7e92]
[main] 11 11:32:53.164 DEBUG goods.selectPage_COUNT - ==> Preparing: SELECT count(0) FROM t_goods WHERE current_price < 1000
[main] 11 11:32:53.220 DEBUG goods.selectPage_COUNT - ==> Parameters:
[main] 11 11:32:53.383 DEBUG goods.selectPage_COUNT - <== Total: 1
[main] 11 11:32:53.387 DEBUG goods - Cache Hit Ratio [goods]: 0.0
[main] 11 11:32:53.387 DEBUG goods.selectPage - ==> Preparing: select * from t_goods where current_price < 1000 LIMIT ?, ?
[main] 11 11:32:53.390 DEBUG goods.selectPage - ==> Parameters: 10(Long), 10(Integer)
[main] 11 11:32:53.395 DEBUG goods.selectPage - <== Total: 10
总页数:182
总记录数:1813
开始行号:10
结束行号:20
当前页码:2
康泰 家用智能胎心仪 分体探头操作方便 外放聆听 与家人分享宝宝心声
惠氏 启赋(Wyeth illuma)有机1段 900g (0-6月)婴儿配方奶粉(罐装)
惠氏 启赋(Wyeth illuma)有机2段900g(6-12月)较大婴儿配方奶粉(罐装)
惠氏启赋3段(12-36个月)幼儿配方奶粉900g *2罐
爱他美婴幼儿配方奶粉pre段800g 铂金版
【日本】尤妮佳MOONY 纸尿裤S84*3包
【日本】日本Moony XL38(男)拉拉裤*4包
【日本】Moony尤妮佳婴儿拉拉裤(男)L44片*3包
【日本】Moony尤妮佳婴儿裤型拉拉裤(女)L44*3包
【日本】Moony XL38(男)婴幼儿拉拉裤*3包
批处理
批量插入
<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 separator="," index="index" item="item" collection="list">
(#{item.title},#{item.subTitle}, #{item.originalCost},
#{item.currentPrice}, #{item.discount}, #{item.isFreeDelivery},
#{item.categoryId})
</foreach>
</insert>
@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);
list.add(goods);
}
session.insert("goods.batchInsert", list);
session.commit();//提交事务数据
long et = new Date().getTime();
System.out.println("执行时间:" + (et - st) + "毫秒");
} catch (Exception e) {
if (session != null) {
session.rollback();//回滚事务
}
throw e;
} finally {
MyBatisUtils.closeSession(session);
}
}
批量删除
<delete id="batchDelete" parameterType="java.util.List">
DELETE FROM t_goods WHERE goods_id in
<foreach separator="," index="index" item="item" collection="list" close=")" open="(">
#{item}
</foreach>
@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) + "毫秒");
} catch (Exception e) {
if (session != null) {
session.rollback();//回滚事务
}
throw e;
} finally {
MyBatisUtils.closeSession(session);
}
}