Mybatis框架基础知识

霸气de小男生 提交于 2020-01-18 09:33:18

mybatis的官方文档网站 https://mybatis.org/mybatis-3/zh/index.html

什么是框架

框架是某种应用的半成品,就是一组组件,是一套解决方案,供你选用完成自己的系统。框架帮你封装了一些细节,开发者可以使用极简的方式实现功能,可以提高程序的开发效率。

三层架构和框架

在这里插入图片描述

持久层技术解决方案

  • JDBC技术:
    Connection
    PreparedStatement
    ResultSet
  • Spring的JdbcTemplate:
    Spring中对jdbc的简单封装
  • Apache的DBUtils:
    也是对jdbc的简单封装
    以上这些都不是框架
    jdbc是规范
    JdbcTemplate和DBUtils都是工具类

MyBatis框架概述

mybatis是一个优秀的基于java的持久层框架,用java编写,它内部发封装了jdbc,使开发者只需要关注sql语句本身,而不需要话费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。
采用ORM思想解决了实体和数据库的映射,实现了结果集的封装

  • ORM(对象关系映射)
    就是把数据库和实体类的属性进行对应起来
    让我们可以操作实体类实现操作数据库表

mybatis的环境搭建

1、创建maven工程导入坐标

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>

2、创建实体类和dao的接口
3、创建mybatis的主配置文件
4、创建映射配置文件
环境搭建的注意事项

  • mybatis的映射文件位置必须和dao接口的包结构相同

  • 在idea中创建目录时,它和包是不一样的
    包在创建时,com.hwh是二级目录
    目录在创建时,com.hwh 是一级目录

  • 映射配置文件的mapper标签namespace属性的取值必须是dao接口的全限定类名

  • 映射配置文件的操作配置(如select),id属性必须是dao接口的方法名

入门案例代码:(基于xml配置)

  • 实体类
package com.hwh.entity;



import java.io.Serializable;
import java.util.Date;

/**
 * @Description TODO
 * @Author hwh
 * @Date 2019/12/24 21:02
 **/
public class User implements Serializable {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", birthday=" + birthday +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

  • IUserDao
package com.hwh.dao;

import com.hwh.entity.User;

import java.util.List;

/**
 * @Description TODO
 * @Author hwh
 * @Date 2019/12/24 21:06
 **/
public interface IUserDao {
    public List<User> findAllUser();
}

