Mybatis

目录

一、工程

1.1 依赖

1.2 配置

二、骚操作

2.1 Mapper.xml文件的不同映射方式

2.2 从外部引入数据连接

2.3 别名

2.4 setting

三、结果集映射、日志

3.1 结果集映射

 3.2 日志

四、使用注解开发

4.1 查询

 4.2 更新

4.3 添加

五、一对多和多对一处理

5.1 学生里面有一个老师类

5.2 老师类里面有一个学生集合

六、动态sql

6.1  where

 6.2 set

 6.4 sql片段

6.5 for-each

七、缓存

7.1 概述

 7.2 二级缓存


一、工程

1.1 依赖

      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.7</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.27</version>
    </dependency>
<resources>
   <resource>
       <directory>src/main/java</directory>
       <includes>
           <include>**/*.properties</include>
           <include>**/*.xml</include>
       </includes>
       <filtering>false</filtering>
   </resource>
   <resource>
       <directory>src/main/resources</directory>
       <includes>
           <include>**/*.properties</include>
           <include>**/*.xml</include>
       </includes>
       <filtering>false</filtering>
   </resource>
</resources>

1.2 配置

com.gzj.dao.pojo.User

package com.gzj.dao.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class User {
    private String name;
    private String pwd;
}

com.gzj.dao.mapper.UserMapper

package com.gzj.dao.mapper;

import com.gzj.dao.pojo.User;

import java.util.List;

public interface UserMapper {
    List<User> queryAllUsers();
}

com.gzj.dao.mapper.UserMapper.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.gzj.dao.mapper.UserMapper">
    <select id="queryAllUsers" resultType="com.gzj.dao.pojo.User">
  select * from user
 </select>
</mapper>

/resources/config.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">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:8848/test?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="12345678"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/gzj/dao/mapper/UserMapper.xml"/>
    </mappers>
</configuration>

com.gzj.utils.MybatisUtils

package com.gzj.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.IOException;
import java.io.InputStream;

public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;

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

    //获取SqlSession连接
    public static SqlSession getSession(){
        return sqlSessionFactory.openSession();
    }

}

test

    @Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        System.out.println(mapper.queryAllUsers());
        sqlSession.close();
    }

二、骚操作

2.1 Mapper.xml文件的不同映射方式

<!-- 使用相对于类路径的资源引用 -->
<mappers>
 <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- 使用完全限定资源定位符(URL) -->
<mappers>
 <mapper url="file:///var/mappers/AuthorMapper.xml"/>
</mappers>
<!--
使用映射器接口实现类的完全限定类名
需要配置文件名称和接口名称一致,并且位于同一目录下
-->
<mappers>
 <mapper class="org.mybatis.builder.AuthorMapper"/>
</mappers>
<!--
将包内的映射器接口实现全部注册为映射器
但是需要配置文件名称和接口名称一致,并且位于同一目录下
-->
<mappers>
 <package name="org.mybatis.builder"/>
</mappers>

2.2 从外部引入数据连接

/resources/db.properties

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:8848/test?useSSL=true&useUnicode=true&characterEncoding=utf8
username=root
password=12345678

 /resources/config.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">
<configuration>
    <!--导入properties文件-->
    <properties resource="db.properties"/>
    <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>
        <mapper class="com.gzj.dao.mapper.UserMapper"/>
    </mappers>
</configuration>

2.3 别名

<!--配置别名,注意顺序-->
<typeAliases>
   <typeAlias type="com.kuang.pojo.User" alias="User"/>
</typeAliases>
<typeAliases>
   <package name="com.kuang.pojo"/>
</typeAliases>

2.4 setting

  • 设置(settings)

    • 懒加载

    • 日志实现

    • 缓存开启关闭

  •  一个配置完整的 settings 元素的示例如下:
