Mybatis学习笔记

Mybatis

一、第一个 Mybatis 程序
1. 创建一个简单的 Maven 项目
2. 导入相关 jar 包

pom.xml

<dependencies>
    <!-- 导入相关 jar 包 -->
    <dependency>
        <!-- mybatis jar 包 -->
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.2</version>
    </dependency>

    <dependency>
        <!-- 数据库驱动 jar 包 -->
        <groupId>org.mariadb.jdbc</groupId>
        <artifactId>mariadb-java-client</artifactId>
        <version>2.7.2</version>
        <type>pom</type>
    </dependency>

    <dependency>
        <!-- junit 包,测试使用 -->
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.9</version>
        <type>pom</type>
    </dependency>
</dependencies>

<!-- 防止 maven 读取不到配置文件 -->
<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
                <include>**/*.properties</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.xml</include>
                <include>**/*.properties</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>
3. 创建 mybatis xml 配置文件

与数据库进行交互

src / main / resources / mybatis-config.xml

<configuration>
    <!-- 核心配置文件-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="org.mariadb.jdbc.Driver"/>
                <property name="url" value="jdbc:mariadb://localhost:3306/mybatis?useSSL=false&amp;characterEncoding=UTF-8&amp;useUnicode=true"/>
                <property name="username" value="root"/>
                <property name="password" value="ruirui"/>
            </dataSource>
        </environment>
    </environments>
<!--    需与 mapper.xml 映射起来-->
    <mappers>
        <mapper resource="com/nari/mybatis/mapper/MybatisDemoMapper.xml"/>
    </mappers>
</configuration>
4. 创建 mapper.xml 文件

可放在任意位置,类必须使用全限定类名

<!-- 命名空间是 mapper 接口 -->
<mapper namespace="com.nari.mybatis.mapper.IMybatisDemoMapper">
    <!-- id 是接口中的方法,resultType 是实体类 -->
    <select id="findAll" resultType="com.nari.mybatis.pojo.MybatisDemo1Pojo">
        select * from mybatisdemo1
    </select>
</mapper>
5. 使用 SqlSessionFactoryBuilder 创建 SqlSession 对象
// 创建 builder 对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
String mybatisXml = "mybatis-config.xml";
// 通过流读取 mybatis 配置文件
InputStream inputStream = Resources.getResourceAsStream(mybatisXml);
// 通过 builder 得到 SqlSessionFactory 对象,用于创建 SqlSession
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
6. 测试连接
@Test
public void MybatisDemo1Test(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    // 参数是 mapper 接口的类
    IMybatisDemoMapper mapper = sqlSession.getMapper(IMybatisDemoMapper.class);
    for (MybatisDemo1Pojo mybatisDemo1Pojo : mapper.findAll()){
        System.out.println(mybatisDemo1Pojo);
    }
    sqlSession.close();
}
二、mapper 配置文件详解
1. SELECT 标签

id:对应的 namespace 中的接口方法名

resultType:结果集类型

parameterType:参数类型

2. INSERT 、UPDATE、DELETE 标签

id:对应的 namespace 中的接口方法名

parameterType:参数类型

mapper.xml:

<select id="findAll" resultType="com.nari.mybatis.pojo.MybatisDemo1Pojo">
        select * from mybatisdemo1
</select>

<select id="findById" resultType="com.nari.mybatis.pojo.MybatisDemo1Pojo" parameterType="Integer">
    select * from mybatisdemo1 where id = #{id}
</select>

