Java学习笔记-Day76 MyBatis 框架(三)



一、类型别名


类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。要将<typeAliases>放在mybatis配置文件的<configuration>中。在配置后,Goods 可以用来代替在任何使用 com.etc.entity.Goods 的地方。

  <typeAliases>
  	<typeAlias type="com.etc.entity.Goods" alias="Goods"/>
  	<typeAlias type="com.etc.entity.GoodsType" alias="GoodsType"/>
  </typeAliases>

二、MyBatis中的 # 和 $ 区别

元素 # $
类型匹配 #:会进行预编译,而且进行类型匹配 $:不进行数据类型匹配
替换或者拼接 #:用于变量替换 $:实质上是字符串拼接
场景 变量的传递,必须使用#,使用#{}就等于使用了PrepareStatement这种占位符的形式,提高效率。可以防止sql注入等等问题。# 方式一般用于传入添加,修改的值或查询,删除的where条件 id值 $ 只是只是简单的字符串拼接,要特别小心sql注入问题,对应非变量部分,只能用 $$ 方式一般用于传入数据库对象,比如这种group by 字段 ,order by 字段,表名,字段名等没法使用占位符的就需要使用${}

三、MyBatis的缓存


MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制。 默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行<cache>

1、一级缓存


一级缓存(本地缓存)是Session级别的缓存,是默认开启的。一个session做了一个查询操作,它会把这个查询操作的结果放在一级缓存中,如果短时间内这个session又做了同一个查询操作,那么会直接从一级缓存中获取,而不会再去数据库中获取数据。必须是同一个session范围内的操作,才能获取一级缓存的数据。

以下是一级缓存的两种情况:

  • 情况1:同一个session,同一个Mapper。
  • 情况2:同一个session,不同的Mapper。
package com.etc.test;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.etc.dao.GoodsMapper;
import com.etc.entity.Goods;

public class TestGoodsSelectCache {
    
    
	public static void main(String[] args) throws IOException {
    
    
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession session = sqlSessionFactory.openSession();
		GoodsMapper mapper = session.getMapper(GoodsMapper.class);
		Goods goods = mapper.selectGoodsById(1);
		// 一级缓存
		System.out.println("*********一级缓存(同一个session,同一个mapper)***********");
		Goods goods1 = mapper.selectGoodsById(1);
		System.out.println(goods);
		System.out.println(goods1);
		System.out.println("*********一级缓存(同一个session,不同mapper)***********");
		// 一级缓存
		GoodsMapper mapper2 = session.getMapper(GoodsMapper.class);
		Goods goods2 = mapper2.selectGoodsById(1);
		System.out.println(goods2);
	}
}

在这里插入图片描述

2、二级缓存


不同session范围内的操作才可以获取二级缓存的数据。二级缓存默认不开启。
  

启用二级缓存的步骤:

(1)在映射文件中添加一行 <cache/> 启用全局的二级缓存。

<cache/>语句的效果如下:

  • 映射语句文件中的所有 select 语句的结果将会被缓存。
  • 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
  • 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
  • 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
  • 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
  • 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.etc.dao.GoodsMapper">
	<resultMap id="GoodsResultMap" type="Goods">
		<id column="goodsid" property="goodsid" />
		<result column="goodsname" property="goodsname" />
		<result column="goodsprice" property="goodsprice" />
		<result column="goodsinfo" property="goodsinfo" />
		<result column="goodscount" property="goodscount" />
		<result column="cover" property="cover" />
		<result column="typeid" property="typeid" />
		<result column="shopid" property="shopid" />
		<result column="goodsstate" property="goodsstate" />
		<!-- 关联一个GoodsType对象 -->
		<association property="goodstype" column="typeid" javaType="GoodsType">
			<id column="typeid" property="typeid" />
			<result column="typename" property="typename" />
			<result column="typeinfo" property="typeinfo" />
		</association>
	</resultMap>
	<select id="selectGoodsById" resultMap="GoodsResultMap">
		select * from tbl_goods
		inner join tbl_goodstype on tbl_goods.typeid=tbl_goodstype.typeid
		where tbl_goods.goodsid=#{
    
    goodsid}
	</select>
	<cache></cache>
