Mybatis个人学习笔记

Mybatis个人总结笔记

01 基本信息

  1. Mybatis 是 SQL映射框架
  2. 可以将数据库表中的一行数据, 映射为一个java对象, 操作这个对象, 相当于操作表中的数据
  3. 开发人员只需要提供SQL, 通过 Mybatis 处理sql, 最终就能得到List集合或者是Java对象
  4. Mybatis是半自动ORM映射工具, 因为他在查询关联对象或关联集合对象时, 需要手动编写SQL 来实现, 所以称之为 半自动ORM映射工具

02 传统JDBC的缺陷

  1. 数据库连接创建, 释放频繁造成系统资源浪费从而会影响系统的性能, 如果说使用数据库连接池会解决这个问题

解决:在mybatis-config.xml 配置文件中配置数据库连接池, 使用连接池来进行管理

  1. SQL 在 代码中是硬编码, 造成代码不易维护, 实际应用SQL的变化的可能比较大,SQL的变动需要改动Java代码

解决:将SQL语句配置在XXXmapper.xml 文件中, 与java代码分隔

  1. 使用PreparedStatement向占位符传参存在硬编码, 因为SQL语句的where条件不一定, 可能多也可能少, 修改SQL语句还有修改代码, 系统不易维护

解决:Mybatis自动将Java对象映射到SQL语句中

  1. 对结果集解析存在硬编码

解决:Mybatis 自动将SQL执行结果映射至Java对象

03 Mybatis的优点和缺点

3.1 优点

  1. 基于SQL语句编程, 相当的灵活,不会对应用程序或者数据库的现有设计造成任何影响
  2. SQL语句编写在XML文件中, 解除了SQL与程序代码的耦合
  3. 与JDBC相比, 代码量少, 消除了JDBC中大量的冗余代码, 不需要手动开关连接
  4. 能和多种数据库兼容

3.2 缺点

  1. SQL语句的编写工作量大, 尤其当字段多,关联表比较多的是,SQL语句编写难度大
  2. SQL语句依赖于数据库, 导致数据库移植能力差

04 Mybatis的开发方式

4.1 使用原生接口

4.1.1 添加依赖

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.5.1</version>
</dependency>
<dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.13</version>
</dependency>

4.1.2 新建数据库表

4.1.3 创建数据表对应的实体类

package com.mybatis.model;

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

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private String username;
    private String sex;
    private Long phone;
}

4.1.4 创建SQL映射文件

Mybatis 框架需要开发者自定义SQL语句, 写在Mapper.xml 文件中, 实际开发中, 会为每个实体类创建一个对应的Mapper.xml , 定义管理该对象数据的SQL

  • namespace:通常设置为 文件所在包+文件名的形式
  • select标签表示执行查询操作
  • insert标签表示执行插入操作
  • update标签表示执行更新操作
  • delete标签表示执行删除操作
  • id:实际调用Mybatis方法是需要用到的参数
  • paramterType:调用对应方法时,参数的数据类型
<?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.mybatis.dao.UserMapper">
    <select id="getAllStudent" resultType="com.mybatis.model.Student">
        select * from student
    </select>
</mapper>

4.1.5 创建Mybatis主配置文件

部分参数解析
<transactionManager type="JDBC"/>

  • JDBC:表示mybatis底层调用JDBC中的Connection 对象的 commit rollback
  • MANAGED:把mybatis的事务处理委托给其他的容器,一个服务器软件,一个框架spring

<dataSource type="POOLED">

  • 表示数据源, java体系中,规定使用javax.sql.DataSoutce 接口的都是数据源,数据源表示Connection对象。
  • type的类型
    • POOLED:使用连接池,mybatis会创建PooleDataSource类
    • UPOOLED:不使用连接池,在每次执行sql语句,先创建连接,执行sql,在关闭连接mybatis会创建一个UnPooledDataSource,管理Connection的管理
