Mybatis学习总结

1、第一个Mybatis程序

思路:搭建环境->导入Mybatis->编写代码->测试

1.1搭建环境

搭建数据库

create database `Mybatis`;
use `mybatis`;

create table `user`(
id int not null,
name varchar(30) default null,
pwd varchar(30) default null,
primary key(`id`)
)  ENGINE=INNODB default CHARSET=utf8;

insert into `user`(`id`, `name`, `pwd`)
values(1, 'qwer', '123456'),
(2, 'asdf', '123456'),
(3, 'zxcv', '123456');

新建项目

  •   1.新建一个普通的maven项目
  •   2.删除src目录
  •   3.导入maven依赖

        
            mysql
            mysql-connector-java
            5.1.46
        
        
            org.mybatis
            mybatis
            3.5.2
        
        
            junit
            junit
            4.12
        
    

1.2创建一个模块

  • 编写mybatis 核心文件




    
  
        
            
            
                
                
                
                
            
        
    

  • 编写mybatis 工具类
public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;
    static{//初始加载
        try {
            //获取SqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //有了 SqlSessionFactory,可以从中获得 SqlSession 的实例。
    // SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。openSession
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
 }

1.3 编写代码

  • 实现类
public class User {
    private int id;
    private String name;
    private String pwd;
    public User() {
    }
    public User(int id, String name, String pwd) {

        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
}
  • dao接口
public interface UserDao {
    List getUserList();
}
  • 接口实现 由DaoImpl转换为了Mapper




    

1.4测试

Junit测试

public class UserDemoTest {
    @Test
    public void test(){
        //获得sqlsession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //执行sql
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        List userList = userDao.getUserList();
        for (User user :userList) {
            System.out.println(user);
        }
        //关闭sqlsession
        sqlSession.close();

    }
}

注意点:
错误一:org.apache.ibatis.binding.BindingException: Type interface com.beibei.dao.UserDao is not known to the MapperRegistry.
MapperRegistry是什么?
解决方法:mybatis配置文件中添加


    
        
    

错误二:
java.lang.ExceptionInInitializerError
Could not find resource com.beibei.dao.UserMapper.xml
解决方法:内部pom.xml添加


    
        
            
                src/main/resources
                
                    **/*.properties
                    **/*.xml
                
                true
            
            
                src/main/java
                
                    **/*.properties
                    **/*.xml
                
                true
            
        
    

生命周期和作用域

SqlSessionFactoryBuilder->sqlSessionFactory->SqlSession
SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量):不占用过多资源
SqlSessionFactory 最佳作用域是应用作用域:等同于连接池过多创建影响性能,单例模式
SqlSession 实例不是线程安全的,将 SqlSession 放在一个和 HTTP 请求相似的作用域中,每次收到 HTTP 请求,就可以打开一个SqlSession,返回一个响应后,就关闭它。sqlSession.close();

2. CRUD

  1.namespace

namespace中的包名要和Dao/mapper接口的包名保持一致。

  2.select/insert/update/delete

选择,查询语句:

  • id:对应namespace方法名;
  • resultType:Sql语句执行返回值!
  • parameterType:参数类型

1.编写接口

public interface UserDao {
    List getUserList();
    User getUserByID(int id);
    int addUser(User user);
    int updateUser(User user);
    int deleteUser(int id);
}

2.编写mapper中的sql语句



    
    
    
        insert into mybatis.user(id, name, pwd) values (#{id}, #{name}, #{pwd});
    

    
        update mybatis.user
        set name=#{name},
            pwd=#{pwd}
        where id=#{id};
    

    
        delete from mybatis.user where id = #{id}
    

3.测试 ==注意事务的提交==

@Test
    public void testSelectbyID(){
        //获得sqlsession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //执行sql
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        User user = userDao.getUserByID(1);
            System.out.println(user);
        //关闭sqlsession
        sqlSession.close();
    }

    @Test
    public void testAddUser(){
        //获得sqlsession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //执行sql
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        int res = userDao.addUser(new User(4, "hanhan", "123456"));
        System.out.println(res);
        //提交事务
        sqlSession.commit();
        //关闭sqlsession
        sqlSession.close();

    }

    @Test
    public void testUpdateUser(){
        //获得sqlsession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //执行sql
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        int res = userDao.updateUser(new User(4, "hehe", "123123"));
        System.out.println(res);
        //提交事务
        sqlSession.commit();
        //关闭sqlsession
        sqlSession.close();

    }
    @Test
    public void testDeleteUser(){
        //获得sqlsession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //执行sql
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        int res = userDao.deleteUser(4);
        System.out.println(res);
        //提交事务
        sqlSession.commit();
        //关闭sqlsession
        sqlSession.close();
    }

4.Map妙用

对于字段过多的情况,由于pojo对象的构造方法难以分属性创建构造方法,在全属性构造方法下就必须传所有参数,可以使用Map规避这个问题,只需传指定参数即可。

dao:

int updateUserByMap(Map map);

daomapper:


        update mybatis.user
        set name=#{username}
        where id=#{id};
    

test:

@Test
    public void testUpdateUserByMap(){
        //获得sqlsession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao User = sqlSession.getMapper(UserDao.class);
        Map map = new HashMap();
        map.put("id", 4);
        map.put("username", "meng");
        int i = User.updateUserByMap(map);
        System.out.println(i);
        sqlSession.commit();
        sqlSession.close();
    }

5.模糊查询

1.Java代码执行的时候,传递通配符%%

List userlist = mapper.getUserLike("%李%");

2.在sql中拼接使用通配符

select * from mybatis.user where name like "%"#{value}"%";

3.配置解析

1.核心配置文件

mybatis-config.xml

properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
    environment(环境变量)
        transactionManager(事务管理器)
        dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
  • environments(环境配置)
    尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。

  
    
      
    
    
      
      
      
      
    
  

  1. 默认使用的环境 ID(比如:default="development")。
  2. 每个 environment 元素定义的环境 ID(比如:id="development")。
  3. 事务管理器的配置(比如:type="JDBC")。
    • 存在JDBC和MANAGED 两者,MANAGED一般不用
  4. 数据源的配置(比如:type="POOLED")
    • UNPOOLED 无连接池,性能依赖于数据库
    • POOLED 存在连接池,减少连接响应时间,可进一步配置
    • JNDI EJB 或应用服务器这类容器中使用

2.properties(属性)

通过properties来实现配置文件引用
编写db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/Mybatis?useSSL=true&useUnicode=true&charterEncoding=UTF-8
username=root
password=root123

mybatis-config.xml中进行引用


3.类型别名(typeAliases)

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。


  
  
  
  
  
  

若有注解,则别名为其注解值。

@Alias("author")
public class Author {
    ...
}

4.settings(设置)

核心配置:
cacheEnabled:全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。默认true
lazyLoadingEnabled: 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。默认false
logImpl:指定 MyBatis 所用日志的具体实现,未指定时将自动查找。
完整的配置元素:


  
  
  
  
  
  
  
  
  
  
  
  
  
  
  

5.其他配置,基本使用不到

  • 类型处理器(typeHandlers)
  • objectFactory(对象工厂)
  • plugins(插件)

6.其他配置,基本使用不到

MapperRegistry:注册绑定Mapper文件
方式一:


    
        
    

方式二:使用class文件绑定注册


        
    

注意点:
接口和Mapper.xml文件名称必须一致
接口和Mapper.xml文件必须在一个包下

方式三:通过包引入


        
 

注意点:
接口和Mapper.xml文件名称必须一致
接口和Mapper.xml文件必须在一个包下

7.ResultMap结果映射集

当pojo对象与数据库对象字段名称不相同时,无法正确查询结果,此时需要使用ResultMap 进行映射


        
        
        

    

不进行resultType返回,使用resultMap进行对象返回
property是数据库字段名
column是pojo属性

4.日志

如果数据库操作出现异常,需要通过日志进行更方便的排错
在mybatis-config.xml中存在settings进行日志配置
logImpl 指定 MyBatis所用日志的具体实现,未指定时将自动查找。
核心2种,STDOUT_LOGGING 和常用的 LOG4J

4.1日志工厂

STDOUT_LOGGING标准的日志工厂实现,无需添加外部包,配置好可直接使用
配置项:


    
    
        
    

输出结果:

Opening JDBC Connection
Created connection 156545103.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@954b04f]
==>  Preparing: select * from mybatis.user where id = ?; 
==> Parameters: 1(Integer)
<==    Columns: id, name, pwd
<==        Row: 1, qwer, 123456
<==      Total: 1
User{id=1, name='qwer', password='123456'}
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@954b04f]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@954b04f]
Returned connection 156545103 to pool.

