MyBatis学习笔记

前言:
学习B站UP主狂神说[MyBatis]视频笔记整理
B站链接

简介

MyBatis 是一款优秀的 持久层框架,它支持自定义 SQL、存储过程以及高级映射。
MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
MyBatis学习笔记_第1张图片
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到 Github

获得MyBatis

  1. Mavenc仓库:

<dependency>
    <groupId>org.mybatisgroupId>
    <artifactId>mybatisartifactId>
    <version>3.4.6version>
dependency>
  1. GitHub: https://github.com/mybatis/mybatis-3

  2. 中文文档:https://mybatis.org/mybatis-3/zh/index.html

持久化

  1. 数据持久化就是将程序的数据在持久状态和瞬时状态转化的过程
  2. 内存:断电即失
  3. 持久化方式:数据库(JDBC),IO文件持久化

持久层

Dao层,service层,controller层

  1. 层是界限明显的
  2. 完成持久化工作的代码块

MyBatis优点

  1. 简化传统的JDBC代码,实现自动化
  2. 帮助程序员将数据存入数据库
  3. SQL与代码分离
  4. 简单易学,灵活
  5. 提供映射标签,支持对象与数据库ORM映射

使用MyBatis

搭建数据库


-- 创建数据库
CREATE DATABASE `mybatis`;

--如果存在则删除
DROP TABLE IF EXISTS `user`;

-- 创建数据库
CREATE TABLE `user`(
   `id` int(20) NOT null PRIMARY KEY,
	 `name` varchar(30) DEFAULT null,
	 `pwd` VARCHAR(30) DEFAULT null
)ENGINE=INNODB DEFAULT charset=utf8;

-- 插入数据
insert  into `user`(`id`,`name`,`pwd`) values (1,'狂神','123456'),(2,'张三','abcdef'),(3,'李四','987654');

创建项目

创建普通Maven项目
MyBatis学习笔记_第2张图片
MyBatis学习笔记_第3张图片
删除src目录,使项目充当父工程
MyBatis学习笔记_第4张图片

导入依赖

MyBatis学习笔记_第5张图片


<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    
    <modelVersion>4.0.0modelVersion>
    <groupId>cn.tonygroupId>
    <artifactId>TestMybatisartifactId>
    <packaging>pompackaging>
    <version>1.0-SNAPSHOTversion>


    
    <dependencies>
        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>8.0.17version>
        dependency>
        
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatisartifactId>
            <version>3.4.6version>
        dependency>
        
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.12version>
        dependency>
        
        
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>1.18.12version>
            <scope>providedscope>
        dependency>
    dependencies>



    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-surefire-pluginartifactId>
                <version>2.18.1version>
                <configuration>
                    <skipTests>trueskipTests>
                configuration>
            plugin>
        plugins>
    build>
project>

创建子级项目
MyBatis学习笔记_第6张图片
MyBatis学习笔记_第7张图片

编写代码

编写核心配置文件

参考官方文档,创建mybatis-config.xml配置文件
MyBatis学习笔记_第8张图片
MyBatis学习笔记_第9张图片



<configuration>
    <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 resource="org/mybatis/example/BlogMapper.xml"/>
    mappers>
configuration>

核心配置文件详解





<configuration>
    
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=true"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            dataSource>
        environment>
    environments>
    
configuration>

编写Mybatis工具类

阅读官方文档

MyBatis学习笔记_第10张图片
SqlSessionFactory中获取到SqlSession,就可以执行其中的SQL语句
SqlSession相当于JDBC中的statement
MyBatis学习笔记_第11张图片

编写工具类

创建目录,创建MybatisUtil工具类
MyBatis学习笔记_第12张图片

package cn.tony.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;

/**
 * Mybatis工具类
 * 获取SqlSessionFactory对象
 * @author Tu_Yooo
 * @Date 2021/3/9 10:40
 */
public class MybatisUtil {
     

    private static SqlSessionFactory sqlSessionFactory=null;

    //从官方文档取出的代码 获取SqlSessionFactory
    static{
     
        String resource = "mybatis-config.xml";
        InputStream inputStream = null;
        try {
     
            inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
     
            e.printStackTrace();
        }

    }

    /**
     * 获取SqlSession
     *
     * 既然有了 SqlSessionFactory,顾名思义,
     * 我们可以从中获得 SqlSession 的实例。SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。
     * 你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句
     * @return
     */
    public  static SqlSession getSqlSession(){
     
        return sqlSessionFactory.openSession();
    }

}

测试Mybatis

编写实体类