<?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>
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <!--配置Mybatis的运行环境 default是从多个数据源中选一个-->
    <environments default="development">
        <!--一个数据源,id值唯一-->
        <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:3306 /frame?serverTimezone=GMT%2B8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com\mybatis\dao\UserMapper.xml"/>
    </mappers>
</configuration>

4.1.6 创建测试类

public class Main {
    public static void main(String[] args) throws IOException {
        String config = "mybatis-config.xml";
        //读取路径所表示文件的信息
        InputStream in = Resources.getResourceAsStream(config);
        //创建SqlSession对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sessionFactory = builder.build(in);
        SqlSession sqlSession = sessionFactory.openSession();
        Student student = new Student("佩奇","男","18893694975");
        String statement = "com.mybatis.dao.UserMapper.insertStudent";
        sqlSession.insert(statement,student);
        sqlSession.commit();
        sqlSession.close();
    }
}

4.2 使用Mapper代理实现自定义接口

4.2.1 添加依赖

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.5.1</version>
</dependency>
<dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.13</version>
</dependency>

4.2.2 新建数据库表

4.2.3 创建数据表对应的实体类

package com.mybatis.model;

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

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private String username;
    private String sex;
    private Long phone;
}

4.2.4 自定义Mapper接口

public interface UserMapper {
    List<Student> getAllStudent();
    int save(Student student);
    int deleteByName(String name);
    int update(Student student);
}

4.2.5 创建接口映射文件

statement标签可根据SQL执行的业务选择, Mybatis框架会根据规则自动创建接口实现类的代理对象

规则

  • Mapper.xml 中 namespace 为接口的全类名
  • Mapper.xml 中 statement 的 id 为接口中对应的方法名
  • Mapper.xml 中 statement 的 parameterType 和接口中对应方法的参数类型一致
  • Mapper.xml 中 statement 的 resultType 和接口中对应方法的返回值类型一致
