40.MyBaits懒加载、一二级缓存、模糊查询、分页查询、动态SQL

本文介绍了MyBatis的懒加载技术,用于优化级联查询,详细讲解了如何开启和配置一级、二级缓存,以及缓存的作用。此外,还探讨了模糊查询和分页查询的实现方法,包括动态SQL的运用,如if、choose、when、otherwise等标签的使用,以及foreach标签在遍历集合时的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MyBaits_Day04

第一节、作业
	<!--   对getAllCateAndGoods做实现-->
	<select id="getAllCateAndGoods" resultMap="cateAndGoods">
		SELECT * FROM category;
	</select>
	
	<!-- type表示resultMap是在封装谁的对象 -->
	<resultMap type="category" id="cateAndGoods">
		<id property="cid" column="cid"/>
		
		<!--  allGoods是一个list集合  myBatis不能自动封装-->
		<!--对应list类型 我们用collection -->
		<collection property="allGoods" ofType="goods" select="getGoodsByCid" column="cid"></collection>
	</resultMap>

	<select id="getGoodsByCid" resultType="goods">
		SELECT * FROM goods WHERE cid=#{cid};
	</select>
	private int cid;
	private String cname;
	
	//每一个分类下对应的商品
	//分析:一个商品分类下面有多个商品--一对多--一个分类下有多个商品(多个-集合)
	
	private List<Goods> allGoods;
第二节、MyBatis做级联查询的时候的懒加载

什么是懒加载:按需加载

场景:我页面上只需要显示分类,当用户选中某个分类的时候,才去加载商品

版本一:(没有开启懒加载)每次页面进来,只要调用接口,会查询分类同时也查询分类下的商品

image-20210904101322645

解决:开启懒加载

方法一:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u8bTsIQd-1631707125142)(C:\Users\王元元\AppData\Roaming\Typora\typora-user-images\image-20210904192103279.png)]

方法二:

<collection property="allGoods" ofType="goods" select="getGoodsByCid" column="cid" fetchType="lazy"></collection>=

什么叫关联对象:

查分类及其分类的商品的时候,每一个分类下对应的商品就是关联对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WS0M0PPZ-1631707125143)(C:/Program%20Files/Typora/upload/image-20210904101652038.png)]

image-20210904101438936

image-20210904102046465

image-20210904102121658

image-20210904102140268

第三节、MyBatis中缓存

什么叫缓存:

image-20210904105548291

缓存的作用:

1、提高访问的效率(缓存放在内存)

2、减小数据库的压力

3、缓存有一个过期时间

MyBaits中缓存

一级缓存:sqlSession(通一个SqlSession的操作会触发缓存 默认开启的)

image-20210904110129653


SqlSession sqlSession = SqlSessionFactoryUtil.getSqlSession();
CategoryMapper mapper = sqlSession.getMapper(CategoryMapper.class);
List<Category> allCateAndGoods = mapper.getAllCateAndGoods();
sqlSession.clearCache();//清除缓存
CategoryMapper mapper2 = sqlSession.getMapper(CategoryMapper.class);
List<Category> allCateAndGoods2 = mapper.getAllCateAndGoods();
System.out.println(allCateAndGoods==allCateAndGoods2);//地址比较
二级缓存:基于mapper(同一个mapper下的操作触发缓存)

image-20210904111656446

开启二级缓存的步骤:

1、全局配置文件中开启缓存

<setting name="cacheEnabled" value="true"/>

2、需要开启二级缓存mapper开启缓存

image-20210904111819231

3、mapper中操作的实体类实现序列化接口

注意点:如果实体类中有关联对象,关联对象也需要实现序列化接口

