MyBatis

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

MyBatis 动态SQL

  MyBatis为了解决通过一些不确定性的条件进行SQL语句的拼接操作的问题, 提供了动态SQL. 具体来说,就是提供了一些标签 <if> <where> <trim> <set> <choose> <foreach> 等.写出可扩展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) <if>:用于完成简单的判断.只有一个属性 test 用于判断条件是否成立

  2) <where>:在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) <trim> : 可以在条件判断完的SQL语句的前后 添加内容 或者去掉指定的内容. 去掉第一个或最后一个

    prefix: 添加前缀  prefixOverrides: 去掉前缀

    suffix: 添加后缀  suffixOverrides: 去掉后缀

    <delete id="deleteBook">
DELETE FROM books
<trim prefix="WHERE" suffixOverrides="and">
<if test="id != null">id = #{id} and</if>
<if test="title != null">itle = #{title} and</if>
</trim >
</delete>

  4) <set>  :在修改的操作中, 去掉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片段抽取出来,不仅仅只提取整条sql语句,字段也可以提取

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

    引用:在任何需要插入此 sql 片段的语句中使用 <include refid="id标识"></include> 引入即可

    <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) <choose> <when> <otherwise> : 用于分支判断,最终只会满足其中的一个分支.  类似于 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) <foreach>: 主要用于循环迭代

      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配置文件

Java框架之MyBatis 07-动态SQL-缓存机制-逆向工程-分页插件的更多相关文章

  1. java web(七): mybatis的动态sql和mybatis generator自动生成pojo类和映射文件

    前言: MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据 不同条件拼接 SQL 语句的痛苦.例如拼接时要确保不能忘记添加必要的空格,还 ...

  2. Java框架之Mybatis(二)

    本文主要介绍 Mybatis(一)之后剩下的内容: 1 mybatis 中 log4j的配置 2 dao层的开发(使用mapper代理的方式) 3 mybatis的配置详解 4 输入输出映射对应的类型 ...

  3. MyBatis的动态SQL详解

    MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑,本文详解mybatis的动态sql,需要的朋友可以参考下 MyBatis 的一个强大的特性之一通常是它 ...

  4. mybatis中的.xml文件总结——mybatis的动态sql

    resultMap resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功. 如果sql查询字段名和pojo的属性名不一致,可以通过re ...

  5. MyBatis的动态SQL详解-各种标签使用

    MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑. MyBatis中用于实现动态SQL的元素主要有: if choose(when,otherwise) ...

  6. 9、SpringBoot+Mybatis整合------动态sql

    开发工具:STS 前言: mybatis框架中最具特色的便是sql语句中的自定义,而动态sql的使用又使整个框架更加灵活. 动态sql中的语法: where标签 if标签 trim标签 set标签 s ...

  7. Java-MyBatis:MyBatis 3 动态 SQL

    ylbtech-Java-MyBatis:MyBatis 3 动态 SQL 1.返回顶部 1. 动态 SQL MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架 ...

  8. MyBatis 示例-动态 SQL

    MyBatis 的动态 SQL 包括以下几种元素: 详细的使用参考官网文档:http://www.mybatis.org/mybatis-3/zh/dynamic-sql.html 本章内容简单描述这 ...

  9. mybatis 使用动态SQL

    RoleMapper.java public interface RoleMapper { public void add(Role role); public void update(Role ro ...

随机推荐

  1. linux进程 阻塞和非阻塞操作

    在我们看全功能的 read 和 write 方法的实现之前, 我们触及的最后一点是决定何时使 进程睡眠. 有时实现正确的 unix 语义要求一个操作不阻塞, 即便它不能完全地进行下去. 有时还有调用进 ...

  2. linux 安装一个中断处理

    如果你想实际地"看到"产生的中断, 向硬件设备写不足够; 一个软件处理必须在系统中配 置. 如果 Linux 内核还没有被告知来期待你的中断, 它简单地确认并忽略它. 中断线是一个 ...

  3. The Preliminary Contest for ICPC Asia Nanjing 2019ICPC南京网络赛

    B.super_log (欧拉降幂) •题意 定一个一个运算log*,迭代表达式为 给定一个a,b计算直到迭代结果>=b时,最小的x,输出对m取余后的值 •思路 $log*_{a}(1)=1+l ...

  4. APK签名替换检测

    APK二次打包的危害 APK二次打包是Android应用安全风险中的一部分, 一般是通过反编译工具向应用中插入广告代码与相关配置,再在第三方应用市场.论坛发布.打包党对移动App带来的危害有以下几种: ...

  5. HDU - 5015 233 Matrix (矩阵快速幂)

    In our daily life we often use 233 to express our feelings. Actually, we may say 2333, 23333, or 233 ...

  6. 裁剪nutch 8步骤

    裁剪nutch 8步骤

  7. Java 8 默认接口实现及其他语言特性

    一.为什么有默认接口实现 1.由于Java 8的API在现存的接口上引入了非常多的新方法(如List接口上的sort方法).在原有语法基础上,如Guava和Apache Commons这样的框架都需要 ...

  8. Jquery为动态添加的元素添加事件

    $("tbody").on("click","button", function() { var text = $(this).parent ...

  9. 20191031-6beta week 1/2 Scrum立会报告+燃尽图 04

    此作业要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/9914 git地址:https://e.coding.net/Eustia/ ...

  10. 【题解】P1712 [NOI2016]区间(贪心+线段树)

    [题解]P1712 [NOI2016]区间(贪心+线段树) 一个observe是,对于一个合法的方案,将其线段长度按照从大到小排序后,他极差的来源是第一个和最后一个.或者说,读入的线段按照长度分类后, ...