Java框架之MyBatis 07-动态SQL-缓存机制-逆向工程-分页插件

简介: Java框架之MyBatis 07-动态SQL-缓存机制-逆向工程-分页插件


MyBatis

  今天大年初一,你在学习!不学习做什么,斗地主...人都凑不齐。学习吧,学习使我快乐!除了诗和远方还有责任,我也想担当,我也想负责,可臣妾做不到啊,怎么办?你说怎么办,为啥人家能做到你做不到,因为人家比你多做了那么一点点。哪一点点?就那么一点点,只要你也多做那么一点点,不就做到了!...就那么一点点呀,我回顾SE去了。万丈高楼平地起,基础打的牢,怕什么狂风暴雨

MyBatis 动态SQL

  MyBatis为了解决通过一些不确定性的条件进行SQL语句的拼接操作的问题, 提供了动态SQL. 具体来说,就是提供了一些标签       等.写出可扩展SQL语句

  MyBatis 采用功能强大的基于 OGNL 的表达式来简化操作

  OGNL( Object Graph Navigation Language )对象图导航语言,这是一种强大的表达式语言,通过它可以非常方便的来操作对象属性。 类似于EL表达式,例:

访问对象属性:              person.name
    调用方法:                     person.getName()
    调用静态属性/方法:     @java.lang.Math@PI    
    调用构造方法:              new com.bean.Person(‘admin’).name
    运算符:                         +,-*,/,%
    逻辑运算符:                  in,not in,>,>=,<,<=,==,!=
    注意:xml中特殊符号如”,>,<等这些都需要使用转义字符

标签

   1)用于完成简单的判断.只有一个属性 test 用于判断条件是否成立

  2) 在SQL语句中添加WHERE关键字, 作用:去掉 where 后面第一个条件前面的 and / or 。

<select id="getBook" resultType="main.beans.Book">
        SELECT id,title,author,price
        FROM books
        <where>
            <if test="id != null"> and id= #{id}if>
            <if test="title != null"> and title = #{title}if>
        where>
    select>

  3)  : 可以在条件判断完的SQL语句的前后 添加内容 或者去掉指定的内容. 去掉第一个或最后一个

prefix: 添加前缀  prefixOverrides: 去掉前缀
    suffix: 添加后缀  suffixOverrides: 去掉后缀
<delete id="deleteBook">
        DELETE FROM books
        <trim prefix="WHERE" suffixOverrides="and">
            <if test="id != null">id = #{id} andif>
            <if test="title != null">itle = #{title} andif>
        trim >
    delete>

  4)   :在修改的操作中, 去掉SQL语句中多出的逗号,即在sql语句中最后句可能多出的逗号

<update id="updateBook">
        UPDATE books
        <set>
            <if test="title != null">title = #{title},if>
            <if test="author != null">author = #{author},if>
        set>
        where id = #{id}
    update>

  5) 标签是用于抽取可重用的sql片段,将使用频繁的SQL片段抽取出来,不仅仅只提取整条sql语句,字段也可以提取

    id:指定被提取的 sql 片段唯一标识被引用

    引用:在任何需要插入此 sql 片段的语句中使用  引入即可

<sql id="bookFields">
        id,title,author,price,sales,stock,img_path
    sql>
    <insert id="insertBook" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO books (<include refid="bookFields">include>)
        VALUES(#{id},#{title},#{author},#{price},#{sales},#{stock},#{imgPath})
    insert>

  6)   : 用于分支判断,最终只会满足其中的一个分支.  类似于 switch case 语句.

<select id="selectBookPrice" resultType="main.beans.Book">
        SELECT <include refid="bookFields">include>
        FROM books
        <where>
            <choose>
                <when test="id != null">id = #{id}when>
                <otherwise>price > #{price}otherwise>
            choose>
        where>
    select>

  7) : 主要用于循环迭代

 

collection: 要迭代的集合
      item: 当前从集合中迭代出的元素赋值的变量
      open: 开始字符
      close:结束字符
      separator: 指定元素与元素之间的分隔符
      index:
        迭代的是List集合: index表示当前元素的下标
        迭代的Map集合:  index表示当前元素的 key

  注意:此操作属于批量操作需在 properties 配置的 url 中添加 allowMultiQueries=true 开启批处理

<select id="getBooks" resultType="main.beans.Book">
        SELECT <include refid="bookFields">include>
        FROM books where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")" >
            #{id}
        foreach>
    select>

MyBatis 缓存机制

    MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。缓存可以极大的提升查询效率

    MyBatis系统中默认定义了两级缓存:一级缓存、二级缓存

    默认情况下,只有一级缓存(SqlSession级别的缓存,也称为本地缓存)开启。

    二级缓存需要手动开启和配置,他是基于namespace级别的缓存。为了提高扩展性。MyBatis定义了缓存接口Cache,支持第三方缓存。