/**
 * User
 * @author Tu_Yooo
 * @Date 2021/3/9 10:56
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
     
    private int id;
    private String name;
    private String pwd;
}

编写Dao接口

MyBatis学习笔记_第13张图片

/**
 * Dao层接口
 * @author Tu_Yooo
 * @Date 2021/3/9 11:08
 */
public interface UserMapper {
     
    public List<User> getUserList();
}

从官方文档可以看出,MyBatis几乎避免了几乎所有JDBC代码,
由原来的UserMapperimpl变成xml文件

所以这里我们不用编写接口实现类,直接创建UserMapper.xml配置文件
在这里插入图片描述

编写Dao接口XML配置文件

查看官方文档

MyBatis学习笔记_第14张图片

编写与配置文件详解

MyBatis学习笔记_第15张图片





<mapper namespace="cn.tony.dao.mapper.UserMapper">

    
    <select id="getUserList" resultType="cn.tony.pojo.User">
     select * from user
    select>

mapper>

MyBatis学习笔记_第16张图片

编写Test测试文件

编写Junit测试文件 测试UserMapper

/**
 * 测试UserMapper
 * @author Tu_Yooo
 * @Date 2021/3/9 11:31
 */
public class UserMapperTest {
     

    @Test
    public void testUser(){
     
        //获取sqlSession
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        //指向SQL
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> list = mapper.getUserList();
        for (User user: list) {
     
            System.out.println(user);
        }
        //关闭SqlSession
        sqlSession.close();
    }
}

1.通过编写的工具类,获取sqlSession
2.通过sqlSession获取UserMapper接口实例
3.执行方法获取结果

测试运行发现报错了!:
org.apache.ibatis.binding.BindingException: Type interface cn.tony.dao.mapper.UserMapper is not known to the MapperRegistry.
MyBatis学习笔记_第17张图片
原因是核心配置文件中缺少指向UserMapper.xml的配置
MyBatis学习笔记_第18张图片
继续运行发现还是报错了!
Error building SqlSession.
The error may exist in resources/UserMapper.xml
Caused by: java.io.IOException: Could not find resource resources/UserMapper.xml
MyBatis学习笔记_第19张图片
这是Maven过滤的问题的原因 无法导出配置文件
MyBatis学习笔记_第20张图片
解决:在pom.xml文件中加入以下配置

 <build>
        
        <resources>
            <resource>
                <directory>src/main/resourcesdirectory>
                <includes>
                    <include>**/*.propertiesinclude>
                    <include>**/*.xmlinclude>
                includes>
                <filtering>truefiltering>
            resource>
            <resource>
                <directory>src/main/javadirectory>
                <includes>
                    <include>**/*.propertiesinclude>
                    <include>**/*.xmlinclude>
                includes>
                <filtering>truefiltering>
            resource>
        resources>
    build>

再次测试运行:
MyBatis学习笔记_第21张图片
成功!

补充:SqlSession调用方式

参考官方文档会发现调用SqlSession执行SQL有两种方式
MyBatis学习笔记_第22张图片
官网推荐的是第二种,也就是我们刚刚使用的通过session.getMapper(BlogMapper.class);

方式一:

//获取sqlSession
SqlSession sqlSession = MybatisUtil.getSqlSession();
//指向SQL
UserMapper mapper = sqlSession.getMapper(UserMapper.class);

方式二:

 List<User> objects = sqlSession.selectList("cn.tony.dao.mapper.UserMaper.getList");

通过官网理解作用域与生命周期

作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题
MyBatis学习笔记_第23张图片

SqlSessionFactoryBuilder

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的 最佳作用域是方法作用域(也就是局部方法变量)。 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但最好还是不要一直保留着它,以保证所有的 XML 解析资源可以被释放给更重要的事情。

MyBatis学习笔记_第24张图片

SqlSessionFactory

可以把它想象成数据库连接池

SqlSessionFactory 一旦被创建就应该在应用的 运行期间一直存在,没有任何理由 丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏习惯”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是 使用单例模式或者静态单例模式。

SqlSession

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例 不是线程安全的,因此是 不能被共享的,所以它的最佳的作用域是 请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。 如果你现在正在使用一种 Web 框架,考虑将 SqlSession 放在一个和 HTTP 请求相似的作用域中。 换句话说,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 这个关闭操作很重要,为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中。 下面的示例就是一个确保 SqlSession 关闭的标准模式:

try (SqlSession session = sqlSessionFactory.openSession()) {
  // 你的应用逻辑代码
}

在所有代码中都遵循这种使用模式,可以保证所有数据库资源都能被正确地关闭。
MyBatis学习笔记_第25张图片

MyBatis执行流程

MyBatis学习笔记_第26张图片