<insert id="insertUser" parameterType="com.nari.mybatis.pojo.MybatisDemo1Pojo">
    insert into mybatisdemo1 (id, name, age, address) value (#{id}, #{name}, #{age}, #{address})
</insert>

<update id="updateUser" parameterType="com.nari.mybatis.pojo.MybatisDemo1Pojo">
    update mybatisdemo1 set name=#{name}, age=#{age}, address=#{address} where id=#{id}
</update>

<delete id="deleteUser" parameterType="int">
    delete from mybatisdemo1 where id=#{id}
</delete>

IMybatisMapper:

// 查询所有用户
List<MybatisDemo1Pojo> findAll();

// 通过 ID 查询用户
MybatisDemo1Pojo findById(Integer id);

// 插入
void insertUser(MybatisDemo1Pojo mybatisDemo1Pojo);

// 修改
void updateUser(MybatisDemo1Pojo mybatisDemo1Pojo);

// 删除
void deleteUser(Integer id);

test:

@Test
public void FindAll(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    IMybatisDemoMapper mapper = sqlSession.getMapper(IMybatisDemoMapper.class);
    for (MybatisDemo1Pojo mybatisDemo1Pojo : mapper.findAll()){
        System.out.println(mybatisDemo1Pojo);
    }
    sqlSession.close();
}

@Test
public void FindById(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    IMybatisDemoMapper mapper = sqlSession.getMapper(IMybatisDemoMapper.class);
    MybatisDemo1Pojo byId = mapper.findById(2);
    System.out.println(byId);
    sqlSession.close();
}

@Test
public void InsertUser(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    IMybatisDemoMapper mapper = sqlSession.getMapper(IMybatisDemoMapper.class);
    mapper.insertUser(new MybatisDemo1Pojo(null, "王五", 32, "太原"));
    sqlSession.commit();
    sqlSession.close();
}

@Test
public void UpdateUser(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    IMybatisDemoMapper mapper = sqlSession.getMapper(IMybatisDemoMapper.class);
    mapper.updateUser(new MybatisDemo1Pojo(2, "孙六", 33, "运城"));
    sqlSession.commit();
    sqlSession.close();
}

@Test
public void DeleteUser(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    IMybatisDemoMapper mapper = sqlSession.getMapper(IMybatisDemoMapper.class);
    mapper.deleteUser(3);
    sqlSession.commit();
    sqlSession.close();
}

注意点:

1. 除了 SELECT 有结果集类型,其它没有结果集类型
2. 除了查询外,增删改完成后,需要提交事务,否则数据不会更新
三、万能的 map
  • 如果数据库中的字段很多,我们在插入或更新数据库数据的时候,如果是使用实体类当参数,就要填入很多的参数,而且有的参数我们是用不到的,比如下面这个 insert 语句:
<insert id="insertUser" parameterType="com.nari.mybatis.pojo.MybatisDemo1Pojo">
    insert into mybatisdemo1 (id, name, age, address) value (#{id}, #{name}, #{age}, #{address})
</insert>

​ 如果我们只想插入 name、address 字段,我们也需要把实体类所有的字段都填上,而且名字还得和实体类中的一样,因为实体类中只有无参和全参构造,否则只能在实体类中在添加一个只有 name 和 address 的有参构造,这样的话就不太灵活,如果要解决这个问题,我们就可以使用 map,接口方法的参数为 map,mapper 映射文件中的类型也是 map,这样我们就可以只传入 name 和 address 了,而且名字也可以自定义,如下:

​ 接口方法:

public interface IMybatisDemoMapper {
    public void insertUser(HashMap user);
}

​ mapper 映射文件:

<insert id="insertUser" parameterType="map">
    insert into mybatisdemo1 (name,age,address) values (#{userName}, #{userAge}, #{userAddress})
</insert>

​ test 方法中:

@Test
public void insertUsers(){
    SqlSession sqlSession = MybatisDemoUtils.getSqlSession();
    IMybatisDemoMapper mapper = sqlSession.getMapper(IMybatisDemoMapper.class);
    HashMap map = new HashMap();
    map.put("userName", "孙六");
    map.put("userAge", 33);
    map.put("userAddress", "广东");
    mapper.insertUser(map);
    sqlSession.commit();
    sqlSession.close();
}
四、配置文件解析
核心配置文件
mybatis-config.xml
1.	properties(属性)
2.	settings(设置)
3.	typeAliases(类型别名)
4.	typeHandlers(类型处理器)
5.	objectFactory(对象工厂)
6.	plugins(插件)
7.	environments(环境配置)
8.	environment(环境变量)
9.	transactionManager(事务管理器)
10.	dataSource(数据源)
11.	databaseIdProvider(数据库厂商标识)
12.	mappers(映射器)
a)environments:环境配置
<environments default="mysql">
    <environment id="mysql">
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
            <property name="driver" value="org.mariadb.jdbc.Driver"/>
            <property name="url" value="jdbc:mariadb://localhost:3306/mybatis?useSSL=false&amp;characterEncoding=UTF-8&amp;useUnicode=true"/>
            <property name="username" value="root"/>
            <property name="password" value="ruirui"/>
        </dataSource>
    </environment>
    
    <environment id="oracle">
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
            <property name="driver" value="org.mariadb.jdbc.Driver"/>
            <property name="url" value="jdbc:mariadb://localhost:3306/mybatis?useSSL=false&amp;characterEncoding=UTF-8&amp;useUnicode=true"/>
            <property name="username" value="root"/>
            <property name="password" value="ruirui"/>
        </dataSource>
    </environment>
</environments>

​ 上面就是环境的配置,即可以在里面配置多套不同的数据库或者不同的应用环境(生产 or 测试)

b)transactionManager:事务管理

​ 默认是 JDBC,还有一个 MANAGED,但是这个一般不用,只有在老的项目才会有用,如:EJB。。

c)dataSource:数据源