4.2log4j

优点:

  • 可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码
  • 日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等
  1. 导入log4j

            log4j
            log4j
            1.2.17

  1. resources下编写log4j.properties
    当前配置为输出到文件和控制台
### 配置根 ###
#日志信息输出到console和file下
log4j.rootLogger = debug,console,file

### 设置输出sql的级别,其中logger后面的内容全部为jar包中所包含的包名 ###
log4j.logger.org.apache=dubug
log4j.logger.java.sql.Connection=dubug
log4j.logger.java.sql.Statement=dubug
log4j.logger.java.sql.PreparedStatement=dubug
log4j.logger.java.sql.ResultSet=dubug

### 配置输出到控制台 ###
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern =  %d{ABSOLUTE} %5p %c{1}:%L - %m%n

### 配置输出到文件 ###
log4j.appender.file = org.apache.log4j.FileAppender
log4j.appender.file.File = logs/log.log
log4j.appender.file.Append = true
log4j.appender.file.Threshold = DEBUG
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

3.配置log4j为mybatis日志实现


    
        
    

4.测试运行

19:31:52,373 DEBUG LogFactory:105 - Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
19:31:52,376 DEBUG LogFactory:105 - Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
19:31:52,414 DEBUG PooledDataSource:353 - PooledDataSource forcefully closed/removed all connections.
19:31:52,414 DEBUG PooledDataSource:353 - PooledDataSource forcefully closed/removed all connections.
19:31:52,415 DEBUG PooledDataSource:353 - PooledDataSource forcefully closed/removed all connections.
19:31:52,415 DEBUG PooledDataSource:353 - PooledDataSource forcefully closed/removed all connections.
19:31:52,563 DEBUG JdbcTransaction:136 - Opening JDBC Connection
19:31:52,868 DEBUG PooledDataSource:424 - Created connection 793315160.
19:31:52,868 DEBUG JdbcTransaction:100 - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@2f490758]
19:31:52,875 DEBUG getUserList:143 - ==>  Preparing: select * from mybatis.user; 
19:31:52,920 DEBUG getUserList:143 - ==> Parameters: 
19:31:52,952 DEBUG getUserList:143 - <==      Total: 4
User{id=1, name='qwer', password='123456'}
User{id=2, name='asdf', password='123456'}
User{id=3, name='zxcv', password='123456'}
User{id=4, name='meng', password='123123'}
19:31:52,955 DEBUG JdbcTransaction:122 - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@2f490758]
19:31:52,961 DEBUG JdbcTransaction:90 - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@2f490758]
19:31:52,961 DEBUG PooledDataSource:381 - Returned connection 793315160 to pool.

