Mybatis

1Mybatis

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。1、Mybatis是一个半ORM(对象关系映射)框架,底层封装了JDBC,是程序员在开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。使得程序员可以花更多的精力放到业务开发中。另外,程序员直接编写原生态sql,严格控制sql执行性能,灵活度高。2、MyBatis 可以使用简单的 XML文件 或注解方式来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。3、通过xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过java对象和 statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。(从执行sql到返回result的过程)。

1.1为什么要是有mybatis框架

1、基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
2、与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;
3、很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。
4、能够与Spring很好的集成;
5、提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。

1.2.如何使用Mybatis

(1)引入Mybatis和mysql的jar包

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>

        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>

(2) 创建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="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <!--数据源的配置:name的值固定  value的值要根据客户自己修改-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver" />
                <property name="url"    value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai" />
                <property name="username" value="root" />
                <property name="password" value="123456" />
            </dataSource>
        </environment>
    </environments>
</configuration>

(3) 创建mybatis和数据库的映射文件.作用: 映射实体和表之间的映射关系。

<?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">
<!--namespace:命名空间
       可以随便起名,但是后期我们要求命名空间的值必须和所对应的dao相同
-->
<mapper namespace="user">
    <!--查询 根据id查询用户信息
          select标签用于查询的标签
             id:标签的唯一标识
             resultType: 定义返回的类型 把sql查询的结果封装到哪个实体类钟
         #{id}===表示占位符等价于?  这是mybatis框架的语法
    -->
    <select id="findOne" resultType="com.hzk.entity.User">
        select * from tb_user where userid=#{id}
    </select>
</mapper>
注意:==把映射文件注册到配置文件上==     mybatis.xml上
<!--注册映射文件-->
    <mappers>
        <!--resource:引用资源文中的映射文件 url:网络上的映射文件-->
         <mapper resource="mapper/UserMapper.xml" />
    </mappers>

(4) 测试mybatis

package com.hzk.test01;

import com.hzk.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.Test;

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


/**
 1. @author hzk
 2. @date 2022/6/1 8:36
 */
public class Test01 {
    @Test
    public void insert() throws IOException {
        //读取Mybatis配置内容
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        //创建factory对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
        //将数据库的各种操作封装进session
        SqlSession session = factory.openSession();
        User user = new User();
        user.setUsername("gfc");
        user.setRealname("郭富城");
        session.insert("user.add",user);
        session.commit();
        session.close();
    }
    @Test
    public void del() throws IOException {
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = factory.openSession();
        session.delete("user.del",7);
        session.commit();
        session.close();
    }
    @Test
    public void update()throws Exception{
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = factory.openSession();
        User user = new User();
        user.setUserid(7);
        user.setRealname("帅哥");
        user.setUsername("shuaige");
        session.update("user.up",user);
        session.commit();
        session.close();
    }
    @Test
    public void findAll() throws IOException {
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = factory.openSession();
        List<Object> objects = session.selectList("user.findAll");
        System.out.println(objects);
    }
}

(1)SqlSessionFactoryBuilder【全局的对象】
每一个MyBatis的应用程序的入口是:SqlSessionFactoryBuilder。它的作用是通过XML配置文件创建Configuration对象(当然也可以在程序中自行创建),然后通过build方法创建SqlSessionFactory对象。
(2)SqlSessionFactory【全局的对象】
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。SqlSessionFactory是由SqlSessionFactoryBuilder 从 XML 配置文件或通过Java的方式构建出 的实例,主要功能是创建SqlSession(会话)对象;SqlSessionFactory对象一个必要的属性是Configuration对象;SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,建议使用单例模式或者静态单例模式。一个SqlSessionFactory对应配置文件中的一个环境(environment),如果你要使用多个数据库就配置多个环境分别对应一个SqlSessionFactory。
(3) SqlSession
作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能。SqlSession通过调用api的Statement ID找到对应的MappedStatement对象。SqlSession是一个接口,它有2个实现类,分别是DefaultSqlSession(默认使用)以及SqlSessionManager;默认使用DefaultSqlSession,它有两个必须配置的属性:Configuration和Executor,SqlSession通过内部存放的执行器(Executor)来对数据进行CRUD。由于不是线程安全的,所以SqlSession对象的作用域需限制方法内;每一次操作完数据库后都要调用close对其进行关闭,官方建议通过try-finally来保证总是关闭SqlSession。