一级缓存

  1) 一级缓存(local cache), 即本地缓存, 作用域默认为sqlSession。每个sqlSession对象都有自己的一级缓存,相互独立不共享。当  Session flush 或 close 后, 该 Session 中的所有 Cache 将被清空。

  2) 本地缓存不能被关闭, 但可以调用 clearCache() 来清空本地缓存, 或者改变缓存的作用域.

  3) 在mybatis3.1之后, 可以配置本地缓存的作用域. 在 mybatis.xml 中配置

  4) 一级缓存的工作机制,同一次会话期间只要查询过的数据都会保存在当前SqlSession的一个Map中

     key: hashCode+查询的SqlId+编写的sql查询语句+参数

缓存机制:

  基于相同sqlSession多次查询,每次查询都会先从缓存中获取数据,如果缓存中没获取到数据,则从数据库中获取数据,之后,将数据存放到一级缓存。

一级缓存的失效问题

  1)不同的SqlSession对应不同的一级缓存

  2)同一个SqlSession但是查询条件不同

  3)同一个SqlSession两次查询期间执行了任何一次增删改操作

    增删改操作,会默认清空缓存。

  4)同一个SqlSession两次查询期间手动清空了缓存

总结:当同一 SqlSession 多次查询同一语句时,且中间未有增删改或手动刷新、关闭、清空 clearCache() 过缓存,便会直接从缓存中取数据。若开启了二级缓存则会先从二级缓存读取,若二级缓存里没有再去一级缓存读取,如果只想从一级缓存中读取可在对应 <select> 配置属性中设置  useCache="false" 来关闭当前二级缓存,注意增删改不涉及缓存机制

二级缓存

 默认关闭,使用需要满足三个条件才被开启

 二级缓存:namespace级别缓存(sqlSessionFacotry)级别的缓存,作用域更广但是需要在 sqlSessionFacotry 内的 sqlSession 提交或关闭以后才会生效。即才会将 sqlSession 中的缓存存到二级缓存中。

     二级缓存使用的步骤:

   ①   全局配置文件中开启二级缓存<setting name="cacheEnabled" value="true"/>

   ②   在需要使用二级缓存的映射文件( <mapper> 配置文件)使用 cache 标签配置缓存<cache />

   ③   注意:POJO需要实现 Serializable 接口

 <cache> 标签属性

   ①   eviction=“LRU”:缓存回收策略:默认的是 LRU。

       LRU – 最近最少使用的:移除最长时间不被使用的对象。

       FIFO – 先进先出:按对象进入缓存的顺序来移除它们。

       SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。

       WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

    ②   flushInterval:刷新间隔,单位毫秒

       默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新

   ③   size:引用数目,正整数

       代表缓存最多可以存储多少个对象,太大容易导致内存溢出

   ④   readOnly:只读,默认是 false。虽然设为true能提高效率但是为了安全,因此不需设置此项

   ⑤ type:引入缓存类库(第三方缓存)

 其他相关属性设置

   1) 全局setting的 cacheEnable:

      配置二级缓存的开关,一级缓存一直是打开的。

   2) select标签的 useCache 属性:

         配置这个 select 是否使用二级缓存。一级缓存一直是使用的

   3) sql标签的 flushCache 属性:

      增删改默认 flushCache=true。sql执行以后,会同时清空一级和二级缓存。

      查询默认 flushCache=false。

   4) sqlSession.clearCache():只是用来清除一级缓存。

 二级缓存机制

   基于相同sqlSessionFactory下,多次查询,优先去二级缓存中获取数据,二级缓存获取不到数据,去一级缓存中获取数据,一级缓存中也获取不到数据,直接去数据库中查询数据。

   查询后,将数据直接存放一级缓存,提交或关闭 sqlSession 时,才将一级缓存中的数据,缓存到二级缓存中。

EhCache第三方缓存

 EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider

 整合EhCache缓存的步骤:

   ① 导入ehcache包,以及整合包,日志包

     ehcache-core-2.6.8.jar、mybatis-ehcache-1.0.3.jar

     slf4j-api-1.6.1.jar、slf4j-log4j12-1.6.2.jar

   ② 编写 ehcache.xml 配置文件

   ③ 配置 cache 标签

 

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

  第三方缓存的使用机制,同二级缓存一样也需要 setting 的 cacheEnable 设置为 true 并且实现序列化接口 Serializable  

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
 <!-- 磁盘保存路径 -->
 <diskStore path="F:\code\mysql\ehcache" />
 <defaultCache  
   maxElementsInMemory="1000"  
   maxElementsOnDisk="10000000"
   eternal="false"  
   overflowToDisk="true"  
   timeToIdleSeconds="120"
   timeToLiveSeconds="120"  
   diskExpiryThreadIntervalSeconds="120"
   memoryStoreEvictionPolicy="LRU">
 </defaultCache>
</ehcache>

MyBatis 逆向工程

 MyBatis Generator: 简称MBG,是一个专门为MyBatis框架使用者定制的代码生成器,可以快速的根据表生成对应的映射文件,接口,以及bean类。支持基本的增删改查,以及QBC风格的条件查询。但是表连接、存储过程等这些复杂sql的定义需要我们手工编写

