SSM之Mybatis_ch7(完结篇)——XML映射文件细解(五)

SSM之Mybatis_ch7

XML映射文件细解(五)

  • cache——命名空间的缓存配置
  • cache-ref——引用其他命名空间的缓存配置
  • resultMap——从数据库结果集中加载对象,是最复杂也最强大的元素
  • sql——可被其他语句引用的可重用语句块
  • insert——映射插入语句
  • update——映射更新语句
  • delete——映射删除语句
  • select——映射查询语句

此篇讲述cache缓存相关的内容

测试连通

Usermapper.java:列出此次要用到的几个方法

public interface UserMapper {

    // 根据id查询用户
    User queryUserById(@Param("id") int id);

    List<User> queryUsers();

    boolean updateUser(User user);
}

Usermapper.xml中相关的代码

<select id="queryUsers" resultType="user">
select * from mybatis.user
</select>

Test类中相关的代码

@Test
public void queryUsers() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    try {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = mapper.queryUsers();
        for (User user : userList) {
            System.out.println(user);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        sqlSession.close();
    }
}

测试结果

测试项目的连通

开始验证

一级缓存

一次会话中查询到的记录会在本地缓存中。一级缓存默认是开启的。

Usermapper.xml中相关的代码

<select id="queryUserById" resultType="user">
    select * from mybatis.user where id=#{id}
</select>

Test类中相关的代码

@Test
public void queryUserById() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    try {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User user1 = mapper.queryUserById(1);
        System.out.println(user1);

        // 再次执行相同的查询
        User user2 = mapper.queryUserById(1);
        System.out.println(user2);
        // 判断两个查询的结果的是否相等(hascode是否相等)
        System.out.println(user1 == user2);

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        sqlSession.close();
    }
}

运行结果:

一级缓存验证

select语句结果会被缓存,但是insert、update和delete会刷新缓存

也可以直接手动清理缓存sqlSession.clearCache();

Usermapper.xml中相关的代码

<update id="updateUser" parameterType="user">
    update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id}
</update>

在上面的查询use1和use2之间增加这一行

mapper.updateUser(new User(3,"reflect999","654321"));

运行结果

刷新之后的一级缓存验证

二级缓存

也叫作全局缓存,基于namespace级别的,即一个名称空间对应一个二级缓存。当一次会话关闭,将会把一级缓存存入到二级缓存。

在XML配置文件显示开启全局缓存

<!--显示的开启全局缓存-->
<setting name="cacheEnabled" value="true"/>

Usermapper.xml中相关的代码

<!--    在当前Mapper中使用二级缓存-->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
<!--    官方默认的配置-->
<!--    <cache eviction="FIFO"-->
<!--            flushInterval="60000"-->
<!--            size="512"-->
<!--            readOnly="true"/>-->

测试类中的相关代码

// 测试二级缓存
@Test
public void Test(){
    SqlSession sqlSession1 = MybatisUtils.getSqlSession();
    SqlSession sqlSession2 = MybatisUtils.getSqlSession();

    try {
        UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
        User user1 = mapper1.queryUserById(1);
        System.out.println(user1.hashCode());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        sqlSession1.close();
    }

    try {
        UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
        User user2 = mapper2.queryUserById(1);
        System.out.println(user2.hashCode());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        sqlSession2.close();
    }
}

运行结果

二级缓存验证

注:当使用上述官方的默认缓存配置,可能出现序列化错误,只需要将pojo类User实现Serializable即可。

全部代码

项目结构图

项目结构图

1.Pojo类User

package com.reflect.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * author: Administrator
 * date: 2021/1/2 - 18:17
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private int id;
    private String name;
    private String pwd;
}

2.UserMapper类和UserMapper.xml

package com.reflect.mapper;

import com.reflect.pojo.User;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * author: Administrator
 * date: 2021/1/2 - 18:18
 */
public interface UserMapper {

    List<User> queryUsers();

    // 根据id查询用户
    User queryUserById(@Param("id") int id);

    boolean updateUser(User user);
}
<?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.reflect.mapper.UserMapper">