​ 默认是 POOLED,还有 UNPOOLED、JNDI

​ POOLED:数据源连接池,每次用完都会把连接放回到池里,而不是关闭,以供下次使用

​ UNPOOLED:非池,每次都会创建和关闭连接

​ JNDI:正常的数据源

d)mappers:映射器

​ 用于告诉 mybatis 哪里可以找到 sql 语句,可以通过四种方式定位资源,一般使用第一种

<mappers>
    <!-- 方式一:类路径 -->
	<mapper resource="com/nari/mybatismapper/IMybatisDemoMapper.xml"></mapper>
    <!-- 方式二:文件绝对路径 -->
    <mapper url="file:///var/mappers/AuthorMapper.xml"></mapper>
    <!-- 方式三:接口实现类的完全限定类名 -->
    <mapper class="com.nari.mybatismapper.IMybatisDemoMapper"></mapper>
    <!-- 方式四:将包内的映射器接口实现全部注册为映射器 -->
    <mapper name="com.nari.mybatismapper"></mapper>
</mappers>

​ 注意点:

- 推荐使用方式一
- 极不推荐使用方式二
- 使用方式三和方式四,mapper 映射文件必须和类同名,且必须在同一个包下
e)properties:属性
<!-- 两种方式配置 -->
<!-- 方式一,引入外部属性 -->
<properties resource="db.properties"/>

​ src / main / resources / db.properties:

url=jdbc:mariadb://localhost:3306/mybatis?useSSL=false&characterEncoding=UTF-8&useUnicode=true
driver=org.mariadb.jdbc.Driver
username=root
password=ruirui
<!-- 方式二,内部标签写属性 -->
<properties>
	<property name="username" value="root"/>
    <property name="password" value="ruirui"/>
</properties>

​ 然后在 mybatis-config.xml 中配置:

​ 把属性以 ${ } 的方式引入外部变量

<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>

​ 两种方式的优先级:

	- 优先使用外部的配置文件内容
f)typeAliases :类型别名

​ 为 javaBean 对象起别名,用来代替 mapper.xml 文件中的全限定类名

两种方式:

​ 方式一:为具体的实体类起别名

<typeAliases>
    <typeAlias type="com.nari.mybatisPojo.User" alias="User"/>
    <typeAlias type="com.nari.mybatisPojo.Admin" alias="Admin"/>
</typeAliases>

​ 方式二:扫描整个包下的实体类

<typeAliases>
	<package name="com.nari.mybatisPojo"/>