  • sqlMapConfig.xml(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>
    <!-- 配置环境-->
    <environments default="mysql">
        <environment id="mysql">
            <!-- 配置事务的类型-->
            <transactionManager type="JDBC"/>
            <!-- 配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!-- 配置连接数据库的4个基础信息-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test"/>
                <property name="username" value="root"/>
                <property name="password" value=""/>
            </dataSource>
        </environment>
    </environments>
    <!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件-->
    <mappers>
        <mapper resource="com/hwh/dao/IUserMapper.xml"/>
    </mappers>
</configuration>
  • IUserMapper.xml(mapper映射文件)
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.hwh.dao.IUserDao">
<!--id需与接口中的方法名称一致-->
    <select id="findAllUser" resultType="com.hwh.entity.User">
		select * from user
	</select>


</mapper>
  • test.java(测试类)
import com.hwh.dao.UserDao;
import com.hwh.entity.User;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;


import java.io.IOException;
import java.io.InputStream;
import java.util.List;


public class test {
    private InputStream in;
    private SqlSession sqlSession;
    private UserDao userDao;

    @Before
    public void init() throws IOException {
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        sqlSession = factory.openSession();
        userDao = sqlSession.getMapper(UserDao.class);
    }

    @After
    public void destroy() throws IOException {
        in.close();
        sqlSession.close();
    }

    @Test
    public void testAllUsers(){
        List<User> users = userDao.findAllUsers();
        for(User user:users){
            System.out.println(user);
        }
    }
}

  • 基于注解配置
public interface IUserDao {
    @Select("select * from user")
    public List<User> findAllUser();
}
   <mapper class="com.hwh.dao.IUserDao"></mapper>
   

获取插入数据的id

<!--保存用户-->
	<insert id="saveUser" parameterType="com.hwh.entity.User">
		<!--获取插入数据行的id-->
		<!--keyProperty为属性名 keyColumn为列名-->
		<selectKey keyProperty="id" keyColumn="id" resultType="java.lang.Integer" order="AFTER">
			select last_insert_id();
		</selectKey>
		insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
	</insert>

模糊查询(两种方式)

    /**
     * 根据名字进行模糊查询
     */
    @Test
    public void findUserByName(){
//        List<User> users = userDao.findUserByName("%a%");
        List<User> users = userDao.findUserByName("a");
        for(User user:users){
            System.out.println(user);
        }
    }
	<!--根据名字模糊查询-->
	<select id="findUserByName" parameterType="java.lang.String" resultType="com.hwh.entity.User">
		<!--select * from user where username like #{name}-->
		select * from user where username like '%${value}%'
	</select>
  • 注意
    #表示为PreparedsStatement的占位符,可以防止sql注入,一般用这种方式
    $为Statement的字符串拼接。

log4j

#设置日志的级别 ,多个以,分开(没有给出的,则不会被输出)
log4j.rootLogger=debug,A,R

#
log4j.appender.logfile.encoding=utf-8
#DailyRollingFileAppender每天产生一个日志文件
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender

#设置日志文件保存路径
log4j.appender.R.File=logs/log.log //这里的是你输出到日志文件的路径

#日志输出格式
log4j.appender.R.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss} [%c]-[%p] %m%n

#设置日志文件后缀名,决定着多长时间创建一个新的文件!yyyyMMdd每天一个,yyyyMMddHH第小时一个,...
log4j.appender.R.DatePattern='.'yyyy-MM-dd

#日志布局格式
log4j.appender.R.layout=org.apache.log4j.PatternLayout
#输出到控制台
log4j.appender.A=org.apache.log4j.ConsoleAppender
log4j.appender.A.layout=org.apache.log4j.PatternLayout
log4j.appender.A.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n

mybatis的参数深入

parameterType(输入类型)

  • 传递简单类型
  • 传递pojo对象(也就是javabean对象)
    mybatis使用ognl表达式解析对象的值,#{}或者${}括号中的值为pojo属性名称。
    扩展:OGNL表达式(Apache开发)
    全称 Object graphic navigation language(对象图导航语言)
    它是通过对象的取值方法来获取数据,在写法上把get给省略了
    如:我们获取用户的名称
    类中的写法:user.getUsername();
    OGNL表达式写法:user.username
    mybatis 中为什么直接写username而不用写user.,是因为在parameterType中已经提供了属性所属的类,所以此时不需要写对象名。
  • 传递pojo包装对象

当表字段与类属性名不一致时的两种解决方案

  • 查询时使用别名
    示例代码:
select id as userId,username as userName from user 
  • 使用resultMap使字段名与类属性名对应(推荐使用,可以提高开发效率)
    示例代码
	<resultMap id="userMap" type="com.hwh.entity.User">
		<!--主键字段的对应-->
		<id property="userId" column="id"></id>
		<!--非主键字段的对应-->
		<result property="userAddress" column="address"></result>
	</resultMap>

注意:在window系统下mysql不区分大小写,但是在linux系统下时严格区分大小写的

Properties标签

  • 配置properties
    可以再标签内部配置连接数据库的信息,也可以通过属性引用外部配置文件信息
    resources属性(常用)
    用于指定配置文件的位置,是按照类路径的写法来写,并且必须存在于类路径下
    url属性:
    是要求按照Url的写法来写地址
    URL Uniform Resource Locator 统一资源定位符,它是可以唯一标识资源的位置
    它的写法:
    http://localhost:8080/mybatis/demoServlet
    协议    主机      端口            URI
    URI: Uniform Resource Identifier 统一资源标识符,它是在应用中可以唯一定位一个资源的。
    <properties resource="application.properties">
<!--        <property name="driver" value="com.mysql.jdbc.Driver"/>-->
<!--        <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=UTF8"/>-->
<!--        <property name="username" value="root"/>-->
<!--        <property name="password" value=""/>-->