5.log4j项目使用
使用类中引入
import org.apache.log4j.Logger;
具体测试使用

static Logger logger = Logger.getLogger(UserDemoTest.class);
    @Test
    public void  testLog4j(){
        logger.info("info: testLog4j");
        logger.debug("debug: testLog4j");
        logger.error("error: testLog4j");
    }

可以在输出文件logs.log看差异

[ INFO ] - 2020-08-30 19:46:07 info: testLog4j
[ DEBUG ] - 2020-08-30 19:46:07 debug: testLog4j
[ ERROR ] - 2020-08-30 19:46:07 error: testLog4j

5.分页实现

为什么需要分页

  • 减少数据处理量

5.1 limit 分页

limit语法:

mysql> SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15
//为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1: 
mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.
//如果只给定一个参数,它表示返回最大的记录行数目: 
mysql> SELECT * FROM table LIMIT 5; //检索前 5 个记录行
//换句话说,LIMIT n 等价于 LIMIT 0,n。

测试:
创建接口:

List getUserListByLimit(Map map);

mapper:


    
    
    



测试调用:

@Test
    public void testSelectByLimit(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao userdao = sqlSession.getMapper(UserDao.class);
        Map map = new HashMap();
        map.put("startIndex", 0);
        map.put("pageSize", 2);

        List userList = userdao.getUserListByLimit(map);
        for (User user:userList) {
            System.out.println(user);
        }
        sqlSession.close();
    }

