一、程序中的缓存
所谓的缓存,就是将程序或系统经常要调用的对象(临时数据)存在内存中,以便其使用时可以快速调用,不必再去创建新的重复的实例。这样做
可以减少和数据库的交互次数,提高效率。
什么样的数据能使用缓存,什么样的数据不能使用?
- 适用于缓存的数据:经常查询并且不经常改变的,并且数据的正确与否对最终结果影响不大。
- 不适用于缓存的数据:经常改变的数据,数据的正确与否对最终结果影响很大的。
- MyBatis目前的缓存方式在多表操作时是无解的,使用Mybatis进行多表操作不要进行缓存。
二、Mybatis的一级缓存
Mybatis的一级缓存指的是Mybatis中sqlSession对象的缓存,当我们执行查询以后,查询的结果会同时存入到SqlSession为我们提供的一块区域中,该区域的底层结构是一个Map,当我们再次查询同样的数据,mybatis会先去sqlsession中查询是否有,有的话直接拿出来用。一级缓存是SqlSession范围的缓存,当SqlSession对象消失时,mybatis的一级缓存也就消失了。如果调用SqlSession的修改、添加、删除、commit(),close等方法时,就会清空一级缓存。
- Mybatis默认支持一级缓存,当Mybatis与Spring整合后,一级缓存就失效了。
总结:mybatis的一级缓存是SqlSession级别的缓存,一级缓存缓存的是对象,当SqlSession提交、关闭以及其他的更新数据库的操作发生后,一级缓存就会清空。
三、测试Mybatis的一级缓存
1.User用户pojo
package com.gql.pojo;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 类说明:
* User_JavaBean
* @guoqianliang1998.
*/
public class User implements Serializable{
private static final long serialVersionUID = 1L;
private int id;
private String username;
private String sex;
private String address;
private Date birthday;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
2.dao接口
package com.gql.mapper;
import java.util.List;
import com.gql.pojo.User;
/**
* 类说明:
* 接口
* @guoqianliang1998.
*/
public interface UserMapper {
User getUserById(int id);
void updateUser(User user);
}
3.dao层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.gql.mapper.UserMapper">
<select id="getUserById" parameterType="java.lang.Integer" resultType="com.gql.pojo.User">
SELECT id,username,sex,address,birthday FROM user WHERE id = #{id};
</select>
<update id="updateUser" parameterType="com.gql.pojo.User">
UPDATE user SET
username=#{username},
sex=#{sex},
address=#{address},
birthday=#{birthday}
WHERE id =#{id};
</update>
</mapper>
4.测试一级缓存
package com.gql.mapper;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
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 org.junit.Before;
import org.junit.Test;
import com.gql.pojo.User;
public class UserMapperTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void init() throws IOException{
String resource = "mybatis-config.xml";
InputStream in = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
}
@Test
public void testCache1(){
SqlSession session = sqlSessionFactory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
//第一次查询数据库
User user1 = userMapper.getUserById(1);
System.out.println(user1.getUsername());
//更新一级缓存
user1.setUsername("周冬雨");
userMapper.updateUser(user1);
session.commit();
//第二次查询数据库
User user2 = userMapper.getUserById(1);
System.out.println(user2.getUsername());
}
}
在debug模式下单步调试上述代码,
①第一次查询数据库时,执行了sql语句,并向SqlSession添加了缓存。
②当执行了更新啊哦做commit后,SqlSession缓存被清空了。
③当再次执行查询数据库时,由于SqlSession已经被清空,仍然需要进行数据库的查询。