    </properties>

typeAliases

作用: 用于配置别名,它只能配置类的别名
在这里插入图片描述

连接池

我们在实际开发中都会实用连接池,因为它可以减少我们获取连接所消耗的时间。
连接池就是用于存储连接的一个容器。
容器其实是一个集合对象,该集合必须是线程安全的,不能两个线程拿到同一个连接。
该集合必须实现队列的特性:先进先出

mybatis中的连接池

mybatis连接池提供来3中方式的配置:

  • 配置的位置
    主配置文件SqlMapConfig.xml(主配置文件)的dataSource标签,type属性就是表示采用何种连接池方式。
    type属性的取值:
    POOLED 采用传统的javax.sql.DateSource规范中的连接池,mybatis中有针对规范的实现
    UPOOLED 采用传统的获取连接的方式,虽然也实现来javax.sql.DataSource接口,但是并没有实用池的思想(每次用都重新获取一个连接)
    JNDI 采用服务器提供JNDI技术实现来获取dataSource对象,不同的服务器所能拿到的dataSource是不一样的
    注意:如果不是web或者maven的war工程,是不能实用的
    一般使用的tomcat服务器,采用的连接池就是dbcp连接池。

  • POOLED原理
    当需要获取一个连接时,首先看空闲池中是否有连接,若有则返回一个连接,若没有则看活动池中是否已经达到最大数量,若没达到,则建立一个连接,若已达到最大数量,则将最老的连接拿过来用。
    在这里插入图片描述

事务(待写)

  • 什么是事务
    事务由单独单元的一个或者多个sql语句组成,在这个单元中,每个mysql语句时相互依赖的。而整个单独单元作为一个不可分割的整体,如果单元中某条sql语句一旦执行失败或者产生错误,整个单元将会回滚,也就是所有受到影响的数据将会返回到事务开始以前的状态;如果单元中的所有sql语句均执行成功,则事务被顺利执行。
  • 事务的四大特性(ACID)
    1)原子性
    原子性指事务不可分割,要么全部执行,要么全部不执行
    2)一致性
    事务必须使数据库在事务执行前与执行后保持一个一致的状态(如银行转账,总金额仍一致)
    3)隔离性
    多个并发事务之间相互隔离,互补干扰
    4)持久性
     持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
  • 不考虑隔离性会产生的3个问题
    1)脏读
    一个事务读取了另一个事物未提交的数据
    2)不可重复读
    一个事务多次读取表中数据,结果不一致
    不可重复读和脏读的区别是,脏读是读取前一事务未提交的脏数据,不可重复读是重新读取了前一事务已提交的数据。
    3)幻读(虚读)
    一个事务读取了别的事务插入的数据导致前后读取结果不一致
  • 解决办法:四种隔离级别(隔离级别由低到高)
    1)Read uncommitted(读未提交)
    一个事务可以读取另一个未提交事务的数据。
    2)Read committed(度提交)
    就是一个事务要等另一个事务提交后才能读取数据。
    3)Repeatable read(重复读)
    就是在开始读取数据(事务开启)时,不再允许修改操作
    4)Serializable(序列化)
    是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。
    注意:大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle。Mysql的默认隔离级别是Repeatable read。

mybatis中的事务

sqlSession的commit和rollback方法实现事物的提交和回滚

  sqlSession = factory.openSession(ture);

通过设置为true可以将其设置为自动提交

mybatis中的动态sql语句

  • if判断语句
    <select id="findByCondition" parameterType="user" resultType="user">
        select * from user where 1=1
        <if test="username!=null">
            and username=#{username}
        </if>
    </select>
  • where标签
    加上where标签可以省略上面的where 1=1,效果等同于上面的代码
    <select id="findByCondition" parameterType="user" resultType="user">
        select * from user
        <where>
            <if test="username!=null">
                and username=#{username}
            </if>          
        </where> 
    </select>
  • foreach标签实现in查询
    <select id="findInId" parameterType="queryvo" resultType="user">
        select * from user
        <where>
            <foreach collection="ids" open="and id in (" close=")" item="uid" separator=",">
                #{uid}
            </foreach>
        </where>

    </select>

抽取重复的sql语句

	<sql id="defaultSql">
        select * from user
    </sql>
     