</typeAliases>

​ 二者区别:

  • 为具体的类起别名,可以自定义别名,而扫描整个包的话,不可以自定义别名
  • 建议具体的类别名为首字母大写,扫描包的别名首字母小写,作为区分
  • 可以用注解的方式为扫描包的实体类自定义别名,如下:
@Alias("Admin")
public class MybatisDemoEntry {...}
  • 二者没有优先级问题,都可以使用
  • 如果实体类比较少的话,推荐使用方式一,如果实体类比较多的话,就扫描整个包,然后用注解

mybatis 中的默认别名:

  • _int int

  • int Intrger

  • map Map

  • hashmap HashMap

  • list List

    总结就是:

    ​ - 如果想使用基本类型,就在基本类型前加下划线 _

    ​ - 如果使用包装类,就使用小写的基本类型

g)settings:设置

​ mybatis 的设置,该设置会直接影响 mybatis 的运行时行为,需记住以下几个即可:

<settings>
	<setting name="cacheEnabled" value="true"/>
    <setting name="lazyLoadingEnabled" value="true"/>
    <setting name="logImpl" value="LOG4J"/>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

​ cacheEnabled:是否开启映射器配置文件中已配置的缓存

​ lazyLoadingEnabled:延迟加载的全局开关

​ logImpl:指定 MyBatis 所用日志的具体实现,未指定时将自动查找,其值有:SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING

  • LOG4J(需引入 jar 包)
  • STDOUT_LOGGING(不需要配置任何东西就可以使用)

​ mapUnderscoreToCamelCase:是否开启驼峰命名自动映射,即从经典数据库列名 user_name 映射到经典 Java 属性名 userName

h)其它配置

​ plugins:插件

​ 常用插件:

	- mybatis-generator-core
	- mybatis-plus
	- 通用 mapper
五、生命周期和作用域

生命周期和作用域极其重要,因为错误的使用会导致很严重的并发问题

SqlSessionFactoryBuilder:

  • 一旦创建就不需要了,所以最佳作用域是方法作用域(局部方法变量)
  • 可以使用它创建多个 SqlSessionFactory

SqlSessionFactory:

  • 最佳作用域是整个应用的的作用域,即 applicationScope
  • 使用单例模式
  • 应用存活期间,只保留一份即可

SqlSession:

  • 每个线程都应该有自己的 SqlSession
  • 不是线程安全的,所以不能被共享,否则会有并发问题
  • 最好放到每个方法中,用完即关闭
  • 关闭操作最好是放到 finally 块中,以保证数据库资源能被正确的关闭
六、ResultMap结果集映射

​ 将数据库中的字段与实体类属性映射起来

<resultMap id="userResultMap" type="user">
    <id property="id" column="id"></id>
    <result property="userAge" column="age"/>
    <result property="userName" column="name"/>
    <result property="userAddress" column="address"/>
</resultMap>

<select id="findById" resultMap="userResultMap" parameterType="int">
    select * from mybatisdemo1 where id = #{id}
</select>

id:可自定义,需要与 select 标签中的一致

type:实体类,可用别名代替

property:实体类中的属性名

column:数据库中的字段名

需注意:

  • resultMap 标签中的 id 标签,必须与数据库中的主键字段一致,否则报错
  • resultMap 可以代替 resultType,写上 resultMap 后,就无需在写 resultType 了
七、Log4j简单使用
1、导入依赖
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
2、mybatis 核心配置文件
<settings>
    <setting name="logImpl" value="LOG4J"/>
</settings>
3、log4j 配置文件
#设置日志级别,以及输出位置
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/mybatis.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
4、基本使用
// 创建日志对象,导的包是 log4j
Logger logger = Logger.getLogger(UserTest.class);
// 输出信息
logger.info("[INFO]:进入了 INFO 信息");
logger.debug("[DEBUG]:进入了 DEBUG 信息");
logger.error("[ERROR]:进入了 ERROR 信息");
八、分页
九、多对一查询