小结

  1. namespace(命名空间)中的包名要与Mapper接口中一致
  2. select中id就是方法名,resultType是返回值类型

增删改查实现

CRUD

查询

1.在UserMapper接口中新增方法

//指定id查询
public User getUser(int id);

2.在UserMapper.xml中新增SQL映射

 <select id="getUser" resultType="cn.tony.pojo.User" parameterType="int">
        select * from user where id=#{id}
select>

其中parameterType是入参类型

3.编辑测试类

    @Test
    public void testgetUser(){
     
        //获取sqlSession
        SqlSession sqlSession = MybatisUtil.getSqlSession();

        
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

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

        //关闭SqlSession
        sqlSession.close();
    }

新增

1.在UserMapper接口中新增方法

//新增用户
public int insertUser(User user);

2.在UserMapper.xml中新增SQL映射


    <insert id="insertUser" parameterType="cn.tony.pojo.User" >
        insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
    insert>

3.编辑测试类

   @Test
    public void TestinsertUser(){
     
        //获取sqlSession
        SqlSession sqlSession = MybatisUtil.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        int i = mapper.insertUser(new User(4, "王根基", "123456"));
        System.out.println(i);

        //关闭SqlSession
        sqlSession.close();
    }

运行发现成功了
但是实际数据库并没有新增一行数据
MyBatis学习笔记_第27张图片
这是由于 增删改 必须要 提交事务

修改测试代码

   //增删改必须要提交事务
    @Test
    public void TestinsertUser(){
     
        //获取sqlSession
        SqlSession sqlSession = MybatisUtil.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        int i = mapper.insertUser(new User(4, "王根基", "123456"));
        System.out.println(i);
        //提交事务
        sqlSession.commit();
        //关闭SqlSession
        sqlSession.close();
    }

再次执行
MyBatis学习笔记_第28张图片
新增成功!

修改

1.在UserMapper接口中新增方法

 //修改用户
public int UpdateUser(User user);

2.在UserMapper.xml中新增SQL映射

 <update id="UpdateUser"  parameterType="cn.tony.pojo.User">
        update user set name=#{name},pwd=#{pwd} where id=#{id}
update>

3.编辑测试类

  @Test
    public void updateUser(){
     
        //获取sqlSession
        SqlSession sqlSession = MybatisUtil.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);


        int i = mapper.UpdateUser(new User(1, "郑在稿", "123456"));
        System.out.println(i);
        //提交事务
        sqlSession.commit();
        //关闭SqlSession
        sqlSession.close();
    }

删除

1.在UserMapper接口中新增方法

// 删除用户
public int deleteUser(int id);

2.在UserMapper.xml中新增SQL映射

  <delete id="deleteUser" parameterType="int">
        delete from user where id=#{id} ;
    delete>

3.编辑测试类

    @Test
    public void testdeleteUser(){
     
        //获取sqlSession
        SqlSession sqlSession = MybatisUtil.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        int i = mapper.deleteUser(2);
        System.out.println(i);
        //提交事务
        sqlSession.commit();
        //关闭SqlSession
        sqlSession.close();
    }

设置自动提交事务

每次都要手动提交事务,相对麻烦
查看SqlSessionFactory源码可知,其中openSession(),可以设置是否自动提交事务
MyBatis学习笔记_第29张图片
修改MybatisUtil工具类
MyBatis学习笔记_第30张图片

万能的Map

在实际工作中 如果实体类或数据库字段过多,使用对象User的入参方式,过于繁琐且每个字段必须得赋值

 <update id="UpdateUser"  parameterType="cn.tony.pojo.User">
        update user set name=#{name},pwd=#{pwd} where id=#{id}
update>

此时我们可以使用Map来做参数的传递:
1.在UserMapper接口中新增map修改方法

   //修改用户map
    public int updateMapUser(Map<String,Object> map);

2.在UserMapper.xml中新增SQL映射

 <update id="updateMapUser" parameterType="map">
        update user set name=#{nameMap} where id=#{idMap}
update>

#{}内的名字可以任意定义,只需要与map中的K保持一致即可

3.编辑测试类

 @Test
    public void testupdateMapUser(){
     
        //获取sqlSession
        SqlSession sqlSession = MybatisUtil.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        Map<String, Object> map = new HashMap<String, Object>();

        map.put("nameMap","郑爽");
        map.put("idMap",2);
        int i = mapper.updateMapUser(map);
        System.out.println(i);

        //提交事务
        sqlSession.commit();
        //关闭SqlSession
        sqlSession.close();
    }

map传递参数,直接在SQL中取Key即可
对象传递参数,直接取对象的属性即可
如果只有单个基本类型参数,parameterType可以不写

limit分页查询