2.出错点

(1).不要使用关键字:mybatis
在这里插入图片描述
(2).没有把映射文件注册到配置文件上。
在这里插入图片描述
(3).xml格式不正确
在这里插入图片描述

3.lombok插件

它可以帮你生成实体类的get和set方法 而且可以帮你生成构造方法。重写toString方法
(1) idea安装lombok插件
在这里插入图片描述

(2) 工程中引入lombok依赖

<!--lombok的依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
        </dependency>

(3)在实体类上添加lombok注解

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Stu {
    private Integer id;
    private String name;
    private Integer cid;
    private Cla cla;
}

4. 使用mybatis完成crud

<?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="user">
    <insert id="add" parameterType="u">
        insert into user values (null ,#{username},#{realname})
    </insert>
    <delete id="del" parameterType="int">
        delete from user where userid=#{id}
    </delete>
    <update id="up" parameterType="u">
        update user set username=#{username},realname=#{realname} where userid=#{userid}
    </update>
    <select id="findAll" resultType="u">
        select * from user
    </select>
</mapper>

测试

package com.hzk.test01;

import com.hzk.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.Test;

import java.io.IOException;
import java.io.Reader;

/**
 * @author hzk
 * @date 2022/5/31 15:29
 */

public class Test01 {
    public static void main(String[] args) throws IOException {
        //1.读取mybatis配置文件的内容----未来不需要写tomcat 解析配置文件
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        //2. 获取SqlSessionFactory对象
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(reader);

        //3. 获取SqlSession对象----封装了对数据库操作的各种方法
        SqlSession session=factory.openSession();

        //调用查询一个结果的接口
        //String statement, 命名空间+id----指向sql标签
        // Object parameter 需要实参
        User user = session.selectOne("user.findById", 5);
        System.out.println(user);
        //4.关闭
        session.close();

    }
    @Test
    public void add() throws IOException {
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = factory.openSession();
        User user = new User();
        user.setUsername("lxd");
        user.setRealname("刘大姐");
        session.insert("user.add",user);
        session.commit();
        session.close();
    }
    @Test
    public void delete()throws Exception{
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = factory.openSession();
        session.delete("user.delete",1);
        session.commit();
        session.close();
    }
}

5.mybatis优化

5.1 为实体类起别名

mybatis.xml配置文件

 <typeAliases>
        <!--单独为某个实体类起别名 -->
        <typeAlias type="com.hzk.entity.User" alias="u"/>
        <!--为指定包下的实体类起别名该别名就是实体类名-->
        <package name="com.hzk.entity"/>
    </typeAliases>

5.2 添加sql日志

(1)添加日志的jar.

<!--log4f-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

(2) 添加日志的文件配置–log4j.properties

log4j.rootLogger=DEBUG, Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

在这里插入图片描述

6.实际开发中的模式

接口结合映射文件一起用
1.创建一个接口

package com.hzk.dao;

import com.hzk.entity.Stu;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * @author hzk
 * @date 2022/6/2 8:57
 */
public interface StuDao {
    public void add(@Param("name") String name, @Param("age") Integer age,@Param("sex") String sex);
    public Stu findOne(Integer id);
    public void delete(Integer id);
    public void update(Stu stu);
    public List<Stu> findAll(@Param("stuName") String stuName,@Param("stuAge") Integer strAge);
}

2.创建映射文件

<?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">
        <!--namespace必须和接口的路径一致-->
<mapper namespace="com.hzk.dao.StuDao">
<!--解决字段名与实体类属性名不相同的冲突,问题: 查询时返回一个null,或者某个列没有值
可以有两种解决办法:
第一种: 为查询的列起别名,而别名和属性名一致。
第二种: 使用resultMap完成列和属性之间的映射关系。-->
    <resultMap id="StuMap" type="com.hzk.entity.Stu">
        <id column="stuId" property="id"/>
        <result column="stuName" property="name"/>
        <result column="stuAge" property="age"/>
        <result column="stuSex" property="sex"/>
    </resultMap>
    <!--id必须和接口中的方法名一致-->
    <insert id="add">
        insert into stu values (null ,#{name},#{age},#{sex})
    </insert>
    <update id="update">
        update stu set stuName=#{name},stuAge=#{age},stuSex=#{sex} where stuId=#{id}
    </update>
    <delete id="delete">
        delete from stu where stuid=#{id}
    </delete>
    <select id="findOne" resultMap="StuMap">
        select * from stu where stuid=#{id}
    </select>
    <select id="findAll" resultMap="StuMap">
        select * from stu
        <where>
            <if test="stuName!=null and stuName!=''">
                and stuName=#{stuName}
            </if>
            <if test="stuAge!=null">
                and stuAge=#{stuAge}
            </if>
        </where>
    </select>
</mapper>

7.动态Sql查询

在这里插入图片描述

<select id="findByCondition02" resultType="com.ykq.entity.Account">
        select * from account where 1=1
        <choose>
             <when test="name!=null and name!=''">
                 and  name=#{name}
             </when>
            <when test="money!=null">
                and  money=#{money}
            </when>
            <otherwise>
                and isdeleted=0
            </otherwise>
        </choose>
    </select>

我们观察到上面的sql都加了 where 1=1 ,如果不使用where 1=1 那么你的动态sql可能会出错。 我们能不能不加where 1=1呢! 可以 那么我们就可以使用where标签,作用:可以自动为你添加where关键字,并且可以帮你去除第一个and |or

select id="findAll" resultMap="StuMap">
    select * from stu
    <where>
        <if test="stuName!=null and stuName!=''">
            and stuName=#{stuName}
        </if>
        <if test="stuAge!=null">
            and stuAge=#{stuAge}
        </if>
    </where>
</select>

7.1 set标签

这个配合if标签一起用,一般用在修改语句。如果传递的参数值为null,那么应该不修改该列的值

<update id="update">
        update user
        <set>
            <if test="username!=null and username!=''">
                username=#{name},
            </if>
            <if test="password!=null">
                password=#{pwd}
            </if>
        </set>
        where userid=#{id}
    </update>

7.2 foreach标签

<!-- select * from user where id in(25,28,29,30)
        如果你使用的为数组array  如果你使用的为集合 那么就用list
        collection:类型
        item:数组中每个元素赋值的变量名
        open: 以谁开始
        close:以谁结束
        separator:分割符
    -->
    <select id="findByid" resultMap="UserMapper">
        select * from user where userid in
        <foreach collection="array" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </select>

删除

 <delete id="batchDelete">
        delete from user where userid in
        <foreach collection="array" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </delete>

添加

<insert id="add">
        insert into user values
        <foreach collection="list" item="user" separator=",">
            (null,#{user.name},#{user.pwd})
        </foreach>
    </insert>

7.2 sql片段

 <sql id="baseColumn">
        sid,sname,classid,cid,cname
    </sql>
    <select id="findOne" resultMap="StuMapper">
        select <include refid="baseColumn"/>
        from t_stu s join t_class c on s.classid=c.cid where s.sid=${id}
    </select>

8. mybatis映射文件处理特殊字符

   第一种:转义标签 &nbsp; &lt;  
   第二种: <![CDATA[sql]]>
 <select id="findByMinMax" resultMap="UserMapper">
        select <include refid="baseColumn"/>
        from user <![CDATA[where userid >#{min} and userid<#{max}]]>
    </select>

9. mybatis完成模糊查询。

使用字符串函数 完成拼接 concat或者使用${}

<select id="findByLike" resultMap="UserMapper">
        select <include refid="baseColumn"/>
        from user where username like /*'%${name}%'*/ concat('%',#{name},'%')
    </select>

通过观察: 发现使用${}实际上是字符串拼接,它不能防止sql注入, 而#{}它是预编译,它可以防止sql注入问题,#{}实际使用的PreparedStatement.
总结:
动态sql标签: if where (choose when otherwise) set foreach sql
处理特殊字符: <![CDATA[sql]]> 转义符
模糊查询: concat(‘’,#{},‘’) ${}

10.连表查询

实体类

package com.hzk.entity;

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

/**
 * @author hzk
 * @date 2022/6/4 22:44
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Stu {
    private Integer sid;
    private String sname;
    private Integer classid;

    private Cla cla;
}

package com.hzk.entity;

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

/**
 * @author hzk
 * @date 2022/6/4 22:45
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Cla {
    private Integer cid;
    private String cname;
}

xml

<?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.hzk.dao.StuDao">
    <resultMap id="StuMapper" type="com.hzk.entity.Stu">
        <id column="sid" property="sid"/>
        <result column="sname" property="sname"/>
        <result column="classid" property="classid"/>
        <association property="cla" javaType="com.hzk.entity.Cla" autoMapping="true">
        </association>
    </resultMap>
    <sql id="baseColumn">
        sid,sname,classid,cid,cname
    </sql>
    <select id="findOne" resultMap="StuMapper">
        select <include refid="baseColumn"/>
        from t_stu s join t_class c on s.classid=c.cid where s.sid=${id}
    </select>

</mapper>

测试类

package com.hzk.test01;

import com.hzk.dao.StuDao;
import com.hzk.entity.Stu;
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.Test;

import java.io.Reader;

/**
 * @author hzk
 * @date 2022/6/4 22:43
 */
public class Test02 {
    @Test
    public void findOne() throws Exception{
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = factory.openSession();
        StuDao stuDao = session.getMapper(StuDao.class);
        Stu one = stuDao.findOne(2);
        System.out.println(one);
        session.commit();
        session.close();
    }
}

结果:
在这里插入图片描述
在这里插入图片描述

11.分页插件

select * from 表名 [where 条件] limit (page-1)*pageSize, pageSize;

page: 当前页码
pageSize: 每页显示的条数
(1)引入pageHelper的jar包

<!--引入pageHelper-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.1.11</version>
        </dependency>

(2)mybatis中设置pageHelper的拦截器

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

(3)使用pageHelper

 //设置分页属性pageNum:显示第几页 pageSize:每页显示的条数
        PageHelper.startPage(2,1);
        List<User> list = mapper.findAll();
        //把查询的结果封装到pageInfo类中.
        PageInfo<User> pageInfo = new PageInfo<User>(list);
        System.out.println("总条数:"+pageInfo.getTotal());
        System.out.println("总页数:"+pageInfo.getPageNum());

12.mybatis的代码生成器–generator

http://mybatis.org/generator/
(1)引入mybatis-generator的依赖jar包。

<dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.4.0</version>
        </dependency>

(2)generator的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <!--找到你的mysql驱动jar的位置-->
    <classPathEntry location="D:\AAA\repMaven\mysql\mysql-connector-java\8.0.20\mysql-connector-java-8.0.20.jar" />

    <context id="DB2Tables" targetRuntime="MyBatis3">
        <!--抑制注释-->
        <commentGenerator>
            <property name="suppressAllComments" value="true" />
        </commentGenerator>
        <!--数据库的配置信息-->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai"
                        userId="root"
                        password="123456">
        </jdbcConnection>

        <javaTypeResolver >
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>
        <!--java实体类的配置-->
        <javaModelGenerator targetPackage="com.hzk.entity" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!--映射文件的配置-->
        <sqlMapGenerator targetPackage="mapper"  targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>
        <!--dao数据访问层的配置-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.hzk.dao"  targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>
        <!--数据库表和实体的映射关系
            schema:数据库名称
            tableName:表名
            domainObjectName:实体类名

            enableUpdateByExample:是否生成复杂的修改操作
        -->
        <table schema="myvatis" tableName="tbl_user" domainObjectName="User"
            enableCountByExample="false" enableDeleteByExample="false"
            enableUpdateByExample="false" enableSelectByExample="false">

        </table>

    </context>
</generatorConfiguration>

(3)运行你的配置文件

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author hzk
 * @date 2022/6/6 18:52
 */
public class Test01 {
    public static void main(String[] args) throws Exception {
        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        File configFile = new File("generator.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);
    }
}

引入的jar包

<dependency>
            <groupId>repMaven.org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.4.0</version>
        </dependency>

13. mybatis的缓存

13.1什么是缓存

缓存是存在于内存中的临时数据。
mysql数据库中的数据存在----表—>磁盘上。 查询—程序IO读取磁盘的数据—添加–io向磁盘添加数据.

13.2 缓存的好处

使用缓存减少和数据库的交互次数,提高执行效率。
在这里插入图片描述

13.3什么样的数据适合或不适合放入缓存

适合: 经常查询并且不经常改变的;
数据的正确与否对最终结果影响不大的;
不适合: 经常改变的数据数据的正确与否对最终结果影响很大的;—数据安全性要求不高。
例如:商品的库存,银行的汇率,股市的牌价;

13.4 mybatis也支持缓存

mybatis支持两种缓存
(1)一级缓存----基于SqlSession级别的缓存。默认一级缓存是开启的,不能关闭。
(2)二级缓存–基于SqlSessionFactory级别的缓存,它可以做到多个SqlSession共享数据。默认它是关闭。需要手动开启。

13.4 .1演示一级缓存
 //一级缓存---必须查询同一个数据
    @Test
    public void test01() throws Exception{
        Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(resourceAsReader);
        SqlSession session=factory.openSession();

        UsersMapper mapper = session.getMapper(UsersMapper.class);
        //第一次查询编号=2的用户信息--缓存不能命中,则向数据库查询-发送sql语句、把查询的结果放入缓存中。
        //底层就是一个hashmap---(2,user)
        Users users = mapper.selectByPrimaryKey(2);
        System.out.println(users);
        Users users1 = mapper.selectByPrimaryKey(2);
        System.out.println(users1);

    }

    //一级缓存---基于sqlSession完成的一级缓存
    @Test
    public void test02() throws Exception{
        Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(resourceAsReader);
        SqlSession session=factory.openSession();

        UsersMapper mapper = session.getMapper(UsersMapper.class);
        //第一次查询编号=2的用户信息--缓存不能命中,则向数据库查询-发送sql语句、把查询的结果放入缓存中。
        //底层就是一个hashmap---(2,user)
        Users users = mapper.selectByPrimaryKey(2);
        System.out.println(users);
        session.close();

        //开启新的SqlSession
        SqlSession session1=factory.openSession();
        UsersMapper mapper1 = session1.getMapper(UsersMapper.class);
        Users users1 = mapper1.selectByPrimaryKey(2);
        System.out.println(users1);
    }
13.4 .1演示二级缓存

(1)开启二级缓存

<settings>
        <!--开启二级缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>

(2)在映射文件中使用二级缓存

 <!--使用二级缓存 这里面的所有查询都使用了二级缓存-->
  <cache/>

(3)实体一定要实现序列化接口
在这里插入图片描述
(4)测试二级缓存

//二级缓存的测试
    @Test
    public void test03() throws Exception{
        Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(resourceAsReader);
        SqlSession session=factory.openSession();

        UsersMapper mapper = session.getMapper(UsersMapper.class);
        //第一次查询编号=2的用户信息--缓存不能命中,则向数据库查询-发送sql语句、把查询的结果放入缓存中。
        //底层就是一个hashmap---(2,user);
        //查询的结果放入一级缓存和二级缓存。 如果二级缓存能命中
        Users users = mapper.selectByPrimaryKey(2);
        System.out.println(users);
        session.close();
        //开启新的SqlSession
        SqlSession session1=factory.openSession();
        UsersMapper mapper1 = session1.getMapper(UsersMapper.class);
        Users users1 = mapper1.selectByPrimaryKey(2);
        System.out.println(users1);
    }

查询顺序: 二级缓存----一级缓存----数据库。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值