public class Category implements Serializable{
第四节、模糊查询

直接将模糊的条件传入即可

<select id="getGoodByLike" resultType="goods">
    SELECT * FROM goods WHERE name LIKE #{name}
</select>
SqlSession sqlSession = SqlSessionFactoryUtil.getSqlSession();
GoodsMapper mapper = sqlSession.getMapper(GoodsMapper.class);
List<Goods> goodByLike = mapper.getGoodByLike("%红%");//直接将模糊条件传入即可
for (Goods goods : goodByLike) {
    System.out.println(goods);
}
第五节、分页查询

方式一、

1、在Mapper中直接通过SQL实现(DAO)

<select id="getGoodsBylimit" resultType="goods">
    SELECT * FROM goods limit #{start},#{pagesize}
</select>

2、在Service层调用DAO层(需要将前台传入参数做计算)

SqlSession sqlSession = SqlSessionFactoryUtil.getSqlSession();
GoodsMapper mapper = sqlSession.getMapper(GoodsMapper.class);

//查第几页    每页的条数  controller -->service-->dao
List<Goods> goodsBylimit = mapper.getGoodsBylimit(2, 2);

3、数据来源从页面上来–接收是通过Controller

注意:分页的计算方式: (pagenum-1)*pageSize, pageSize

方式二、通过PageHelper实现

pageHelper是MyBaits一个分页插件

环境搭建:

1、导入依赖pagehelper-5.1.2.jar jsqlparser-1.0.jar

2、在全局配置文件中使用pageHelper的插件

<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
	</plugin>
</plugins>

3、使用—Service层


//1.配置分页pageNum  第几页  pageSize 每一页多少条
PageHelper.startPage(2, 2);
SqlSession sqlSession = SqlSessionFactoryUtil.getSqlSession();
GoodsMapper mapper = sqlSession.getMapper(GoodsMapper.class);
List<Goods> allGoods = mapper.getAllGoods();

//通过pageInfo对象进行分页
PageInfo<Goods> pageInfo = new PageInfo<>(allGoods);

List<Goods> list = pageInfo.getList();
for (Goods goods : list) {
    System.out.println(goods);
}
System.out.println(pageInfo.getTotal());//获取数据的总数
System.out.println(pageInfo.getPrePage());//pageInfo 封装分页的一些信息
第六节、动态SQL

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

if标签

<if test="title != null">

规则:如果if中条件满足,则将if标签SQL进行拼接

<!--如果条件指传我才根据传入的条件进行查询
     什么都不传 查所有
     如:页面传了名字 按照名字查
        页面传了名字和地址  按名字和地址
        ...
    -->
SELECT * FROM goods WHERE 1=1
<if test="name!=null and name!=''">
    AND name=#{name}
</if>
<if test="location!=null and location!=''">
    AND location=#{location}
</if>		  
<if test="price!=null and price!=0">
    AND price > #{price}
</if>
</select>

choose、when、otherwise

作用:类似于JAVA中switch

<select id="getGoods" resultType="goods">
    SELECT * FROM goods WHERE 1=1
    <choose>
        <when test="name!=null and name!=''">
            AND name=#{name}
        </when>
        <when test="location!=null and location!=''">
            AND name=#{name}
        </when>
        <otherwise>
            ORDER BY  price DESC;
        </otherwise>
    </choose>
</select>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ehi7cAvV-1631707125150)(upload/image-20210904154728332.png)]

where

<select id="getGoods" resultType="goods">
    SELECT * FROM goods 
    <where>
        <if test="name!=null and name!=''">
            AND name=#{name}
        </if>
        <if test="location!=null and location!=''">
            AND location=#{location}r
        </if>
    </where>

set

image-20210904155346006

<update id="getGoods">
    update goods
    <set>
        <if test="name!=null and name!=''">
            name=#{name},
        </if>
        <if test="location!=null and location!=''">
            location=#{location},
        </if>	
    </set>
    WHERE id=#{id}
</update>

trim标签----自定义标签

image-20210904160626471

foreach标签 -----遍历list或者map集合

image-20210904161742306

/if>

location=#{location},


WHERE id=#{id}


**trim标签----自定义标签**

[外链图片转存中...(img-hk9vLBJs-1631707125152)]



**foreach标签 -----遍历list或者map集合**

[外链图片转存中...(img-mgAmfEij-1631707125153)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值