分页查询的作用在于减少数据处理量

编写UserMapper接口

//分页查询
public List<User> limitgetUser(Map<String,Integer> map);

在UserMapper.xml中新增SQL映射

<select id="limitgetUser" parameterType="map" resultType="user">
        select * from user limit #{stateInt},#{pageInt}
select>

编写测试类

    @Test
    public void testlimitgetUser(){
     
        //获取sqlSession
        SqlSession sqlSession = MybatisUtil.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("stateInt",0);
        map.put("pageInt",2);
        List<User> list = mapper.limitgetUser(map);
        for (User user : list) {
     
            logger.info("查询结果:"+user);
        }

        //关闭SqlSession
        sqlSession.close();
    }

使用注解开发

阅读官方文档:
MyBatis学习笔记_第31张图片
对于一些简单的SQL,我们完全可以不用xml配置文件的方式来定义.可以使用注解来进行配置

编写接口

//使用注解开发
@Select("select * from user")
public List<User> getUserannation();

编写测试类

  @Test
    public void Testannotion(){
     
        //获取sqlSession
        SqlSession sqlSession = MybatisUtil.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        List<User> userList = mapper.getUserannation();
        for (User user : userList) {
     
            logger.info("查询结果:"+user);
        }
        //关闭SqlSession
        sqlSession.close();
    }

基于id查询用户

编写接口

 //传入多个参数 使用@Param注解
@Select("select * from where id = #{id}")
public User getUserannotionid(@Param("id") int id);

关于@Param

@Param注解用于给方法参数起一个名字。以下是总结的使用原则:

  1. 在方法只接受一个参数的情况下,可以不使用@Param。
  2. 在方法接受多个参数的情况下,建议一定要使用@Param注解给参数命名。
  3. 如果参数是 JavaBean , 则不能使用@Param。
  4. 不使用@Param注解时,参数只能有一个,并且是Javabean。

插入用户数据

编写接口

@Insert("insert into user (id,name,pwd) values (#{userid},#{name},#{password})")
public int insertUser2(User user);

核心配置文件详解

mybatis-config.xml
参考官方文档,需要重点掌握的是以下这几个属性
在这里插入图片描述

属性properties

我们可以通过properties 属性来引用配置文件
MyBatis学习笔记_第32张图片

创建properties配置文件

MyBatis学习笔记_第33张图片

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=123456

在核心配置文件中引入

参考官方文档:标签必须在 配置文件最上方 否则会报错
MyBatis学习笔记_第34张图片

MyBatis学习笔记_第35张图片





<configuration>
    
    <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 resource="UserMapper.xml"/>
    mappers>

configuration>

也可以在properties标签增加一些其他的属性

 
    <properties resource="db.properties">
        <property name="username" value="root"/>
        <property name="pwd" value="123456"/>
    properties>

如果标签与配置文件都指定了同一个字段,优先使用properties配置文件内的

设置settings

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等

常见使用以下配置

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

sttings标签在properties标签和typeAliases中间 位置固定

类型别名typeAliases

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

使用别名的方式

方式一

为每个类的全限定类名,取一个特点的名字
MyBatis学习笔记_第36张图片

方式二

也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean
在这里插入图片描述
扫描完包,默认会使用 Bean 的首字母小写的非限定类名来作为它的别名

若有注解,则别名为其注解值
MyBatis学习笔记_第37张图片

在核心配置文件中配置别名

<typeAliases>
        <typeAlias alias="user" type="cn.tony.pojo.User"/>
typeAliases>

MyBatis学习笔记_第38张图片
也可以才用第二种方式,直接扫描包路径

 <typeAliases>
        <package name="cn.tony.pojo"/>
typeAliases>

实体类比较少的时候,建议使用第一种方式

环境变量environments

MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中使用相同的 SQL 映射。还有许多类似的使用场景。

不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。

修改配置文件新增多套环境





<configuration>
    
    <environments default="test">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=true"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            dataSource>
        environment>
        
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=true"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            dataSource>
        environment>
    environments>


    
    <mappers>
        <mapper resource="UserMapper.xml"/>
    mappers>

configuration>

MyBatis学习笔记_第39张图片
通过default指定默认使用环境

事务管理器(transactionManager)

MyBatis学习笔记_第40张图片
在 MyBatis 中有两种类型的事务管理器(也就是 type="[JDBC|MANAGED]"):

JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接。然而一些容器并不希望连接被关闭,因此需要将 closeConnection 属性设置为 false 来阻止默认的关闭行为。

官网提示:
在这里插入图片描述

数据源(dataSource)

配置数据源来连接数据库
MyBatis学习笔记_第41张图片
dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。