两种方式:

  1. 连接查询方式(推荐)
<select id="getStudents" resultMap="StudentsTeachers">
    select 
    	s.id sid, s.name sname, t.name tname 
    from 
    	student s 
    right join 
    	teacher t 
    on 
    	s.tid = t.id;
</select>
<resultMap id="StudentsTeachers" type="Students">
    <id property="id" column="sid"/>
    <result property="name" column="sname"/>
    <association property="teachers" javaType="Teachers">
        <result property="name" column="tname"/>
    </association>
</resultMap>
  1. 子查询(嵌套查询)方式
<select id="getStudents1" resultMap="StudentsTeachers1">
    select * from student;
</select>

<resultMap id="StudentsTeachers1" type="Students">
    <association property="teachers" column="tid" javaType="Teachers" select="getTeachers"/>
</resultMap>

<select id="getTeachers" resultType="Teachers">
    select * from teacher where id=#{tid};
</select>

注意点:

  • 多对一查询,使用 association 标签关联实体类中的对象
  • javaType 是实体类中对象的 java 类型
  • 如果使用了别名,需要让实体类中的类型和别名映射起来,别名是数据库层面的
  • 如果使用嵌套查询方式,#{tid} 中的 tid 可以随便写变量,mybatis 会自动与数据库中的 id 映射起来
  • 使用嵌套查询方式,SQL 中必须写上 where 条件,否则报结果集过多的错,相当于是两个表的关联条件
十、一对多查询
<select id="getTeachers" resultMap="TeacherStudent">
    select t.id tid, t.name tname, s.id sid, s.name sname from teacher t left join student s on t.id=s.tid where t.id=${tid}
</select>

<resultMap id="TeacherStudent" type="teacher">
    <id property="id" column="tid"/>
    <result property="name" column="sname"/>
    <collection property="students" ofType="student" javaType="ArrayList">
        <id property="id" column="sid"/>
        <result property="name" column="sname"/>
    </collection>
</resultMap>
public void getTeachers(){
    try(SqlSession sqlSession = MybatisUtils.getSqlSession();) {
        // 两种方式实现查询
        // ITeachersMapper mapper = sqlSession.getMapper(ITeachersMapper.class);
        // Teachers teachers = mapper.getTeachers(1);
        // System.out.println(teachers);
        val students = sqlSession.selectOne("com.nariit.mybatisdemo.mapper.ITeachersMapper.getTeachers", 1);
        System.out.println(students);
    }
 }

resultMap属性解释:

  • type:实体类的别名,或者全限定名称
  • collection:一对多的表嵌套方式
  • property:需要映射的对象属性名
  • ofType:范型的类型
  • javaType:复杂属性的类型
十一、动态SQL

if:

<select id="selectBlogIf" parameterType="map" resultType="BlogPojo">
    select * from blog
    <where>
        <if test="title != null">
            title like #{title}
        </if>
        <if test="author != null">
            and author = #{author}
        </if>
        <if test="views != null">
            and views > #{views}
        </if>
    </where>
</select>

java:

public void SelectBlogIf(){
        try (SqlSession sqlSession = MybatisUtils.getSqlSession();){
            IBlogMapper mapper = sqlSession.getMapper(IBlogMapper.class);
            HashMap map = new HashMap();
            map.put("title","%spring%");
            map.put("views",9000);
            List<BlogPojo> blogPojo = mapper.selectBlogIf(map);
            for (BlogPojo pojo : blogPojo) {
                System.out.println(pojo);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

choose、when:

<select id="selectBlogChoose" resultType="BlogPojo" parameterType="map">
    select * from blog
    <where>
        <choose>
            <when test="title != null">
                title like #{title}
            </when>
            <when test="author != null">
                and author = #{author}
            </when>
            <otherwise>
                and views > #{views}
            </otherwise>
        </choose>
    </where>
</select>

java:

public void SelectBlogChoose(){
        try (SqlSession sqlSession = MybatisUtils.getSqlSession();){
            IBlogMapper mapper = sqlSession.getMapper(IBlogMapper.class);
            HashMap map = new HashMap();
            //map.put("title","%spring%");
            map.put("author","很简单1");
            map.put("views",2000);
            List<BlogPojo> blogPojos = mapper.selectBlogChoose(map);
            for (BlogPojo blogPojo : blogPojos) {
                System.out.println(blogPojo);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

set:

<update id="updateBlogSet" parameterType="map">
    update blog
    <set>
        <if test="title != null">
            title = #{title},
        </if>
        <if test="author != null">
            author = #{author}
        </if>
    </set>
    <where>
        id = #{id}
    </where>
</update>

java:

public void UpdateBlogSet(){
        try (SqlSession sqlSession = MybatisUtils.getSqlSession();){
            IBlogMapper mapper = sqlSession.getMapper(IBlogMapper.class);
            HashMap map = new HashMap();
            map.put("title","spring不应该这样学");
            map.put("author","不简单");
            map.put("id","baa23393d6c44c7e8e1dd233e08b84a5");
            mapper.updateBlogSet(map);
            sqlSession.commit();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

foreach:

<select id="queryBlogForeach" parameterType="map" resultType="BlogPojo">
    select * from blog
    <where>
        id in
        <foreach collection="ids" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </where>
</select>

java:

public void QueryBlogForeach(){
        try (SqlSession sqlSession = MybatisUtils.getSqlSession();){
            IBlogMapper mapper = sqlSession.getMapper(IBlogMapper.class);
            HashMap map = new HashMap();
            List list = new ArrayList();
            list.add(1);
            list.add(2);
            list.add(3);
            map.put("ids",list);
            List<BlogPojo> blogPojos = mapper.queryBlogForeach(map);
            for (BlogPojo blogPojo : blogPojos) {
                System.out.println(blogPojo);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

注意点:

  • collection 里的值需与 java 里的 map 值对应
十二、缓存机制
1、一级缓存:

SqlSession 级别的缓存,即只在 SqlSession 有效期的缓存,当 SqlSession 对象关闭或被释放,缓存就会失效

mybatis 默认是开启一级缓存的。

2、二级缓存:

NameSpace 级别的缓存,就是每个 mapper.xml 的作用域

当 SqlSession 对象被关闭或释放,即一级缓存失效,如果此时开启了二级缓存,mybatis 就会把数据放到二级缓存中。

优先级:

​ 当用户查询数据时,mybatis 会优先读取二级缓存中的数据,如果二级缓存中没有想要的数据,会去一级缓存中查找,如果一级缓存中还没有该数据,才会去连接数据库查询。

开启二级缓存:

​ 只用在 mapper.xml 文件最前面添加 标签即可

<mapper namespace="com.nariit.mybatisdemo.mapper.IBlogMapper">
    <!-- 开启二级缓存 -->
    <cache/>
    
    <insert id="addBlog" parameterType="BlogPojo">
        insert into blog (id, title, author, create_time, views) values (#{id}, #{title}, #{author}, #{createTime}, #{views})
    </insert>
    
    <select id="selectBlogIf" parameterType="map" resultType="BlogPojo">
        select * from blog
        <where>
            <if test="title != null">
                title like #{title}
            </if>
            <if test="author != null">
                and author = #{author}
            </if>
            <if test="views != null">
                and views > #{views}
            </if>
        </where>
    </select>
</mapper>

也可以自定义一些二级缓存的参数:

<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。

可用的清除策略有:

LRU – 最近最少使用:移除最长时间不被使用的对象。
FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。
默认的清除策略是 LRU。

或者使用自定义的缓存:

<cache type="com.domain.something.MyCustomCache"/>

一般的自定义的缓存:

Ehcache、memcache

使用第三方的缓存,需要 maven 导入 jar 包。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

很简单_

点个赞在走呗 ~~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值