<settings>
 <setting name="cacheEnabled" value="true"/>
 <setting name="lazyLoadingEnabled" value="true"/>
 <setting name="multipleResultSetsEnabled" value="true"/>
 <setting name="useColumnLabel" value="true"/>
 <setting name="useGeneratedKeys" value="false"/>
 <setting name="autoMappingBehavior" value="PARTIAL"/>
 <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
 <setting name="defaultExecutorType" value="SIMPLE"/>
 <setting name="defaultStatementTimeout" value="25"/>
 <setting name="defaultFetchSize" value="100"/>
 <setting name="safeRowBoundsEnabled" value="false"/>
 <setting name="mapUnderscoreToCamelCase" value="false"/>
 <setting name="localCacheScope" value="SESSION"/>
 <setting name="jdbcTypeForNull" value="OTHER"/>
 <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>
<?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文件-->
    <properties resource="db.properties"/>
    <!-- 打印查询语句 -->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <typeAliases>
        <package name="com.gzj.dao.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>
        <mapper class="com.gzj.dao.mapper.UserMapper"/>
    </mappers>

</configuration>

三、结果集映射、日志

3.1 结果集映射

实体类字段与数据库字段不一致

 

com.gzj.dao.pojo.User

package com.gzj.dao.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class User {
    private String password;
    private String username;
}
<?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.gzj.dao.mapper.UserMapper">
    <resultMap id="UserMap" type="com.gzj.dao.pojo.User">
        <!-- column是数据库表的列名 , property是对应实体类的属性名 -->
        <result column="name" property="username"/>
        <result column="pwd" property="password"/>
    </resultMap>
<!--    返回值类型为 resultMap,而不是resultType-->
    <select id="queryAllUsers" resultMap="UserMap">
        select * from user
    </select>
</mapper>

 3.2 日志

具体选择哪个日志实现工具由MyBatis的内置日志工厂确定。它会使用最先找到的(按上文列举的顺序查找)。如果一个都未找到,日志功能就会被禁用。

  • 依赖
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.12</version>
    </dependency>
  •  log4j配置文件

/resources/log4j.properties

#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file

#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/kuang.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
  •  setting设置日志实现
<settings>
   <setting name="logImpl" value="LOG4J"/>
</settings>

四、使用注解开发

4.1 查询

com.gzj.dao.mapper.UserMapper

package com.gzj.dao.mapper;

import com.gzj.dao.pojo.User;
import org.apache.ibatis.annotations.Select;

import java.util.List;
public interface UserMapper {
    @Select("select * from user")
    List<User> queryAllUsers();
}
    <mappers>
        <mapper class="com.gzj.dao.mapper.UserMapper"/>
    </mappers>

resultType省略了 

本质上利用了jvm的动态代理机制

 4.2 更新

    @Update("update user set pwd=#{newPwd} where name = #{name}")
    void updateUser(@Param("newPwd") String pwd,@Param("name")String name);

4.3 添加

    @Insert("insert into user values(#{name},#{pwd})")
    void addUser(User user);

五、一对多和多对一处理

5.1 学生里面有一个老师类

CREATE TABLE `teacher` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO teacher(`id`, `name`) VALUES (1, '秦老师');

CREATE TABLE `student` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fktid` (`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;


INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');
package com.gzj.dao.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class Teacher {
    private int id;
    private String name;
}
package com.gzj.dao.pojo;

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

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private int id;
    private String name;
    //多个学生可以是同一个老师,即多对一
    private Teacher teacher;
}
package com.gzj.dao.mapper;

import com.gzj.dao.pojo.Student;

import java.util.List;

public interface StudentMapper {
    List<Student> queryStudents();
}
<?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.gzj.dao.mapper.StudentMapper">
<!--    List<Student> queryStudents();-->
    <resultMap id="tea" type="Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
    </resultMap>
    <resultMap id="sT" type="com.gzj.dao.pojo.Student">
        <id property="id" column="sid"/>
        <result property="name" column="sname"/>
        <!--关联对象property 关联对象在Student实体类中的属性-->
        <association property="teacher" resultMap="tea"/>
    </resultMap>
    <select id="queryStudents" resultMap="sT">
        select s.id sid,s.name sname,t.id tid,t.name tname from student s inner join teacher t on s.tid = t.id and t.name='秦老师';
    </select>