有三种内建的数据源类型(也就是 type="[UNPOOLED|POOLED|JNDI]"):

UNPOOLED– 这个数据源的实现会 每次请求时打开和关闭连接。虽然有点慢, 但对那些数据库连接可用性要求不高的简单应用程序来说,是一个很好的选择。 性能表现则依赖于使用的数据库,对某些数据库来说,使用连接池并不重要,这个配置就很适合这种情形。

POOLED– 这种数据源的 实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这种处理方式很流行,能使并发 Web 应用快速响应请求。默认使用

JNDI – 这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的数据源引用。

映射器mappers

映射器是告诉 MyBatis 到哪里去找映射文件

MyBatis学习笔记_第42张图片
定义映射器有以下几种方式:

相对于类路径的资源引用 这种方式是官网推荐的
MyBatis学习笔记_第43张图片
使用class绑定注册
注意点:

  1. 接口和他的Mapper配置文件必须同名!
  2. 接口和他的Mapper配置文件必须在同一个包下!

MyBatis学习笔记_第44张图片
扫描指定包下的所有映射文件
注意点:

  1. 接口和他的Mapper配置文件必须同名!
  2. 接口和他的Mapper配置文件必须在同一个包下!

MyBatis学习笔记_第45张图片

ResultMap结果集映射

ResultMap是解决实体类与数据库字段名不一致,导致查询出来的结果无法正确赋值的问题

resultMap 元素是 MyBatis 中最重要最强大的元素

ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了

初识ResultMap

修改实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
     
    private int userid;
    private String name;
    private String password;
}

MyBatis学习笔记_第46张图片
此时与数据库字段名产生了严重的不一致问题

如果查询数据,那么实体类与数据库字段名不一致的字段必然无法正确赋值
MyBatis学习笔记_第47张图片
这个时候就需要使用resultMap来定义结果集映射

编写UserMapper.xml

MyBatis学习笔记_第48张图片

    
    <resultMap id="usermap" type="user">
        
        <result column="id" property="userid"/>
        <result column="name" property="name"/>
        <result column="pwd" property="password"/>
    resultMap>

    
    <select id="getUserList" resultMap="usermap">
     select * from user
    select>

如果此时你已经对resultMap 足够了解,那么有些实体类与数据库名字相同的字段,完全可以不用显示的定义出来

 
    <resultMap id="usermap" type="user">
        
        <result column="id" property="userid"/>
        
        <result column="pwd" property="password"/>
    resultMap>

如果这个世界总是这么简单就好了。

ResultMap进阶

MyBatis 创建时的一个思想是:数据库不可能永远是你所想或所需的那个样子。 我们希望每个数据库都具备良好的第三范式或 BCNF 范式,可惜它们并不都是那样。 如果能有一种数据库映射模式,完美适配所有的应用程序,那就太好了,但可惜也没有。 而 ResultMap 就是 MyBatis 对这个问题的答案。

MyBatis学习笔记_第49张图片

复杂查询环境搭建

多对一
MyBatis学习笔记_第50张图片

新建数据库表

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');

创建数据库实体类

学生类

/**
 * 学生类
 * @author Tu_Yooo
 * @Date 2021/3/12 16:00
 */
@Data
public class Student {
     

    private int id;
    private String name;
    //学生关联一个老师
    private Teacher teacher;
}

老师类

/**
 * 老师类
 * @author Tu_Yooo
 * @Date 2021/3/12 16:02
 */
@Data
public class Teacher {
     
    private int id;
    private String name;
}

创建接口

/**
 * 学生类
 * @author Tu_Yooo
 * @Date 2021/3/12 16:05
 */
public interface StudentMapper {
     
}
/**
 * 老师类接口
 * @author Tu_Yooo
 * @Date 2021/3/12 16:05
 */
public interface TeacherMapper {
     
}

创建Mapper.xml配置文件





<mapper namespace="cn.tony.dao.mapper.TeacherMapper">

mapper>




<mapper namespace="cn.tony.dao.mapper.StudentMapper">

mapper>

核心配置文件中添加映射

 
<mappers>
      <mapper resource="UserMapper.xml"/>
      <mapper resource="StudentMapper.xml"/>
      <mapper resource="TeacherMapper.xml"/>
mappers>

多对一的处理

需求:查询所有学生 以及对应的老师信息

编辑学生接口

/**
 * 学生类
 * @author Tu_Yooo
 * @Date 2021/3/12 16:05
 */
public interface StudentMapper {
     

    //查询所有学生 以及对应的老师信息
    public List<Student> selectStudent();
}

编写映射文件

按照查询嵌套处理–子查询