</mapper>

(2)实体类实现序列化接口。

package com.etc.entity;
import java.io.Serializable;

public class Goods implements Serializable {
    
    
    private int goodsid;
    private String goodsname;
    private Double goodsprice;
    private String goodsinfo;
    private int goodscount;
    private String cover;
    private int typeid;
    private int shopid;
    private int goodsstate;
    private GoodsType goodstype;   
    public Goods(int goodsid, String goodsname, Double goodsprice, String goodsinfo, int goodscount,
			String cover, int typeid, int shopid, int goodsstate, Goods goods) {
    
    
		super();
		this.goodsid = goodsid;
		this.goodsname = goodsname;
		this.goodsprice = goodsprice;
		this.goodsinfo = goodsinfo;
		this.goodscount = goodscount;
		this.cover = cover;
		this.typeid = typeid;
		this.shopid = shopid;
		this.goodsstate = goodsstate;
	}
	public Goods() {
    
    
		super();
	}
	public GoodsType getGoodstype() {
    
    
		return goodstype;
	}
	public void setGoodstype(GoodsType goodstype) {
    
    
		this.goodstype = goodstype;
	}
	public int getGoodsid() {
    
    
        return goodsid;
    }
    public void setGoodsid(int goodsid) {
    
    
        this.goodsid = goodsid;
    }
    public String getGoodsname() {
    
    
        return goodsname;
    }
    public void setGoodsname(String goodsname) {
    
    
        this.goodsname = goodsname == null ? null : goodsname.trim();
    }
    public Double getGoodsprice() {
    
    
        return goodsprice;
    }
    public void setGoodsprice(Double goodsprice) {
    
    
        this.goodsprice = goodsprice;
    }
    public String getGoodsinfo() {
    
    
        return goodsinfo;
    }
    public void setGoodsinfo(String goodsinfo) {
    
    
        this.goodsinfo = goodsinfo == null ? null : goodsinfo.trim();
    }
    public int getGoodscount() {
    
    
        return goodscount;
    }
    public void setGoodscount(int goodscount) {
    
    
        this.goodscount = goodscount;
    }
    public String getCover() {
    
    
        return cover;
    }
    public void setCover(String cover) {
    
    
        this.cover = cover == null ? null : cover.trim();
    }
    public int getTypeid() {
    
    
        return typeid;
    }
    public void setTypeid(int typeid) {
    
    
        this.typeid = typeid;
    }
    public int getShopid() {
    
    
        return shopid;
    }
    public void setShopid(int shopid) {
    
    
        this.shopid = shopid;
    }
    public int getGoodsstate() {
    
    
        return goodsstate;
    }
    public void setGoodsstate(int goodsstate) {
    
    
        this.goodsstate = goodsstate;
    }
	@Override
	public String toString() {
    
    
		return "Goods [goodsid=" + goodsid + ", goodsname=" + goodsname + ", goodsprice=" + goodsprice + ", goodsinfo="
				+ goodsinfo + ", goodscount=" + goodscount + ", cover=" + cover + ", typeid=" + typeid + ", shopid="
				+ shopid + ", goodsstate=" + goodsstate + ", goodstype=" + goodstype + "]";
	}
}

(3)使用 session.commit(); 提交第一个session。

package com.etc.test;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.etc.dao.GoodsMapper;
import com.etc.entity.Goods;

public class TestGoodsSelectCache {
    
    
	public static void main(String[] args) throws IOException {
    
    
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession session = sqlSessionFactory.openSession();
		GoodsMapper mapper = session.getMapper(GoodsMapper.class);
		Goods goods = mapper.selectGoodsById(1);
		System.out.println(goods);
		session.commit();//让二级缓存生效
		// 二级缓存
		System.out.println("*********二级缓存(不同的session)***********");
		SqlSession session2 = sqlSessionFactory.openSession();
		GoodsMapper mapper2 = session2.getMapper(GoodsMapper.class);
		Goods goods2 = mapper.selectGoodsById(1);
		System.out.println(goods2);
	}
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42141141/article/details/114379589