<select id="findAllUsers" resultType="user">
        <include refid="defaultSql"></include>
        <!--select * from user-->
    </select>

mybatis中的查询

表之间的关系

  • 一对多
  • 多对一
  • 一对一
  • 多对多

mybatis中一对一的多表查询

主要代码

  • accountMapper.xml(mapper配置文件)
<?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.hwh.dao.AccountDao">
    <resultMap id="accountMap" type="account">
        <id property="id" column="aid"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
        <association property="user" column="uid" javaType="user">
            <id property="id" column="id"></id>
            <result property="username" column="username"></result>
            <result property="birthday" column="birthday"></result>
            <result property="sex" column="sex"></result>
            <result property="address" column="address"></result>
        </association>
    </resultMap>

    <select id="findAllAccount" resultMap="accountMap">
        select u.*,a.id as aid,uid,money from account a,user u where a.uid=u.id
    </select>


</mapper>
  • Account类(将user封装进account类)
package com.hwh.entity;

public class Account {
    private Integer id;
    private Integer uid;
    private Float money;
    private User user;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getUid() {
        return uid;
    }

    public void setUid(Integer uid) {
        this.uid = uid;
    }

    public Float getMoney() {
        return money;
    }

    public void setMoney(Float money) {
        this.money = money;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", uid=" + uid +
                ", money=" + money +
                ", user=" + user +
                '}';
    }
}

mybatis中一对多的查询

<resultMap id="userMap" type="user">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="birthday" column="birthday"></result>
        <result property="sex" column="sex"></result>
        <result property="address" column="address"></result>
        <collection property="account" ofType="account">
            <id property="id" column="aid"></id>
            <result property="uid" column="uid"></result>
            <result property="money" column="money"></result>
        </collection>
    </resultMap>

    <select id="findAllUsers" resultMap="userMap">
        SELECT
        `u`.*, `a`.`id` AS 'aid', `uid`, `money`
        FROM
        `user` u
        LEFT JOIN `account` a ON `a`.`uid` = `u`.`id`
    </select>

mybatis中的延迟加载

问题:在一对多中,当我们有一个用户,他有100个账户
在查询用户的时候,要不要把关联的账户查出来?
在查询账户的时候,要不要把关联的用户查出来?

在查询用户时,用户下的账户应该是,什么时候使用,什么时候查询
在查询账户时,账户的所属用户信息应该是随着账户查询时一起查询出来

  • 什么是延迟加载
    在真正使用数据时次发起查询,不使用的时候不查询,按需加载(懒加载)

  • 什么是立即加载
    不管用不用,只要一调用方法,马上发起查询

  • 在对应的四种表关系中:
    一对多,多对多:通常情况下我们都是采用延迟加载
    多对一,一对一:通常情况下我们都是采用立即加载

一对一的延迟加载

  • 配置信息,开启延迟加载
  <!--配置信息-->
    <settings>
        <!--延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--当启用时,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载;反之,每种属性将会按需加载。-->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>
  • mapper文件
	<resultMap id="accountMapDelay" type="account">
        <id property="id" column="id"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
        <!--一对一的关系迎合:配置封装user的内容
        select属性指定的内容:查询用户的唯一标识
        column属性指定的内容:用户根据id查询时,所需要的参数的值
        -->
        <association property="user" column="uid" javaType="user" select="com.hwh.dao.UserDao.findUserById">

        </association>
    </resultMap>
  	<select id="findAll" resultMap="accountMapDelay">
        select * from account
    </select>

一对多的延迟加载

同样需要加上配置信息,如上一对多

  • 主要代码(mapper配置文件)
  <resultMap id="userMapDelay" type="user">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="birthday" column="birthday"></result>
        <result property="sex" column="sex"></result>
        <result property="address" column="address"></result>
        <collection property="accounts" column="id" ofType="account" select="com.hwh.dao.AccountDao.findAccountById">

        </collection>
    </resultMap>

mybatis中的缓存

  • 什么是缓存
    存在于内存中的临时数据
  • 为什么使用缓存
    减少和数据库的交互次数,提高执行效率
  • 什么样的数据能使用缓存,什么样的数据不能使用
    使用于缓存:
    1)经常查询,且不经常改动
    2)数据的正确与否对最终结果影响不大的
    不适用于缓存:
    1)经常改变的数据
    2)数据的正确与否对最终结果影响很大的
    例如:商品的库存,银行的汇率,股市的牌价