<mapper namespace="cn.tony.dao.mapper.StudentMapper">


    <resultMap id="studentmap" type="student">
        
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        
        <association property="teacher" column="tid" javaType="cn.tony.pojo.Teacher" select="selectTeacher"/>
           
    resultMap>

    
    <select id="selectStudent" resultMap="studentmap">
        select * from student
    select>
    
    <select id="selectTeacher" resultType="teacher">
        select * from teacher where id =#{id}
    select>

mapper>
按照结果嵌套处理–联表查询




<mapper namespace="cn.tony.dao.mapper.StudentMapper">


    <resultMap id="studentmap" type="student">
        
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        
        <association property="teacher" javaType="cn.tony.pojo.Teacher" >
            <result property="id" column="tid"/>
            <result property="name" column="tname"/>
        association>
           
    resultMap>

    
    <select id="selectStudent" resultMap="studentmap">
        select a.*,b.id as tid,b.name as tname from student a
        inner join teacher b on a.tid=b.id
    select>
    

mapper>

一对多的处理

修改实体类

/**
 * 老师类
 * @author Tu_Yooo
 * @Date 2021/3/12 16:02
 */
@Data
public class Teacher {
     
    private int id;
    private String name;
    private List<Student> student;
}
/**
 * 学生类
 * @author Tu_Yooo
 * @Date 2021/3/12 16:00
 */
@Data
public class Student {
     

    private int id;
    private String name;
    //学生关联一个老师
    private int pid;
}

需求:获取指定老师下的所有学生及老师的信息

编辑老师接口

/**
 * 老师类接口
 * @author Tu_Yooo
 * @Date 2021/3/12 16:05
 */
public interface TeacherMapper {
     

    //查询指定老师下的所有学生信息及老师信息
    public Teacher selectTeacher(@Param("tid") int id);
}

编写映射文件

按照结果嵌套处理–联表查询
?selectTeacherxml version="1.0" encoding="UTF-8" ?>



<mapper namespace="cn.tony.dao.mapper.TeacherMapper">

    <resultMap id="getTeacher" type="teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        
        <collection property="stud" ofType="Student" >
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
        collection>
    resultMap>

    <select id="selectTeacher" resultMap="getTeacher">
        select a.id as tid,a.name as tname,b.id as sid,b.name as sname from teacher a
        inner join student b on a.id=b.tid
        where a.id = #{tid}
    select>

mapper>

总结

1.如果实体类字段为对象选择-association
2.如果实体类字段为集合 使用-collection
3. javaType 是指定Java类属性
4. ofType 获取指定集合中POJO泛型信息

动态SQL

阅读官方文档

MyBatis学习笔记_第51张图片

动态SQL就是指根据不同的条件生成不同的SQL

搭建测试环境

创建数据库表

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

创建POJO实体类

/**
 * 博客表
 * @author Tu_Yooo
 * @Date 2021/3/13 15:42
 */
@Data
public class Blog {
     

    private String id;
    private String title;
    private String author;
    private Date createTime;
    private int views;
}

编写博客接口表

/**
 * 博客接口类
 * @author Tu_Yooo
 * @Date 2021/3/13 15:47
 */
public interface BlogMapper {
     
}

编写博客xml映射文件





<mapper namespace="cn.tony.mapper.BlogMapper">

mapper>

在核心配置文件中引入


    <mappers>
       <mapper resource="BlogMapper.xml"/>
    mappers>

编写UUID工具类

/**
 * 生成id工具类
 * @author Tu_Yooo
 * @Date 2021/3/13 15:53
 */
public class IDutils {
     

    public static String getId(){
     
        return UUID.randomUUID().toString().replaceAll("-","");
    }   
}

在核心配置文件中设置开启驼峰命名规则

 <settings>
        
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    settings>

插入数据

编写接口

//插入数据
public int insertBlog(Blog blog);

编写xml





