Mybatis_11 Mybatis 缓存

一、Mybatis中的缓存

什么是缓存?
	存在于内存中的临时数据。
为什么使用缓存?
	减少和数据库的交互次数,提高执行效率、
什么样的数据能使用缓存,什么样的数据不能使用缓存
	适用于缓存:
		经常查询,并且不经常改变的。
		数据的正确与否对最终结果影响不大的。
不适用于缓存的:
	例如:商品的库存,银行的汇率,股市的牌价。

二、Mybatis中的一级缓存和二级缓存

一级缓存

1、说明:
	它指的是Mybatis中的SQLSession对象的缓存。
	当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供的一块区域中。
	该区域的结构是一个map,当我们再次查询同样的数据,mybatis会先去SQLSession中
	查询是否有,有的话直接拿出来使用。
	当SQLSession对象消失时,mybatis的一级缓存就消失了。
2、注意:
	一级缓存是sqlSession范围的缓存,当调用SqlSession的修改,添加,删除,commit(),close()等
	方法时,就会清空一级缓存。

二级缓存

1、说明:
	它指的是Mybatis中SQLSessionFactory对象的缓存。由同一个SQLSessionFactory对象创建的SqlSession
	共享其缓存。
2、二级缓存的使用步骤:
	第一步:让Mybatis框架支持二级缓存(SQLMapConfig.xml中配置)
			 <!-- 配置参数 -->
			 <settings>
				 <!-- 	全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 -->
				 <setting name="cacheEnabled" value="true"/>
			</settings>
	第二步:让当前的映射文件支持二级缓存(在IUserDao.xml中配置)
			<!-- 开启user支持二级缓存 -->
			<cache></cache>
	第三步:让当前的操作支持二级缓存(在select标签中配置)
			<!-- 根据id查询 -->
			<select id="findById" parameterType="INT"  resultType="User" useCache="true">
				select * from user where id=#{id}
			</select>
	测试代码     
		第一步:创建一个SqlSessionFactory对象
		第二步:创建两个SqlSession对象
		思想:如图。
	代码:
		factory= new SqlSessionFactoryBuilder().build(in);
	
		@Test
		public void testFirstCache() {
		//第一个SqlSession对象
			SqlSession sqlSession1 = factory.openSession(true);
			IUserDao userDao1 = sqlSession1.getMapper(IUserDao.class);
			User user1 = userDao1.findById(41);
			System.out.println(user1);
			sqlSession1.close();//一级缓存消失
		//第二个SqlSession对象	
			SqlSession sqlSession2 = factory.openSession(true);
			IUserDao userDao2 = sqlSession2.getMapper(IUserDao.class);
			User user2 = userDao2.findById(41);
			System.out.println(user2);
			System.out.println(user1==user2);
			
			System.out.println(user1==user2);
			
		}

三、一级缓存

分析: 一级缓存是 SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除,commit(),close()等

public class MybatisTest {
	private InputStream in;
	private SqlSessionFactory factory;
	private SqlSession sqlSession;
	private IUserDao userDao;
	@Before
	public void init() throws IOException {
		//1、读取配置文件
		in = Resources.getResourceAsStream("SqlMapConfig.xml");
		//2、创建SqlSessionFactory工厂(工厂模式)
		factory= new SqlSessionFactoryBuilder().build(in);
		//3、使用工厂生产SqlSesson对象
		sqlSession = factory.openSession(true);//手动将事务提交方式改为自动提交
		//4、使用SqlSession创建Dao接口的代理对象
		userDao = sqlSession.getMapper(IUserDao.class);

	}
	@After//用于在测试方法执行之后执行
	public void destory() throws Exception {
		//提交事务
		//sqlSession.commit();
		//6、释放资源
		sqlSession.close();
		in.close();
	}
	
	/**
	 * 测试一级缓存
	 */
	@Test
	public void testFirstCache() {
		User user1 = userDao.findById(41);
		System.out.println(user1);//com.song.domain.User@18ce0030
		
		User user2 = userDao.findById(41);
		System.out.println(user2);//com.song.domain.User@18ce0030
		System.out.println(user1==user2);//true
		
	}
	/**
	 * 	测试一级缓存
	 * 		一下三种方式都可以清空缓存
	 */
	@Test
	public void testClearCache() {
		//1、根据id查询用户
		User user1 = userDao.findById(41);
		System.out.println(user1);//com.song.domain.User@18ce0030

		//2.1更新用户信息(执行此方法时会清空缓存,导致两次查询对象不是同一个)
		user1.setUsername("update user clear cache");
		user1.setAddress("北京市显示");
		userDao.updateUser(user1);
		
		//2.2重新获取SqlSession对象
//		sqlSession.close();
//		//再次获取sqlSession对象
//		sqlSession = factory.openSession(true);
//		userDao = sqlSession.getMapper(IUserDao.class);
		
		//2.3清空缓存
//		sqlSession.clearCache();//此方法可以清空缓存
		
		//3、再次查询id为41的用户
		User user2 = userDao.findById(41);
		System.out.println(user2);//com.song.domain.User@25d250c6
		System.out.println(user1==user2);//false
		
	}
	
}

在这里插入图片描述

四、二级缓存

1、二级缓存使用步骤

第一步:让Mybatis框架支持二级缓存(SQLMapConfig.xml中配置)
	<!-- 配置参数 -->
	<settings>
		 <!-- 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 -->
		 <setting name="cacheEnabled" value="true"/>
	</settings>
	
第二步:让当前的映射文件支持二级缓存(在IUserDao.xml中配置)
	<!-- 开启user支持二级缓存 -->
	<cache></cache>
	