</mapper>

Student类必须有无参构造

5.2 老师类里面有一个学生集合

package com.gzj.dao.pojo;

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

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private int id;
    private String name;
    private int tid;
}
package com.gzj.dao.pojo;

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

import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
    private int id;
    private String name;
    //一个老师多个学生
    private List<Student> students;
}
<?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.gzj.dao.mapper.TeacherMapper">
<!--    List<Teacher> queryTeachers();-->
    <select id="queryTeachers" resultMap="tS">
        select t.id tid,t.name tname,s.id sid,s.name sname from student s inner join teacher t on s.tid = t.id and t.name='秦老师';
    </select>
    <resultMap id="tS" type="Teacher">
        <id property="id" column="tid"/>
        <result property="name" column="tname"/>
        <collection property="students" ofType="Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
        </collection>
    </resultMap>
</mapper>

resultMap中的属性:

  • id   代表主键字段
  • result   普通字段

六、动态sql

6.1  where

DROP TABLE IF EXISTS `blog`;
CREATE TABLE `blog` (
  `id` varchar(50) NOT NULL COMMENT '博客id',
  `title` varchar(100) NOT NULL COMMENT '博客标题',
  `author` varchar(30) NOT NULL COMMENT '博客作者',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `views` int(30) NOT NULL COMMENT '浏览量'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of blog
-- ----------------------------
INSERT INTO `blog` VALUES ('1', 'Java', 'so', '2021-12-13 20:29:31', '1');
INSERT INTO `blog` VALUES ('2', 'C++', 'so01', '2021-12-13 20:30:03', '2');
INSERT INTO `blog` VALUES ('3', 'Python', 'so02', '2021-12-13 20:30:20', '3');

需求:根据作者名字和博客名字来查询博客!如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询

 mybatis核心配置文件,下划线驼峰自动转换

   <setting name="mapUnderscoreToCamelCase" value="true"/>
create_time--->createTime
package com.gzj.dao.pojo;

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

import java.sql.Timestamp;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Blog {

    private String id;
    private String title;
    private String author;
    private Timestamp create_time;
    private int views;
}

<?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.gzj.dao.mapper.BlogMapper">
<!--    List<Blog> queryBlogs(Map<String,Object>map);-->
    <select id="queryBlogs" parameterType="map" resultType="Blog">
        select * from blog where
        <if test="title != null">
            title = #{title}
        </if>
        <if test="author != null">
            and author = #{author}
        </if>
    </select>
</mapper>

这样写我们可以看到,如果 author 等于 null,那么查询语句为 select * from user where title=#{title},但是如果title为空呢?那么查询语句为 select * from user where and author=#{author},这是错误的 SQL 语句,如何解决呢?

<?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.gzj.dao.mapper.BlogMapper">
<!--    List<Blog> queryBlogs(Map<String,Object>map);-->
    <select id="queryBlogs" parameterType="map" resultType="Blog">
        select * from blog
        <where>
            <if test="title != null">
                title = #{title}
            </if>
            <if test="author != null">
                and author = #{author}
            </if>
        </where>
    </select>
</mapper>

 这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。

 6.2 set

<!--注意set是用的逗号隔开-->
<update id="updateBlog" parameterType="map">
  update blog
     <set>
         <if test="title != null">
            title = #{title},
         </if>
         <if test="author != null">
            author = #{author}
         </if>
     </set>
  where id = #{id};
</update>

6.3 choose

有时候,我们不想用到所有的查询条件,只想选择其中的一个,查询条件有一个满足即可,使用 choose 标签可以解决此类问题,类似于 Java 的 switch 语句

<?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.gzj.dao.mapper.BlogMapper">
<!--    List<Blog> queryBlogs(Map<String,Object>map);-->
    <select id="queryBlogs" parameterType="map" resultType="Blog">
        select * from blog
        <where>
            <choose>
                <when test="title != null">
                    title = #{title}
                </when>
                <when test="author != null">
                    author = #{author}
                </when>
                <otherwise>
                    views = 1
                </otherwise>
            </choose>
        </where>
    </select>
</mapper>

 6.4 sql片段

有时候可能某个 sql 语句我们用的特别多,为了增加代码的重用性,简化代码,我们需要将这些代码抽取出来,然后使用时直接调用。

<?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.gzj.dao.mapper.BlogMapper">
<!--    List<Blog> queryBlogs(Map<String,Object>map);-->
    <select id="queryBlogs" parameterType="map" resultType="Blog">
        select * from blog
        <where>
            <include refid="test"/>
        </where>
    </select>
    <sql id="test">
        <choose>
            <when test="title != null">
                title = #{title}
            </when>
            <when test="author != null">
                author = #{author}
            </when>
            <otherwise>
                views = 1
            </otherwise>
        </choose>
    </sql>
</mapper>

6.5 for-each

需求:我们需要查询 blog 表中 id 分别为1,2,3的博客信息

<?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.gzj.dao.mapper.BlogMapper">
<!--    List<Blog> queryBlogs(Map<String,Object>map);-->
    <select id="queryBlogs" parameterType="map" resultType="Blog">
        select * from blog
        <where>
            <!--
      collection:指定输入对象中的集合属性
      item:每次遍历生成的对象
      open:开始遍历时的拼接字符串
      close:结束时拼接的字符串
      separator:遍历对象之间需要拼接的字符串
      select * from blog WHERE ( id = ? or id = ? or id = ? )
    -->
            <foreach collection="ids" item="id" open="and (" close=")" separator="or">
                id = #{id}
            </foreach>
        </where>
    </select>

</mapper>

test

    public void test(){
        SqlSession sqlSession = MybatisUtils.getSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Map<String,Object> map = new HashMap<>();
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        map.put("ids",list);
        System.out.println(mapper.queryBlogs(map));

    }

七、缓存

7.1 概述

  • MyBatis系统中默认定义了两级缓存:一级缓存二级缓存

    • 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)

    • 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。

    • 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存