<mapper namespace="cn.tony.mapper.BlogMapper">

    <insert id="insertBlog" parameterType="blog">
        insert into blog (id,title,author,create_time,views)
        values (#{id},#{title},#{author},#{createTime},#{views});
    insert>

mapper>

插入数据

 //测试插入数据
    @Test
    public void testaddBlog(){
     
        SqlSession session = MybatisUtil.getSqlSession();
        BlogMapper mapper = session.getMapper(BlogMapper.class);

        Blog blog = new Blog();
        blog.setId(IDutils.getId());
        blog.setTitle("Mybatis如此简单");
        blog.setAuthor("狂神说");
        blog.setCreateTime(new Date());
        blog.setViews(9999);

        mapper.insertBlog(blog);

        blog.setId(IDutils.getId());
        blog.setTitle("Java如此简单");
        mapper.insertBlog(blog);

        blog.setId(IDutils.getId());
        blog.setTitle("Spring如此简单");
        mapper.insertBlog(blog);

        blog.setId(IDutils.getId());
        blog.setTitle("微服务如此简单");
        mapper.insertBlog(blog);

        session.close();
    }

if标签

MyBatis学习笔记_第52张图片

查询博客信息

编写接口

//查询博客
public List<Blog> selectBlog(Map map);

编写XML文件

 
    <select id="selectBlog" parameterType="map" resultType="blog">
        select * from blog where 1=1
        /*如果传入author或title则匹配后面的值*/
        <if test="author != null">and author=#{author} if>
        <if test="title != null"> and title=#{title}if>
    select>

编写测试类

   @Test
    public void testSelectBlog(){
     
        SqlSession session = MybatisUtil.getSqlSession();
        BlogMapper mapper = session.getMapper(BlogMapper.class);

        Map<String, String> map = new HashMap();

        map.put("title","Java如此简单");
        List<Blog> list = mapper.selectBlog(map);
        for (Blog blog : list) {
     
            System.out.println(blog);
        }
        session.close();
    }

常用标签

trim、where、set标签

where标签

在实际生产环境,SQL不能用where 1=1这样不安全的查询
可以使用where标签匹配后面的查询

修改XML文件


    
    <select id="selectBlog" parameterType="map" resultType="blog">
        select * from blog
        <where>
            <if test="author != null">author=#{author} if>
            <if test="title != null"> and title=#{title}if>
        where>
    select>

where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

trim标签

如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ...
trim>

set标签

用于 动态更新语句 的类似解决方案叫做 set。set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。
MyBatis学习笔记_第53张图片

SQL片段

有些时候我们可能将公共(重复) 的SQL抽取出来,方便复用
这就是标签

使用与注意点:

  1. 使用抽取公共的部分
  2. 在需要使用的地方
  3. 最好基于单表来定义重用的片段
  4. 不要存在标签

修改XML文件

MyBatis学习笔记_第54张图片

<sql id="if-author-title">
        <if test="author != null">author=#{author} if>
        <if test="title != null"> and title=#{title}if>
    sql>

    
    
    <select id="selectBlog" parameterType="map" resultType="blog">
        select * from blog
        <where>
          <include refid="if-author-title"/>
        where>
    select>

choose (when, otherwise)标签

MyBatis学习笔记_第55张图片
choose像Java 中的 switch 语句。
只会匹配其中一个值

修改XML文件

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

foreach标签

阅读官方文档:

MyBatis学习笔记_第56张图片
解析官网SQL语句:

入参类型list集合 index集合中的下标 item集合中的元素
select * from POST p where id in ([开始符] 1 ,[分隔符]2,[分隔符],3[分隔符] )[结束符]

demo演示

需求:查询id为1,2,3的用户

编辑接口

 //查询用户id为1,2,3的用户
public List<Blog> getBlog(Map map);

编辑XML文件

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

demo测试

    //查询用户id为1,2,3的用户
    @Test
    public void test2(){
     
        SqlSession session = MybatisUtil.getSqlSession();
        BlogMapper mapper = session.getMapper(BlogMapper.class);

        Map<String, List> map = new HashMap();

        //准备list集合
        ArrayList<Integer> ids = new ArrayList<Integer>();
        ids.add(1);
        ids.add(2);
        ids.add(3);

        map.put("ids",ids);

        List<Blog> blog = mapper.getBlog(map);
        for (Blog blog1 : blog) {
     
            System.out.println(blog1);
        }
        session.close();
    }

日志工厂

在数据库的使用过程中,很多时候我们需要借助日志来进行排错
在以往我们使用:sout,debug
现在Mybatis提供了日志工厂

官方文档位置:
MyBatis学习笔记_第57张图片
在这里插入图片描述

SLF4J
LOG4J (掌握)
LOG4J2
JDK_LOGGING
COMMONS_LOGGING
STDOUT_LOGGING (掌握)
NO_LOGGING

在核心配置文件中加入日志配置

MyBatis学习笔记_第58张图片
此处使用STDOUT_LOGGING日志

<settings>
        
        <setting name="logImpl" value="STDOUT_LOGGING"/>
settings>

值得注意的是 sttings标签在properties标签和typeAliases中间 位置固定,否则会报错

测试运行

配置完日志,在查询时就能有以下日志输出了,有助于我们日常排错
MyBatis学习笔记_第59张图片

使用LOG4J日志

LOG4J简介

Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等

我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程

最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

导入依赖


<dependency>
    <groupId>log4jgroupId>
    <artifactId>log4jartifactId>
    <version>1.2.17version>
dependency>

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

配置log4j为日志实现

 <settings>
        <setting name="logImpl" value="LOG4J"/>
settings>

测试运行

MyBatis学习笔记_第60张图片

log4J简单使用

**
 * 测试log4j
 * @author Tu_Yooo
 * @Date 2021/3/10 16:48
 */
public class Log4jTest {
     


    //注意导包:org.apache.log4j.Logger
    static Logger logger = Logger.getLogger(Log4jTest.class);

    @Test
    public void testlog4j(){
     
        logger.info("普通级别输出日志");
        logger.debug("debug级别输出日志");
        logger.error("紧急级别输出日志");
    }
}

缓存

缓存简介

1.什么是缓存[ Cache ]?
存在内存中的临时数据
将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了 高并发系统的性能问题

2.为什么使用缓存?
减少和数据库的交互次数,减少系统开销,提高系统效率。

3.什么样的数据能使用缓存?
经常查询并且不经常改变的数据。

Mybatis缓存

MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。
MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存

  1. 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)。
  2. 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
  3. 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义
    二级缓存