第三步:让当前的操作支持二级缓存(在select标签中配置)
	<!-- 根据id查询 -->
	<select id="findById" parameterType="INT"  resultType="User" useCache="true">
		select * from user where id=#{id}
	</select>

2、配置SQLMapConfig.xml支持缓存

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration  
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- mybatis的主配置文件 -->  
<configuration>
	
	<!-- 可以在标签内部配置连接数据库的信息。也可以通过属性引用外部配置文件信息 -->
	<properties resource="jdbcConfig.properties"></properties>
	 
	 <!-- 配置参数 -->
	 <settings>
	 	<!-- 开启Mybatis支持延迟加载 -->
		 <setting name="lazyLoadingEnabled" value="true"/>
		 <setting name="aggressiveLazyLoading" value="false"/>
		 <!-- 	全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 -->
		 <setting name="cacheEnabled" value="true"/>
	</settings>
	
		
	<!-- 使用typeAliases配置别名,它只能配置domain中类的别名-->
	<!-- package:用于配置别名的包,当指定之后,该包下的实体类都会注册别名  类名就是别名不区分大小写 -->
 	<typeAliases><package name="com.song.domain"></package></typeAliases> 
	
	<!-- 配置环境 -->
	<environments default="mysql">
		<!-- 配置MySQL的环境 -->
		<environment id="mysql">
			<!-- 配置事务的类型 -->
			<transactionManager type="JDBC"></transactionManager>
			<!-- 配置数据源(连接池) -->
			<dataSource type="POOLED">
				<!-- 配置连接数据库的四个基本信息 -->
				<property name="driver" value="${jdbc.driver}"></property>
				<property name="url" value="${jdbc.url}"></property>
				<property name="username" value="${jdbc.username}"></property>
				<property name="password" value="${jdbc.password}"></property>
			</dataSource>
		</environment>
	</environments>
	
	
	 <mappers>
		<!-- <mapper resource = "com/song/dao/IUserDao.xml"></mapper> -->
		<!--package标签是用于指定dao接口所在的包 :当指定完成之后就不需要再写mapper以及resource或者class了-->
		<package name="com.song.dao"></package>	
	 </mappers> 
		
</configuration>

3、配置IUserDao.xml支持二级缓存

<?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.song.dao.IUserDao">
	<!-- 配置查询所有 -->
	<!-- ①开启user支持二级缓存 -->
	<cache></cache>
	
	<!-- 查询所有 -->
	<select id="findAll" resultType="User">
		select * from user
	</select>
	<!-- ②根据id查询 -->
	<select id="findById" parameterType="INT"  resultType="User" useCache="true">
		select * from user where id=#{id}
	</select>
	<!-- 修改用户地址和名字 -->
	<update id="updateUser" parameterType="user">
		update user set username=#{username},address=#{address} where id=#{id}
	</update>
	
</mapper>

4、编写二级缓存测试类

public class SeconedCacheTest {
	private InputStream in;
	private SqlSessionFactory factory;

	@Before
	public void init() throws IOException {
		//1、读取配置文件
		in = Resources.getResourceAsStream("SqlMapConfig.xml");
		//2、创建SqlSessionFactory工厂(工厂模式)
		factory= new SqlSessionFactoryBuilder().build(in);
		//3、使用工厂生产SqlSesson对象
		//sqlSession = factory.openSession(true);//手动将事务提交方式改为自动提交
		//4、使用SqlSession创建Dao接口的代理对象
		//userDao = sqlSession.getMapper(IUserDao.class);

	}
	@After//用于在测试方法执行之后执行
	public void destory() throws Exception {
		//提交事务
		//sqlSession.commit();
		//6、释放资源
		//sqlSession.close();
		in.close();
	}
		
	/**
	 * 测试一级缓存
	 */
	@Test
	public void testFirstCache() {
		SqlSession sqlSession1 = factory.openSession(true);
		IUserDao userDao1 = sqlSession1.getMapper(IUserDao.class);
		User user1 = userDao1.findById(41);
		System.out.println(user1);//com.song.domain.User@18ce0030
		sqlSession1.close();//一级缓存消失
		
		SqlSession sqlSession2 = factory.openSession(true);
		IUserDao userDao2 = sqlSession2.getMapper(IUserDao.class);
		User user2 = userDao2.findById(41);
		System.out.println(user2);//com.song.domain.User@5dd6264
		
		System.out.println(user1==user2);//false
		System.out.println(user1.getAddress().equals(user2.getAddress()));//true
		
	}
	
}

5、二级缓存测试结果说明

在这里插入图片描述

6、二级缓存测试控制台说明

在这里插入图片描述
经过上面的测试,我们发现执行了两次查询,并且在执行第一次查询后,我们关闭了一级缓存,再去执行第二次查询时,我们发现并没有对数据库发出 sql 语句,所以此时的数据就只能是来自于我们所说的二级缓存。

7、 二级缓存注意事项

当我们在使用二级缓存时,所缓存的类一定要实现 java.io.Serializable 接口,这种就可以使用序列化方式来保存对象。

public class User implements Serializable {
	private Integer id;
	private String username;
	private Date birthday;
	private String sex;
	private String address;
}

五、基于注解的二级缓存配置

1、配置SQLMapConfig.xml

  <!-- 配置开启二级缓存 -->
  <settings>
  	<setting name="cacheEnabled" value="true"/>
  </settings>

2、持久层接口

//mybatis 基于注解方式实现配置二级缓存
@CacheNamespace(blocking = true)
public interface IUserDao {

	//根据id查询
	@Select("select * from user where id=#{uid}")
	User findById(Integer id);

}
深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值