5.2.RowBounds 分页

不再使用sql实现分页,通过mybatis官方方法实现(不推荐)

接口:

List getUserListByRowBounds();

mapper.xml

   

测试脚本
@Test
public void testSelectByRowBounds(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
RowBounds rowBounds = new RowBounds(1,2 );
List userList = sqlSession.selectList("com.beibei.dao.UserDao.getUserListByRowBounds", null, rowBounds);
for (User user: userList) {
System.out.println(user);
}
sqlSession.close();
}

5.3 其他插件方式

Mysql分页处理(PageHelper)

6 使用注解开发

**面向接口编程 **

  • 解耦
  • 定义(规范,约束)与实现(名实分离的原则)的分离。
  • 接口的本身反映了系统设计人员对系统的抽象理解

6.1使用注解开发

1.注解在接口上实现

    @Select("select * from mybatis.user")
    List getUsers();

2.需要在核心配置中绑定接口



    

3.测试

@Test
public void test(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserDao mapper = sqlSession.getMapper(UserDao.class);
    List userList = mapper.getUsers();
    for (User user: userList ) {
        System.out.println(user);
    }
    sqlSession.close();
    
}

本质:反射来获取注解信息实现
底层:动态代理

6.2 注解开发CRUD
6.2.1 自动提交事务

public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession(true);//自动提交事务
    }

6.2.2 编写接口

@Insert("insert into mybatis.user(id, name, pwd) values(#{id}, #{name}, #{pwd})")
int addUser(@Param("id") int id, @Param("name") String name, @Param("pwd") String password);

@Update("update mybatis.user set name=#{name} where id = #{id}")
int updateUser(@Param("id") int id,  @Param("name") String name);

6.2.3 增加测试类

@Test
public void testAddUser(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserDao mapper = sqlSession.getMapper(UserDao.class);
    int i = mapper.addUser(5, "qwer", "123321");
    System.out.println(i);
}

@Test
public void testUpdateUser(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserDao mapper = sqlSession.getMapper(UserDao.class);
    int i = mapper.updateUser(5, "asdf");
    System.out.println(i);
}

6.3 #{} 和${} 区别

{}是预编译处理,对应JBDC中的PreparedStatement,可以防止依赖注入。

${}是字符串替换。不能防止依赖注入

7.Lombok

不用再getter setter 构造 toString ,注解即可完成
1.idea安装插件
2.导入依赖


    org.projectlombok
    lombok
    1.18.12
    provided

3.使用:

@ToString
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class User {
    private int id;
    private String name;
    private int age;
    private String birth;
    private Date birthday;
}

@Data:生成无参 get set toString equeals hashcode
@AllArgsConstructor:生成全参
@NoArgsConstructor:生成无参

7 复杂查询

7.1环境搭建

1.导入lombok
2.新建实体类Teacher、Student
3.建立Mapper接口
4.建立Mapper.xml文件
5.核心配置文件中绑定注册的Mapper接口或文件
6.测试查询是否成功

7.2 多对一,多表查询