<?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.mybatis.dao.UserMapper">
    <insert id="save" parameterType="com.mybatis.model.Student">
        insert into student(username,sex,phone) values(#{username},#{sex},#{phone})
    </insert>
    <select id="getAllStudent" resultType="com.mybatis.model.Student">
        select * from student
    </select>
    <update id="update" parameterType="com.mybatis.model.Student">
        update student set phone=#{phone} where username=#{username}
    </update>
    <delete id="deleteByName" parameterType="java.lang.String">
        delete from student where username=#{username}
    </delete>
</mapper>

4.2.6 创建Mybatis主配置文件

<?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>
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <!--配置Mybatis的运行环境 default是从多个数据源中选一个-->
    <environments default="development">
        <!--一个数据源,id值唯一-->
        <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:3306 /frame?serverTimezone=GMT%2B8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com\mybatis\dao\UserMapper.xml"/>
    </mappers>
</configuration>

4.2.7 创建测试类

public class Main {
    public static void main(String[] args) throws IOException {
        String config = "mybatis-config.xml";
        //读取路径所表示文件的信息
        InputStream in = Resources.getResourceAsStream(config);
        //创建SqlSession对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sessionFactory = builder.build(in);
        SqlSession sqlSession = sessionFactory.openSession();
        Student student = new Student("佩奇","男","18893694975");
        UserMapper mapper = (UserMapper) sqlSession.getMapper(UserMapper.class);
        // 插入
        int save = mapper.save(student);
        // 查询
        List<Student> allStudent = mapper.getAllStudent();
        // 删除
        int i = mapper.deleteByName("佩奇");
        // 更新
        Student s = new Student("佩奇","男","18893694974");
        int update = mapper.update(s);
        sqlSession.commit();
        sqlSession.close();
    }
}

4.3 配置日志

为了方便我们查看SQL的变化情况,在主配置文件中查看

 <!--控制mybatis全局行为的-->
    <settings>
        <!--设置输出日志-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

05 主要对象说明

5.1 Resources类

  1. mybatis中的一个类,主要负责读取配置文件

5.2 SqlSessionFactoryBuilder

  1. 主要是为了创建SqlSessionFactory对象

5.3 SqlSessionFactroy

  1. 主要是为了创建SqlSession对象
  2. 程序创建这个对象,创建时间比较长,使用的资源比较多,在整个项目中使用一个就好了
  3. 这是一个接口

5.4 openSession方法

  1. 无参数:获取自动提交事务的SqlSession对象
  2. 有参数
  • true:获取自动提交事务的SqlSession对象
  • false:获取非自动提交事务的·SqlSession对象

5.5 SqlSession

  1. 是一个接口,定义了操作数据的方法
  2. 使用要求
  • SqlSession对象不是线程安全的, 需要在方法的内部进行使用, 在执行sql语句之前, 使用openSession()获取, 执行之后, 需要关闭这样就会保证线程是安全的

06 工作原理


  1. Mybatis-config.xml
    1. 作为Mybatis的全局配置文件, 配置了Mybatis的全局配置文件,配置了mybatis的运行环境等信息。
  2. Mapper.xml
    1. SQL 映射文件,文件中配置了操作数据库的SQL语言。这个文件需要在Mybatis-config.xml中进行配置
  3. 通过配置信息来创建会话工厂,SqlSessionFactory
  4. 会话工厂来创建会话,即SqlSession
  5. Mybatis底层自定义了Executor执行器接口操作数据库, Executor接口有两个实现
    1. 基本执行器
    2. 缓存执行器

07 SQL映射文件

7.1 statement标签

select、update、delete、insert分别对应查询,修改,删除,添加操作

<insert id="save" parameterType="com.mybatis.model.Student">
  insert into student(username,sex,phone) values(#{username},#{sex},#{phone})
</insert>

<select id="getAllStudent" resultType="com.mybatis.model.Student">
  select * from student
</select>

<update id="update" parameterType="com.mybatis.model.Student">
  update student set phone=#{phone} where username=#{username}
</update>

<delete id="deleteByName" parameterType="java.lang.String">
  delete from student where username=#{username}
</delete>

7.2 parameterType

指定传入参数的类型

7.2.1 基本数据类型

int findByAge(int age);
<select id="findByAge" parameterType="java.lang.Integer" resultType="java.lang.Integer">
  select count(*) from student where age= #{age}
</select>

7.2.2 String类型

根据用户名删除学生信息

<delete id="deleteByName" parameterType="java.lang.String">
  delete from student where username=#{username}
</delete>

7.2.3 包装类

向 student 表中添加一条数据

<insert id="save" parameterType="com.mybatis.model.Student">
  insert into student(username,sex,phone) values(#{username},#{sex},#{phone})
</insert>

7.2.4 多个参数

这里可以使用param1 也可以是用age1。 这里的数字表示位于方法参数的第几个

List<Student> findByNameAndPhone(String username,String phone);
<select id="findByNameAndPhone" resultType="com.mybatis.model.Student">
        select * from student where username=#{param1} and phone = #{param2}
    </select>

7.2.5 Map

#{键名}

 List<Student> findByNameAndPhone(Map map);
<select id="findByNameAndPhone" resultType="com.mybatis.model.Student">
        select * from student where username=#{username} and phone = #{phone}
    </select>

7.3 resultType

结果类型

Java Bean

结果类型,值SQL执行完毕之后,数据转为的java对象
默认原则:同名的列名赋值给同名的属性

处理方式

mybatis执行sql语句,然后mybatis调用类的无参构造方法,创建对象

mybatis把ResultSet指定的列值付给同名的属性

定义别名

这个必须定义在标签的前面

    <typeAliases>
        <typeAlias type="自定义类型的全限定名称" alias="别名"></typeAlias>
    </typeAliases>

08 工具类

public class MybatisUtils {
    private MybatisUtils(){}
    private static SqlSessionFactory sqlSessionFactory;
    static{
        String config = "mybatis-config.xml";
        try {
            InputStream in = Resources.getResourceAsStream(config);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    public static SqlSession getSession(){
        SqlSession sqlSession = null;
        if(sqlSessionFactory != null) {
            sqlSession = sqlSessionFactory.openSession();
        }
        return sqlSession;
    }
}

09 级联操作

使用<resultMap>中的<association><collection>子标签,进行关联查询

9.1 一对多

一个部门有多个职工, 一个职工只能位于一个部门

创建实体类

@Data
public class Department {
    private Integer id;
    private String name;
    private List<Stuff> list;
}

@Data
public class Stuff {
    private long id;
    private String name;
    private Department department;
}

创建接口方法

    List<Stuff> findInfo(long id);

创建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.mybatis.dao.UserMapper">
    <resultMap id="StuffMap" type="com.mybatis.model.Stuff">
        <!--映射主键-->
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <association property="department" javaType="com.mybatis.model.Department">
            <id column="did" property="id"></id>
            <result column="dname" property="name"></result>
        </association>
    </resultMap>
   
    <select id="findInfo" parameterType="java.lang.Long" resultMap="StuffMap">
        select s.id, s.name,d.name as dname,d.id as did
        from stuff s , department d
        where s.id = #{id} and s.did = d.id
    </select>
</mapper>

9.2 多对多

一个顾客可以购买多个商品, 一个商品可以被多个用户购买

创建实体类

@Data
public class Customer {
    private long id;
    private String name;
    private List<Goods> goods;
}
@Data
public class Goods {
    private long id;
    private String name;
    private List<Customer> customers;
}

创建Mapper接口

public interface ShoppingMapper {
    List<Customer> findById(long id);
}

创建映射文件

<?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.mybatis.dao.ShoppingMapper">
    <resultMap id="customer" type="com.mybatis.model.Customer">
        <id column="cid" property="id"></id>
        <result column="cname" property="name"></result>
        <collection property="goods" ofType="com.mybatis.model.Goods">
            <id column="gid" property="id"></id>
            <result column="gname" property="name"></result>
        </collection>
    </resultMap>
    <select id="findById" parameterType="long" resultMap="customer">
        select c.id as cid ,c.name as cname, g.id as gid , g.name as gname
        from customer c,goods g, cutomer_goods cg
        where c.id = #{id} and cg.cid = c.id and cg.gid = g.id
    </select>
</mapper>

10 两个占位符之间进行比较

  1. #{}
    1. 相对安全
    2. 使用的是PreparedStatement对象
    3. 效率高
  2. ${}
    1. 容易Sql注入
    2. 使用的是Statement对象
    3. 效率低

11 动态sql

sql语句的内容是变化的,可以根据条件获取到不同的是sql

01 if

if 标签可以根据表达式的值,来决定是否将对应的语句添加到 SQL 中

<if test="判断java对象的属性">
	部分sql语句
</if>

示例

    <select id="selectUniqueStudent" resultType="com.hl.mybatis.Student">
        select * from studentlist where
        1=1
        <if test="name!=''">
            and ID = #{ID}
        </if>>
    </select>

02 where

用于包含多个的,当有多个if 有一个成立的时候,会自动增加一个where关键字,并且会去掉 if 中多余的and 和 or。通常情况下 if 和 where 结合起来使用

<select id="findGoodsByIdLazy" parameterType="com.mybatis.model.Goods" resultType="goods" >
    select * from goods
    <where>
        <if test="id != 0">
            id = #{id}
        </if>
        <if test="name != null">
            and username = #{name}
        </if>
    </where>
</select>

03 choose 标签

<select id="find" resultType="goods" parameterType="goods">
        select * from goods
        <where>
            <choose>
                <when test="id != 0">
                    id = #{id}
                </when>
                <when test="name != null">
                    name = #{name}
                </when>
            </choose>
        </where>
    </select>

04 trim

trim 中的 prefix 和 suffix 属性会被用于生成实际的SQL语句,会和标签内部的语句进行拼接,如果说语句前后出现了 prefixOverrides 或者 suffixOverrides 属性中指定的值,Mybatis 框架会自动将其删除

<trim prefix="where" prefixOverrides="and">
  <if test="id != 0">
    id = #{id}
  </if>
  <if test="username != null">
    and name = #{name}
  </if>
</trim>

05 set 标签

用于update 操作,会自动根据参数选择生成SQL语句

<update id="updateGoods">
  update goods 
  <set>
    <if test="name != null">
      name = #{name}
    </if>
  </set>
  where id = #{id}
</update>

06 foreach 标签

可以迭代生成一系列的值,这个标签主要用于SQL 中的 in 语句

<select id="find" resultType="goods">
    select * from goods
    <where>
        <foreach collection="ids" open="in in (" item="id" separator=",">
            #{id}
        </foreach>
    </where>
</select>

12 延迟加载

  1. 什么是延迟加载?
  • 延迟加载也叫懒加载,惰性加载,使用延迟加载可以提高程序的运行效率,针对于数据持久层的操作,在某些特定的情况之下访问特定的数据库,在其他情况之下可以不访问某些表,从一定程度上减少了Java应用于数据库的交互次数
  • 查询学生和班级的时候,学生和班级是两张不同的表,如果当前需求只需要获取学生的信息,那么查询学生单标即可,如果需要通过学生获取对应的班级信息,那么必须要查询两张表
  • 不同的业务需求,需要查询不同的表根据具体的业务需求来动态的减少数据表查询的工作就是延迟加载
  1. 开发步骤
  • 在Mybatis的主配置文件中,开启延迟加载
<settings>
  <setting name="logImpl" value="STDOUT_LOGGING"/>
  <setting name="lazyLoadingEnabled" value="true"/>
</settings>
  • 将多表关联查询拆分成多个单表查询
<resultMap id="customer" type="com.mybatis.model.Customer">
    <id column="cid" property="id"></id>
    <result column="cname" property="name"></result>
    <association property="goods" javaType="com.mybatis.model.Goods" select="findGoodsByIdLazy" column="cid">

    </association>
</resultMap>
<select id="findCustomerByIdLazy" parameterType="long" resultMap="customer">
    select * from customer where id = #{id}
</select>
<select id="findGoodsByIdLazy" parameterType="long" resultType="goods" >
    select * from goods where id = #{id}
</select>

13 数据库的属性配置文件

将数据库的连接信息,放在一个单独的文件中,和mybatis主配置文件进行分开

目的:便于修改,保存,处理多个数据库的信息

在resource目录中定义一个属性配置文件,XXX.properties

mybatis.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 resource="jdbc.properties"></properties>
    <settings>
        <!--设置输出日志-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <typeAliases>
        <typeAlias type="java.lang.Integer" alias="i"></typeAlias>
    </typeAliases>

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

    <mappers>
        <mapper resource="com\hl\mybatis\StudentImpl.xml"/>
    </mappers>
</configuration>

jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/chat?serverTimezone=UTC
jdbc.user=root
jdbc.password=123456

14 指定多个mapper文件

方式一

<mappers>
  <mapper resource="com\hl\mybatis\StudentImpl.xml"/>
  <mapper resource="com\hl\mybatis\StudentImpl.xml"/>      
</mappers>

方式二

mapper文件名称需要和dao接口名称一致,区分大小写

mapper文件和dao接口需要在同一个目录之下

<mappers>
    
        <package name="mapper文件所在位置,全限定名称"/>
    </mappers>

15 PageHelper

Mybatis 通用的分页插件

方式一

通过sql

通过插件

加入maven依赖

<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.2.1</version>
</dependency>

在mybatis主配置文件中加入依赖

    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>

创建测试类

PageHelper.startPage(起始页数,一页有多少条数据);

    @Test
    public void test8(){
        
        SqlSession sqlSession  = MybatisUtils.getSqlSession();
        
        PageHelper.startPage(1,3);
        
        List<Student> students = sqlSession.getMapper(StudentImpl.class).getAllStudent();
        
        System.out.println(students.size());
        
        for(Student s:students){
            
            System.out.println(s);
            
        }

    }

16 缓存

使用缓存可以减少Java应用于数据库的交互次数,从而提升程序的运行效率。比如说查询出一个 id = 1 的对象,第一次查询出之后会自动将该对象保存在缓存之中,当下一次查询时候,直接从缓存中取出对象即可,无需再次访问数据库

01 一级缓存

SqlSession 级别,默认开启,并且说不能关闭

  1. 操作数据库时需要创建SqlSession 对象,在对象中有一个HashMap 用于存储缓存数据,不同的SqlSession 之间,缓存数据区域是互不影响的。
  2. 一级缓存的作用域是SqlSession范围的,当在同一个SqlSession 中执行了两次相同的SQL语句时,第一次执行完成将结果保存在缓存之中,第二次查询会直接从缓冲中进行获取
  3. 需要注意的是,如果说SqlSession执行力DML(insert,update,delete)操作,Mybatis 必须将缓存清空以保证数据的准确性

02 二级缓存

Mapper 级别,默认关闭,可以开启

2.1 基本信息

  1. 使用二级缓存的时候,多个SqlSession使用同一个Mapper的SQL语句操作数据库,得到的数据会存放在二级缓存之中,同样是使用HashMap进行数据存储,相比较于一级缓存,二级缓存的范围更大,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的
  2. 二级缓存是多个SqlSession共享的,其作用域是Mapper的同一个namespace,不同的SqlSession 两次执行相同的 namespace 下的SQL语句,参数也是相等的,则第一次执行成功之后会将数据保存到二级缓存中,第二次之间从二级缓存中取出数据

2.2 Mybatis 自带的二级缓存

  1. Mybatis 主配置文件
<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
    <setting name="lazyLoadingEnabled" value="true"/>
    <setting name="cacheEnabled" value="true"/>
</settings>

  1. Mapper.xml 文件
<cache></cache>
  1. 实体类实现序列化接口
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Serializable {
    private String username;
    private String sex;
    private String phone;
    private Integer age;
    private Department department;
}

2.3 ehcache 二级缓存

  1. 添加依赖
 <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-ehcache</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>net.sf.ehcache</groupId>
      <artifactId>ehcache-core</artifactId>
      <version>2.0.0</version>
    </dependency>

  1. 添加ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">     
    
    <diskStore path="java.io.tmpdir"/>         
    <defaultCache     
            maxElementsInMemory="10000"    
            eternal="false"    
            timeToIdleSeconds="120"    
            timeToLiveSeconds="120"    
            overflowToDisk="true"    
            maxElementsOnDisk="10000000"    
            diskPersistent="false"    
            diskExpiryThreadIntervalSeconds="120"    
            memoryStoreEvictionPolicy="LRU"    
            />     
</ehcache>
  1. Mybatis.xml 的主配置文件中开启二级缓存
<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
    <setting name="lazyLoadingEnabled" value="true"/>
    <setting name="cacheEnabled" value="true"/>
</settings>
  1. Mapper.xml 中配置二级缓存
<cache type="org.mybatis.caches.ehcache.EhcacheCache">
  <!--缓存创建之后,最后一次访问缓存的时间至缓存失效的时间间隔-->
  <property name="timeToIdleSeconds" value="3600"/>
  <!--缓存自创建时间起至失效的时间间隔-->
  <property name="timeToLiveSeconds" value="3600"/>
  <!--缓存的回收策略-->
  <property name="memoryStoreEvictionPolicy" value="LRU"/>
</cache>
  1. 实体类不需要实现序列化接口

17 maven对静态资源的过滤

 <build>
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
        </includes>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.*</include>
        </includes>
      </resource>
    </resources>
  </build>
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

佩奇inging

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值