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. import()函数

    简介 import命令会被 JavaScript 引擎静态分析,先于模块内的其他模块执行(叫做”连接“更合适).所以,下面的代码会报错. // 报错 if (x === 2) { import MyM ...

  2. JavaScript实现版本号比较

    /* * JavaScript实现版本号比较 * 传入两个字符串,当前版本号:curV:比较版本号:reqV * 调用方法举例:Version('5.12.3','5.12.2'),将返回true * ...

  3. Nutch网页抓取速度优化

    Nutch网页抓取速度优化 Here are the things that could potentially slow down fetching 1) DNS setup 2) The numb ...

  4. There is already an open DataReader associated with this Connection which must be closed first EF

    废话不多说,直接 上图,及解决办法.不过问题还不是太清楚到底为什么会出现这个情况..........  

  5. 【原创】(十四)Linux内存管理之page fault处理

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  6. CUBA 框架2019年回顾

    对于 CUBA 框架,2019年最重要的事件应该是 CUBA 7 的发布, 这是 CUBA 框架的一次巨大进化,CUBA 7 引入了一系列全新的 UI 和更灵活的数据访问机制,并且发布了基于 Inte ...

  7. asp.net保留两位小数

    1.System.Globalization.NumberFormatInfo provider = new System.Globalization.NumberFormatInfo();provi ...

  8. 洛谷$2014$ 选课 背包类树形$DP$

    luogu Sol 阶段和状态都是树形DP板子题,这里只讲一下背包的部分(转移)叭 它其实是一个分组背包模型,具体理解如下: 对于一个结点x,它由它的子结点y转移而来 在子结点y为根的树中可以选不同数 ...

  9. JVM性能监测工具——VisualVM

    Java本身自带了有好几个jvm监测工具,其中jconsole和jvisualvm这两个工具具有图形化界面,可以监测到cpu.类.线程.堆等一些参数,而且具有远程监控的能力. 启动:打开cmd命令窗口 ...

  10. Spring MVC拦截器配置

    Spring MVC拦截器配置 (1)自定义拦截器 package learnspringboot.xiao.other; import org.springframework.web.servlet ...