缓存策略:
MyBatis学习笔记_第61张图片

一级缓存

一级缓存也叫本地缓存:sqlSession

  1. 与数据库同一次会话期间查询到的数据会放在本地缓存中。
  2. 以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库;

测试步骤:
1.开启日志
2.测试在一个sqlSession会话中是否查询两次数据库

编辑接口

public User getUser(@Param("id") int id);

编辑XML文件

<select id="getUser" resultType="cn.tony.pojo.User">
       select * from user where id=#{id}
select>

测试并查看日志

 @Test
    public void testgetUser(){
     

        //获取SQLsession
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        //获取接口实现类
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User user = mapper.getUser(1);
        System.out.println(user);
        System.out.println(">>>>>>>>>>>>>>>>");
        User user2 = mapper.getUser(1);
        //判断两个对象是否是一个
        System.out.println(user2);
        System.out.println(user2==user);

        sqlSession.close();
    }

MyBatis学习笔记_第62张图片
缓存失效的情况:

1.查询不同的数据
2.增删改完要刷新缓存
3.手动清除缓存sqlSession.clearCache();//手动清楚缓存
4.查询不同的Mapper.xml

一级缓存只在sqlSession会话中有效,也就是拿到连接到关闭连接这个区间段

二级缓存

二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存基于namespace级别的缓存,一个名称空间,对应一个二级缓存;

工作机制

  1. 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
  2. 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;
  3. 新的会话查询信息,就可以从二级缓存中获取内容;
  4. 不同的mapper查出的数据会放在自己对应的缓存(map)中;

缓存是默认关闭的需要手动开启二级缓存

二级缓存生效机制:一级缓存sqlSession1号去世的时候会将数据放进二级缓存中,sqlSession2号使用的时候会去二级缓存中取

步骤:
1.开启全局缓存
mybatis-config.xml中设置

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

2.在要使用二级缓存的Mapper.xml映射文件中设置
MyBatis学习笔记_第63张图片
也可以自定义参数


<cache
     eviction="FIFO"
     flushInterval="60000"
     size="512"
     readOnly="true"/>

3.在Mapper.xml映射文件中设置可以为不需要使用缓存的方法单独设定


<select id="getUser" resultType="cn.tony.pojo.User" useCache="false">
    select * from user where id=#{id}
select>

注意点:

我们需要将实体类序列化,否则会报错

总结:
1.只要开启了二级缓存,在同一个Mapper下就有效
2.所有的数据都会先放进一级缓存中
3.只有当会话提交,或者关闭的时候,才会提交到二级缓存

缓存原理

MyBatis学习笔记_第64张图片
缓存顺序:

1.先看二级缓存有没有数据
2.再看一级缓存中有没有数据
3.查询数据库

自定义缓存-EhCache

Ehcache是一种广泛使用的 java分布式缓存,用于通用缓存;

要在应用程序中使用Ehcache,需要引入依赖的jar包


<dependency>
   <groupId>org.mybatis.cachesgroupId>
   <artifactId>mybatis-ehcacheartifactId>
   <version>1.1.0version>
dependency>

mapper.xml中使用对应的缓存


<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

创建ehcahe.xml配置文件,里面提供一些自定义配置


<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
        updateCheck="false">
   
   <diskStore path="./tmpdir/Tmp_EhCache"/>
   
   <defaultCache
           eternal="false"
           maxElementsInMemory="10000"
           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="1800"
           memoryStoreEvictionPolicy="LRU"/>
   
   

ehcache>

你可能感兴趣的:(狂神说学习笔记,java,mybatis,数据库)