方式一:按照查询嵌套处理
核心mapper配置如下




    
    
    
    



方式二:按结果嵌套查询




    
    
    
    
        
    

7.3 一对多,集合查询




    
    
    
    
        
        
        
    

8 动态sql

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

数据库搭建

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 '浏览量',
primary key(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;

pojo对象

@Data
public class Blog {
    private String id;
    private String title;
    private String author;
    private Date createTime;
    private int views;
}

if判断动态语句

mapper


    insert into mybatis.blog(id, title, author, create_time, views)
    values (#{id}, #{title}, #{author}, #{createTime}, #{views});



测试

@org.junit.Test
public void testAddBlog(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    Blog blog = new Blog();
    blog.setAuthor("QWER");
    blog.setCreateTime(new Date());
    blog.setTitle("QWEQWRT");
    blog.setViews(6213);
    blog.setId(IDutils.getIdrandom());
    int i = mapper.addBlog(blog);
    System.out.println(i);
    sqlSession.commit();
    sqlSession.close();
}
@org.junit.Test
public void testQueryBlogIF(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    Map map = new HashMap();
    map.put("author","QWER");
    List blogs = mapper.queryBlogIF(map);
    for (Blog blog : blogs) {
        System.out.println(blog.toString());
    }
 //   sqlSession.commit();
    sqlSession.close();
}

choose(when otherwise)选择动态语句

和java的switch效果相同
mapper:


test:

@org.junit.Test
public void testQueryBlogChoose(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();

    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    Map map = new HashMap();
    map.put("author","QWER");
    map.put("title", "QWEQWRT");
    List blogs = mapper.queryBlogIF(map);
    for (Blog blog : blogs) {
        System.out.println(blog.toString());
    }
    //   sqlSession.commit();
    sqlSession.close();
}

trim (where, set)

where 是取消where 1=1 使用的,update中可能使用
trim 则是优化多于的and or ,等元素的
==set== 有使用的必要,优化update中可能存在的多于","
进行set相关的测试


    update mybatis.blog
    
        author = #{author},
        
        views = views+1000,
    
    where 1= 1 and author = "pgm"

测试:

@org.junit.Test
public void testUpdateBlogSet(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();

    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    Map map = new HashMap();
    map.put("author","darmon");
    map.put("title", "QWEQWRT");
    int i= mapper.updateBlogSet(map);
        System.out.println(i);
      sqlSession.commit();
    sqlSession.close();
}

foreach 集合类条件动态语句

你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号item 的值是本次迭代获取到的元素。==当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值==
mapper


测试用例

@org.junit.Test
public void testQueryBlogIn(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    Map map = new HashMap();
    ArrayList authors = new ArrayList();
    authors.add("pgm");
    authors.add("darmon");
    map.put("authors",authors);
    List blogs = mapper.queryBlogIn(map);
    for (Blog blog : blogs) {
        System.out.println(blog.toString());
    }
    sqlSession.commit();
    sqlSession.close();
}

9.缓存机制

为了提升查询效率,引入了缓存机制
mybatis缓存共定义了2级缓存

一级缓存(本地缓存):
  • 默认情况开启
  • 作用于Sqlsession级别(sqlsession.close关闭便关闭)
  • 修改数据后缓存失效(全刷新,失效)
  • sqlsession.clearCache();//清理缓存
二级缓存:
  • namespace级别缓存(又叫mapper级别,任意访问mapper.xml的文件都能使用)
  • 主配置文件中必须开启缓存设置(默认开启)

  • 在mapper.xml中添加既开启二级缓存
  • 缓存设置(FIFO 缓存(先进先出),每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的)
  • 默认使用LRU算法机制(最近最少使用)
 
  • 缓存策略包含
LRU – 最近最少使用:移除最长时间不被使用的对象。
FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象

存在多级缓存时,查询调用顺序是== 优先二级缓存 ==,==其次一级缓存==,==最后查数据库==
Mybatis执行流程

你可能感兴趣的:(Mybatis学习总结)