<!--    在当前Mapper中使用二级缓存-->
    <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
<!--    官方默认的配置-->
    <!--    <cache eviction="FIFO"-->
    <!--            flushInterval="60000"-->
    <!--            size="512"-->
    <!--            readOnly="true"/>-->
    <select id="queryUsers" resultType="user">
        select * from mybatis.user
    </select>

<!--    可在此处显示定义不使用缓存,即设置为false,默认为true-->
    <select id="queryUserById" resultType="user" useCache="true">
        select * from mybatis.user where id=#{id}
    </select>

    <update id="updateUser" parameterType="user">
        update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id}
    </update>
</mapper>

3.Mybatis工具类与Mybatis配置文件、dbconfig数据库配置信息

package com.reflect.utils;

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 java.io.InputStream;

/**
 * author: Administrator
 * date: 2021/1/2 - 18:22
 */
public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }
}
<?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">

<configuration>
    <properties resource="dbconfig.properties">
    </properties>

<!--    开启驼峰命名-->
    <settings>
<!--        调试错误时建议开启日志功能,以方便观察错误-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
<!--        显示的开启全局缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>
    
<!--    设置别名-->
    <typeAliases>
        <package name="com.reflect.pojo"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <!-- 此处的resource要注意是'/',而不是'.'-->
        <mapper resource="com/reflect/mapper/UserMapper.xml"/>
    </mappers>
</configuration>
driver=com.mysql.cj.jdbc.Driver
#url中&在配置文件可以直接写,但是在程序中需要进行可能转义
url=jdbc:mysql://192.168.199.131:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=123456

4.测试类MyTest

import com.reflect.mapper.UserMapper;
import com.reflect.pojo.User;
import com.reflect.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

/**
 * author: Administrator
 * date: 2021/1/2 - 18:25
 */
public class MyTest {

    @Test
    public void queryUsers() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<User> userList = mapper.queryUsers();
            for (User user : userList) {
                System.out.println(user);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

    // 测试一级缓存
    @Test
    public void queryUserById() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        try {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);

            User user1 = mapper.queryUserById(1);
            System.out.println(user1);

            mapper.updateUser(new User(3,"reflect999","654321"));

            // 再次执行相同的查询
            User user2 = mapper.queryUserById(1);
            System.out.println(user2);
            // 判断两个查询的结果的是否相等(hascode是否相等)
            System.out.println(user1 == user2);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

    // 测试二级缓存
    @Test
    public void Test(){
        SqlSession sqlSession1 = MybatisUtils.getSqlSession();
        SqlSession sqlSession2 = MybatisUtils.getSqlSession();

        try {
            UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
            User user1 = mapper1.queryUserById(1);
            System.out.println(user1.hashCode());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession1.close();
        }

        try {
            UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
            User user2 = mapper2.queryUserById(1);
            System.out.println(user2.hashCode());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession2.close();
        }
    }
}

5.自定义缓存相关的配置文件

有需要的可以自行研究,此处只是验证缓存存在,不做过多概述。

<?xml version="1.0" encoding="UTF-8" ?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="false">

    <!--    diskStore: 为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置。参数解释如下:
            user.home - 用户主目录
            user.dir - 用户当前工作目录
            java.io.tmpdir - 默认临时文件路径
            -->
    <diskStore path="./tmpdir/Tmp_Ehcache"/>

    <defaultCache
            eternal="false"
            maxElementsInMemory="1000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="259200"
            memoryStoreEvictionPolicy="LRU"/>

    <cache
            name="cloud_user"
            eternal="false"
            maxElementsInMemory="5000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="259200"
            memoryStoreEvictionPolicy="LRU"/>

</ehcache>

因为许多东西用纯文字和代码无法演示出来,所以想尽量将自己所知识的分享出来,希望能对大家学习略有帮助,也是我自己学习路上的最好写照!有关其它配置,有兴趣的可以在MyBatis官网参考。
因为可能写的也并不是特别好,所以如果有什么不对的地方,希望大家不吝赐教!

至此,MyBatis部分到此告一段落了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值