mybatis中的一级缓存和二级缓存

一级缓存

它指的是mybatis中SqlSession对象的缓存
当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供一块区域中
该区域的结构是一个Map,当我们再次查询相同的数据时,mybatis会先去SqlSession中查询是否存在,若存在则直接返回
当SqlSession对象消失时,mybatis的一级缓存也就消失了

  • 清空缓存
    一级缓存SqlSession范围的缓存,当调用SqlSession的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存。
    通过clerCache()方法也可以清空缓存。

二级缓存

它指的是mybatis中SqlSessionFactory对象的缓存,由同一个SqlSessionFactory对象创建SqlSession共享其缓存。
在这里插入图片描述
注意:二级缓存中存储的是数据而不是对象,当需要拿取数据时,会新建一个对象将数据塞入。

  • 二级缓存的使用步骤
    1)让mybatis框架支持二级缓存(在主配置文件中配置setting)
 <setting name="cacheEnabled" value="true"/>

2)让当前的映射文件支持二级缓存(在mampe中配置)

<cache/>

3)让当前的操作支持二级缓存(在select标签中配置)

userCache="true"

mybaits基于注解的配置

主配置文件

<?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="sqlConfig.yml"></properties>

    <typeAliases>
        <!--类名就是别名,不区分大小写-->
        <package name="com.hwh.entity"/>
    </typeAliases>

    <environments default="mysql">
        <environment id="mysql">
            <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>
        <package name="com.hwh.dao"/>
    </mappers>
</configuration>

CRUD操作

 /**
     * 查询所有用户
     */
    @Select("select * from user")
    @Results(id = "userMap",value = {
            @Result(id = true,property = "id",column = "id"),
            @Result(property = "userName",column = "username"),
            @Result(property = "birthday",column = "birthday"),
            @Result(property = "sex",column = "sex"),
            @Result(property = "address",column = "address")
    })
    public List<User> findAllUser();

    /**
     * 通过id查询用户
     * @return
     */
    @Select("select * from user where id=#{id}")
    @ResultMap("userMap")
    public User findUserById(Integer id);

    /**
     * 根据名字模糊查询
     * @param username
     * @return
     */
    @Select("select * from user where username like #{username}")
    public List<User> findUserByName(String username);

    /**
     * 更新用户信息
     * @param user
     */
    @Update("update user set username=#{userName},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}")
    public void updateUser(User user);

    /**
     * 保存数据
     * @param user
     */
    @Insert("insert into user(username,birthday,sex,address) values(#{userName},#{birthday},#{sex},#{address})")
    public void saveUser(User user);

    /**
     * 删除数据
     * @param id
     */
    @Delete("delete from user where id = #{id}")
    public void deleteUser(Integer id);

使用延迟加载,一对一关系

 @Select("select * from account")
    @Results(id="accountMap",value = {
            @Result(id = true,column = "id",property = "id"),
            @Result(column = "uid",property = "uid"),
            @Result(column = "money",property = "money"),
            @Result(property = "user",column = "uid",one = @One(select = "com.hwh.dao.IUserDao.findUserById",fetchType = FetchType.LAZY))
    })
    public List<Account> findAllAccount();

使用延迟加载,一对多关系

 @Select("select * from user")
    @Results(id = "userMapDelay",value = {
            @Result(id = true,property = "id",column = "id"),
            @Result(property = "userName",column = "username"),
            @Result(property = "birthday",column = "birthday"),
            @Result(property = "sex",column = "sex"),
            @Result(property = "address",column = "address"),
            @Result(property = "accounts",column = "id",
                    many = @Many(select = "com.hwh.dao.IAccountDao.findAccountById",
                            fetchType = FetchType.LAZY))
    })
    public List<User> findAll();

基于注解开启二级缓存

1)让mybatis框架支持二级缓存(在主配置文件中配置setting)

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

2)在dao类头部添加注解

@CacheNamespace(blocking = true)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!