Mybatis使用逆向工程步骤

 1.加入逆向工程相关的jar包.

   mybatis-generator-core-1.3.2.jar

 2.配置逆向工程的配置文件: mbg.xml ==> 生成的版本 、 javaBean、Mapper接口、映射文件的生成策略 、 分析的表 .

   mbg.xml 文件直接放在项目工程根目录下方便路径配置

<?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>
    <!--
            targetRuntime: 执行生成的逆向工程的版本
                  MyBatis3Simple: 生成基本的CRUD
                  MyBatis3: 生成带条件的CRUD
   -->
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <!--        数据库连接设置-->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/bookstore?allowMultiQueries=true"
                        userId="root"
                        password="12345">
        </jdbcConnection>
        <!-- javaBean的生成策略 bean的存放路径-->
        <javaModelGenerator targetPackage="main.beans" targetProject=".\src">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!-- SQL映射文件的生成策略 mapper.xml文件路径-->
        <sqlMapGenerator targetPackage="main.mapper" targetProject=".\conf">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
        <!-- Mapper接口的生成策略 mapper接口路径-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="main.mapper" targetProject=".\src">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
        <!-- 逆向分析的表 表名对应的javaBean名-->
        <table tableName="books" domainObjectName="Book"></table>
        <table tableName="users" domainObjectName="User"></table>
    </context>
</generatorConfiguration>

 3.执行生成代码.

@Test
    public void testMbg() throws Exception {
        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        File configFile = new File("mbg.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);
    }

PageHelper 分页插件

 PageHelper 是MyBatis中非常方便的第三方分页插件。内部提供了 PageHelper 和 PageInfo 两个非常强大的类库。

使用步骤

 1) 导入相关包 pagehelper-5.0.0.jar 和 jsqlparser-0.9.5.jar

 2) 在MyBatis全局配置文件中配置分页插件,注意标签位置不可乱序

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

 3) 使用:在查询出集合之前开启分页查询

Page<Book> page = PageHelper.startPage(3,2 );
        List<Book> books = mapper.selectByExample(bookExample);
        //查询出当前为第3页,每页显示2条的图书信息,其还可得到更多页码相关值
        books.forEach((book -> System.out.println("book = " + book)));
        PageInfo<Book> info = new PageInfo<>(books,3);
        System.out.println("=============获取详细分页相关的信息=================");
        System.out.println("当前页: " + info.getPageNum());
        System.out.println("总页码: " + info.getPages());
        System.out.println("总条数: " + info.getTotal());
        System.out.println("每页显示的条数: " + info.getPageSize());
        System.out.println("是否是第一页: " + info.isIsFirstPage());
        System.out.println("是否是最后一页: " + info.isIsLastPage());
        System.out.println("是否有上一页: " + info.isHasPreviousPage());
        System.out.println("是否有下一页: " + info.isHasNextPage());
        System.out.println("============分页逻辑===============");
        int[] nums = info.getNavigatepageNums();
        for (int num : nums) {
            System.out.println("num = " + num);
        }

 Page对象

   在查询之前通过PageHelper.startPage(页码,条数)设置分页信息,该方法返回Page对象

 PageInfo对象

   在查询完数据后,使用PageInfo对象封装查询结果,可以获取更详细的分页信息以及可以完成分页逻辑

SSM配置文件

相关文章
|
14天前
|
Java
轻松上手Java字节码编辑:IDEA插件VisualClassBytes全方位解析
本插件VisualClassBytes可修改class字节码,包括class信息、字段信息、内部类,常量池和方法等。
66 6
|
20天前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
1月前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
37 10
|
2月前
|
SQL XML Java
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
文章介绍了MyBatis中动态SQL的用法,包括if、choose、where、set和trim标签,以及foreach标签的详细使用。通过实际代码示例,展示了如何根据条件动态构建查询、更新和批量插入操作的SQL语句。
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
|
2月前
|
安全 Oracle Java
edge浏览器加载java插件
edge浏览器加载java插件
|
1月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
118 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
1月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
56 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
1月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
351 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
|
1月前
|
SQL Java 数据库连接
mybatis使用二:springboot 整合 mybatis,创建开发环境
这篇文章介绍了如何在SpringBoot项目中整合Mybatis和MybatisGenerator,包括添加依赖、配置数据源、修改启动主类、编写Java代码,以及使用Postman进行接口测试。
17 0
mybatis使用二:springboot 整合 mybatis,创建开发环境
|
1月前
|
Java 数据库连接 API
springBoot:后端解决跨域&Mybatis-Plus&SwaggerUI&代码生成器 (四)
本文介绍了后端解决跨域问题的方法及Mybatis-Plus的配置与使用。首先通过创建`CorsConfig`类并设置相关参数来实现跨域请求处理。接着,详细描述了如何引入Mybatis-Plus插件,包括配置`MybatisPlusConfig`类、定义Mapper接口以及Service层。此外,还展示了如何配置分页查询功能,并引入SwaggerUI进行API文档生成。最后,提供了代码生成器的配置示例,帮助快速生成项目所需的基础代码。
下一篇
无影云桌面