一级缓存也叫本地缓存:

  • 与数据库同一次会话期间查询到的数据会放在本地缓存中。

  • 以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库;

package com.gzj.dao.mapper;
import com.gzj.dao.pojo.User;
import org.apache.ibatis.annotations.Select;

import java.util.List;
public interface UserMapper {
    @Select("select * from user")
    List<User> queryAllUsers();
}

测试,查询两次不关闭sqlSession

@Test
public void testQueryUserById(){
   SqlSession session = MybatisUtils.getSession();
   UserMapper mapper = session.getMapper(UserMapper.class);

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

   session.close();
}

 每个sqlSession中的缓存相互独立

  •  sqlSession相同,两次查询之间执行了增删改操作!

 观察结果:查询在中间执行了增删改操作后,重新执行了

  •  sqlSession相同,手动清除一级缓存
    @Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        System.out.println(mapper.queryAllUsers());
        sqlSession.clearCache();
        System.out.println(mapper.queryAllUsers());
        System.out.println();
        sqlSession.close();
    }

 

 7.2 二级缓存

  • 二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存

  • 基于namespace级别的缓存,一个名称空间,对应一个二级缓存;

  • 工作机制

    • 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;

    • 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;

    • 新的会话查询信息,就可以从二级缓存中获取内容;

    • 不同的mapper查出的数据会放在自己对应的缓存(map)中;

  •  使用步骤

 1、开启全局缓存 

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

2、在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.gzj.dao.mapper.BlogMapper">
<!--    这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用-->
    <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
<!--    List<Blog> queryBlogs(Map<String,Object>map);-->
    <select id="queryBlogs"  resultType="Blog">
        select * from blog
    </select>

</mapper>

3、test

    @Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        System.out.println(mapper.queryBlogs());
        sqlSession.close();
        SqlSession sqlSession1 = MybatisUtils.getSession();
        BlogMapper mapper1 = sqlSession1.getMapper(BlogMapper.class);
        System.out.println(mapper1.queryBlogs());
        sqlSession1.close();
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值