MyBatis---缓存-提高检索效率的利器

2023-10-29

目录

让我们来看看官方文档

缓存

一.一级缓存

1.基本介绍  

2.一级缓存

3.一级缓存失效分析

二.二级缓存

1.基本介绍

2.二级缓存快速入门 

2.1快速入门

3.注意事项和使用陷阱

三.Mybatis 的一级缓存和二级缓存执行顺序

四.EhCache 缓存

1.基本介绍

2.配置和使用 EhCache

2.1. 加入相关依赖pom.xml

2.2mybatis-config.xml 仍然打开二级缓存

2.3加入配置文件ehcache.xml

2.4在 XxxMapper.xml 中启用 EhCache , 当然原来 MyBatis 自带的缓存配置就注销了

2.5测试

3.EhCache 缓存-细节说明


让我们来看看官方文档

缓存

MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制。 为了使它更加强大而且易于配置,我们对 MyBatis 3 中的缓存实现进行了许多改进。

默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行:

<cache/>

基本上就是这样。这个简单语句的效果如下:

  • 映射语句文件中的所有 select 语句的结果将会被缓存。
  • 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
  • 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
  • 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
  • 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
  • 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

提示 缓存只作用于 cache 标签所在的映射文件中的语句。如果你混合使用 Java API 和 XML 映射文件,在共用接口中的语句将不会被默认缓存。你需要使用 @CacheNamespaceRef 注解指定缓存作用域。

这些属性可以通过 cache 元素的属性来修改。比如:

<cache
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="true"/>

这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。

可用的清除策略有:

  • LRU – 最近最少使用:移除最长时间不被使用的对象。
  • FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
  • SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
  • WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。

默认的清除策略是 LRU。

flushInterval(刷新间隔)属性可以被设置为任意的正整数,设置的值应该是一个以毫秒为单位的合理时间量。 默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调用语句时刷新。

size(引用数目)属性可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。默认值是 1024。

readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false。

提示 二级缓存是事务性的。这意味着,当 SqlSession 完成并提交时,或是完成并回滚,但没有执行 flushCache=true 的 insert/delete/update 语句时,缓存会获得更新。

一.一级缓存

1.基本介绍  

基本说明
1. 默认情况下, mybatis 是启用一级缓存的 / 本地缓存 /local Cache ,它是 SqlSession 级别的。
2. 同一个 SqlSession 接口对象调用了相同的 select 语句 , 会直接从缓存里面获取,而不是再
去查询数据库
一级缓存原理图【简单追一下源码 , 后面还会详细的 Debug

图的解析:

        客户端/浏览器发出一个请求的时候,控制器会先去Executor中去查询Local Cache去查有没有,如果有就会直接返回给客户端/浏览器,没有就会去数据库中去拿,同时也会放到 Local Cache中,下一次在查询这个数据的时候就会直接从Local Cache中获取。

2.一级缓存

当我们第 1 次查询 id=1 Monster 后,再次查询 id=1 monster 对象 , 就会直接
从一级缓存获取 , 不会再次发出 sql

3.一级缓存失效分析

1. 关闭 sqlSession 会话后 , 再次查询,会到数据库查询 , 修改 MonsterMapperTest.java,
试一级缓存失效情况
 //测试一级缓存,失效
    //关闭sqlSession会话后 , 一级缓存失效
    @Test
    public void level1CacheTest2() {

        //查询id=3的monster
        Monster monster = monsterMapper.getMonsterById(3);
        System.out.println("monster=" + monster);

        //关闭sqlSession, 一级缓存失效
        if (sqlSession != null) {
            sqlSession.close();
        }

        //因为关闭了sqlSession,所以需要重新初始化sqlSession和 monsterMapper
        sqlSession = MyBatisUtils.getSqlSession();
        monsterMapper = sqlSession.getMapper(MonsterMapper.class);
        //再次查询id=3的monster
        System.out.println("--如果你关闭了sqlSession,当你再次查询相同的id时, 仍然会发出sql----");
        Monster monster2 = monsterMapper.getMonsterById(3);
        System.out.println("monster2=" + monster2);

        if (sqlSession != null) {
            sqlSession.close();
        }
    }
2. 当执行 sqlSession.clearCache() 会使一级缓存失效,修改 MonsterMapperTest.java,
试一级缓存失效情况(清除localcache中的缓存)
  //测试一级缓存,失效
    //如果执行sqlSession.clearCache() , 会导致一级缓存失效
    @Test
    public void level1CacheTest3() {

        //查询id=3的monster
        Monster monster = monsterMapper.getMonsterById(3);
        System.out.println("monster=" + monster);


        //执行clearCache
        /**
         * @Override
         *   public void clearCache() {
         *     executor.clearLocalCache();
         *   }
         */
        sqlSession.clearCache();

        //再次查询id=3的monster
        System.out.println("--如果你执行sqlSession.clearCache(),当你再次查询相同的id时, 仍然会发出sql----");
        Monster monster2 = monsterMapper.getMonsterById(3);
        System.out.println("monster2=" + monster2);


        if (sqlSession != null) {
            sqlSession.close();
        }
    }
3. 当对同一个 monster 修改,该对象在一级缓存会失效 , 修改 MonsterMapperTest.java,
试一把
 //测试一级缓存,失效
    //如果修改了同一个对象 , 会导致一级缓存[对象数据]失效
    @Test
    public void level1CacheTest4() {

        //查询id=3的monster
        Monster monster = monsterMapper.getMonsterById(3);
        System.out.println("monster=" + monster);


        //如果修改了同一个对象 , 会导致一级缓存[对象数据]失效
        monster.setName("蚂蚱精");
        monsterMapper.updateMonster(monster);

        //再次查询id=3的monster
        System.out.println("--如果你修改了同一个对象,当你再次查询相同的id时, 仍然会发出sql----");
        Monster monster2 = monsterMapper.getMonsterById(3);
        System.out.println("monster2=" + monster2);


        if (sqlSession != null) {
            sqlSession.commit();//这里需要commit
            sqlSession.close();
        }
    }

二.二级缓存

1.基本介绍

基本介绍
1. 二级缓存和一级缓存都是为了提高检索效率的技术
2. 最大的区别就是作用域的范围不一样,一级缓存的作用域是 sqlSession 会话级别 , 在一次
会话有效,而二级缓存作用域是全局范围,针对不同的会话都有效(不管是哪一个sqlsession都有效)
二级缓存原理图

        客户端发出了一次请求或者说一次会话,这个时候假如你配置了二级缓存,会在CachingExecytor中会先有一个获取二级缓存的动作,在这个二级缓存中看有没有数据(有自带二级缓存和第三方缓存库),查到了直接返回,没有查到就会继续往下走,到我们的一级缓存中去查找,在一次里面找到了也可以直接返回给客户端,没有找到继续去数据库查找。 

2.二级缓存快速入门 

2.1快速入门

1. mybatis-config.xml 配置中开启二级缓存

    <configuration>
        <!-- 这里就是引入 jdbc.properties 文件 -->
        <properties resource="jdbc.properties"/>
        <settings>
            <!-- 开启二级缓存 -->
            <setting name="cacheEnabled" value="true"/>
        </settings>

2.使用二级缓存时 entity 类实现序列化接口 (serializable),因为二级缓存可能使用到序

列化技术

3. 在对应的 XxxMapper.xml 中设置二级缓存的策略

<mapper namespace="com.hong.mapper.MonsterMapper">

    <!--
        1、配置二级缓存: 是mybatis自带
        2、FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
        3. flushInterval 刷新间隔 是毫秒单位 60000 表示 60s
        4. size="512": 引用数目, 属性可以被设置为任意正整数, 默认1024
        5. readOnly="true": (只读)属性可以被设置为 true 或 false: 如果我们只是用于读操作,
        建议设置成 true, 这样可以提示效率, 如果有修改操作,设置成 false, 默认就是false
    -->
    <cache eviction="FIFO" flushInterval="60000"
           size="512" readOnly="true"/>

4.测试

 //测试二级缓存的使用
    @Test
    public void level2CacheTest() {

        //查询id=3的monster
        Monster monster = monsterMapper.getMonsterById(3);
        System.out.println("monster=" + monster);


        //这里老师关闭sqlSession
        if (sqlSession != null) {
            sqlSession.close();
        }

        //重新获取sqlSession
        sqlSession = MyBatisUtils.getSqlSession();
        //重新获取了monsterMapper
        monsterMapper = sqlSession.getMapper(MonsterMapper.class);
        //再次查询id=3的monster
        System.out.println("--虽然前面关闭了sqlSession,因为配置二级缓存, " +
                "当你再次查询相同的id时, 依然不会再发出sql, 而是从二级缓存获取数据----");
        Monster monster2 = monsterMapper.getMonsterById(3);
        System.out.println("monster2=" + monster2);

        Monster monster3 = monsterMapper.getMonsterById(3);
        System.out.println("monster3=" + monster3);

        if (sqlSession != null) {
            sqlSession.close();
        }
    }

3.注意事项和使用陷阱

1. 理解二级缓存策略的参数
<cache eviction="FIFO" flushInterval="30000" size="360" readOnly="true"/>
上面的配置意思如下:
创建了 FIFO 的策略,每隔 30 秒刷新一次,最多存放 360 个对象而且返回的对象被认为是只读的。
eviction :缓存的回收策略
flushInterval: 时间间隔,单位是毫秒,
size :引用数目,内存大就多配置点,要记住你缓存的对象数目和你运行环境的可用内存
资源数目。默认值是 1024
readOnly:true, 只读
2. 四大策略
√ LRU – 最近最少使用的 : 移除最长时间不被使用的对象,它是默认
√ FIFO – 先进先出 : 按对象进入缓存的顺序来移除它们。
√ SOFT – 软引用 : 移除基于垃圾回收器状态和软引用规则的对象。
√ WEAK – 弱引用 : 更积极地移除基于垃圾收集器状态和弱引用规则的对象。
3. 如何禁用二级缓存
3.1mybatis-config.xml
<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
    <!--全局性地开启或关闭所有映射器配置文件中已配置的任何缓存, 默认就是 true-->
    <setting name="cacheEnabled" value="false"/>
</settings>

3.2MonsterMapper.xml

<!--<cache eviction="FIFO" flushInterval="30000" size="360" readOnly="true"/>-->

3.3或者更加细粒度的, 在配置方法上指定

设置 useCache=false 可以禁用当前 select 语句的二级缓存,即每次查询都会发出 sql 去查询,
默认情况是 true ,即该 sql 使用二级缓存。

 注意一般我们不需要去修改,使用默认的即可

4. mybatis 刷新二级缓存的设置

<update id="updateMonster" parameterType="Monster" flushCache="true">
    UPDATE mybatis_monster SET NAME=#{name},age=#{age} WHERE id=#{id}
</update>
insert update delete 操作数据后需要刷新缓存,如果不执行刷新缓存会出现脏读
默认为 true ,默认情况下为 true 即刷新缓存,一般不用修改。

三.Mybatis 的一级缓存和二级缓存执行顺序

一句话:缓存执行顺序是:二级缓存-->一级缓存-->数据库

当我们关闭一级缓存的时候,如果你配置二级缓存,那么一级缓存的数据,会放入到二级缓存
细节说明
1. 不会出现一级缓存和二级缓存中有同一个数据。因为二级缓存 ( 数据 ) 是在一级缓存关闭
之后才有的

2.运行效果 , 可以看到,在一级缓存存在的情况下,依然是先查询二级缓存,但是因为 二级缓存,没有数据, 所以命中率都是 0.0 ,

四.EhCache 缓存

1.基本介绍

1. EhCache 是一个纯 Java 的缓存框架,具有快速、精干等特点
2. MyBatis 有自己默认的二级缓存 ( 前面我们已经使用过了 ) ,但是在实际项目中,往往使用
的是更加专业的第三方缓存产品 作为 MyBatis 的二级缓存 ,EhCache 就是非常优秀的缓存
产品

可以通过一个接口找到第三方缓存库。 

2.配置和使用 EhCache

2.1. 加入相关依赖pom.xml

 <dependencies>
        <!--引入ehcache核心库/jar-->
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache-core</artifactId>
            <version>2.6.11</version>
        </dependency>
        <!--引入需要使用的slf4j-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!--引入mybatis整合ehcache库/jar-->
        <dependency>
            <groupId>org.mybatis.caches</groupId>
            <artifactId>mybatis-ehcache</artifactId>
            <version>1.2.1</version>
        </dependency>
    </dependencies>

2.2mybatis-config.xml 仍然打开二级缓存

<settings>
    <!-- 开启二级缓存,默认就是打开 -->
    <setting name="cacheEnabled" value="true"/>
</settings>

2.3加入配置文件ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
    <!--
       diskStore:为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置。参数解释如下:
       user.home – 用户主目录
       user.dir  – 用户当前工作目录
       java.io.tmpdir – 默认临时文件路径
     -->
    <diskStore path="java.io.tmpdir/Tmp_EhCache"/>
    <!--
       defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策略。只能定义一个。
     -->
    <!--
      name:缓存名称。
      maxElementsInMemory:缓存最大数目
      maxElementsOnDisk:硬盘最大缓存个数。
      eternal:对象是否永久有效,一但设置了,timeout将不起作用。
      overflowToDisk:是否保存到磁盘,当系统宕机时
      timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
      timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
      diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
      diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
      diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
      memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
      clearOnFlush:内存数量最大时是否清除。
      memoryStoreEvictionPolicy:可选策略(清除策略)有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。
      FIFO,first in first out,这个是大家最熟的,先进先出。
      LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
      LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
   -->
    <defaultCache
            eternal="false"
            maxElementsInMemory="10000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="259200"
            memoryStoreEvictionPolicy="LRU"/>

</ehcache>

2.4XxxMapper.xml 中启用 EhCache , 当然原来 MyBatis 自带的缓存配置就注销了

<mapper namespace="com.hong.mapper.MonsterMapper">

    <!--
        1、配置二级缓存: 是mybatis自带
        2、FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
        3. flushInterval 刷新间隔 是毫秒单位 60000 表示 60s
        4. size="512": 引用数目, 属性可以被设置为任意正整数, 默认1024(预存对象的大小和运行环境中可用的内存资源)
        5. readOnly="true": (只读)属性可以被设置为 true 或 false: 如果我们只是用于读操作,
        建议设置成 true, 这样可以提示效率, 如果有修改操作,设置成 false, 默认就是false
    -->
<!--    <cache eviction="FIFO" flushInterval="60000"-->
<!--           size="512" readOnly="true"/>-->

    <!--配置/启用ehcache-->
    <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

2.5测试

 //测试ehCache级缓存
    @Test
    public void ehCacheTest() {

        //查询id=3的monster
        Monster monster = monsterMapper.getMonsterById(3);
        //会发出SQL, 到db查询
        System.out.println("monster=" + monster);

        //这里老师关闭sqlSession, 一级缓存[数据]失效.=> 将数据放入到二级缓存 (ehcache)
        if (sqlSession != null) {
            sqlSession.close();
        }

        //重新获取sqlSession
        sqlSession = MyBatisUtils.getSqlSession();
        //重新获取了monsterMapper
        monsterMapper = sqlSession.getMapper(MonsterMapper.class);
        //再次查询id=3的monster
        System.out.println("--虽然前面关闭了sqlSession,因为配置二级缓存(ehcache), " +
                "当你再次查询相同的id时, 不会再发出sql, 而是从二级缓存(ehcache)获取数据----");
        Monster monster2 = monsterMapper.getMonsterById(3);
        System.out.println("monster2=" + monster2);

        //再次查询id=3的monster, 仍然到二级缓存(ehcache), 获取数据, 不会发出sql
        Monster monster3 = monsterMapper.getMonsterById(3);
        System.out.println("monster3=" + monster3);

        if (sqlSession != null) {
            sqlSession.close();
        }

3.EhCache 缓存-细节说明

如何理解 EhCache MyBatis 缓存的关系
1. MyBatis 提供了一个接口 Cache 【如右图,找到 org.apache.ibatis.cache.Cache ,关联源
码包就可以看到 Cache 接口】
2. 只要实现了该 Cache 接口,就可以作为二级缓存产品和 MyBatis 整合使用 ,Ehcache
是实现了该接口
3. MyBatis 默认情况 ( 即一级缓存 ) 是使用的 PerpetualCache 类实现 Cache 接口的 , 是核心类

4. 当我们使用了 Ehcahce 后,就是 EhcacheCache 类实现 Cache 接口的,是核心类. 

5. 我们看一下源码,发现缓存的本质就是 Map<Object,Object> 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MyBatis---缓存-提高检索效率的利器 的相关文章

  • 如何在Netbeans中插入main方法(快捷方式)

    有时您想运行单个文件来快速测试某些代码 正在输入public static void main String args 每次都很乏味 怎样才能做得更快呢 由于 Netbeans 中预定义的代码模板 这很简单 只需输入psvm并按 Tab 键
  • Android PhoneGap 插件,UI 选项卡栏,调整 WebView 大小

    我正在创建一个美味的 PhoneGap 插件 希望一旦它能被打开 准备好了 插件基本完成了 我只需要一个漂亮的用户界面 相互作用 简而言之 我想创建一个 本机 android 工具栏组件 如果您实现 PhoneGap UIControls
  • Maven 2:如何将当前项目版本打包在WAR文件中?

    我正在使用 Maven 2 构建我的 Java 项目 并且正在寻找一种向用户呈现 pom xml 当前版本号的方法 例如使用 Servlet 或 JSP 据我所知 最好的方法是 Maven 将版本号作为文本文件打包到 WAR 中 这使我能够
  • jvm 次要版本与编译器次要版本

    当运行使用具有相同主要版本但次要版本高于 JVM 的 JDK 编译的类时 JVM 会抛出异常吗 JDK 版本并不重要 类文件格式版本 http blogs oracle com darcy entry source target class
  • Google App Engine with Java - 运行 javac.exe 编译器时出错

    在 Windows XP 上 刚刚下载并解压谷歌应用程序引擎java sdk to C Program Files appengine java sdk 我已经安装了jdk C Program Files Java jdk1 6 0 20
  • 在哪里可以获得有关 Java FitNesse 和 Slim 的一些教程? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Spring3/Hibernate3/TestNG:有些测试给出 LazyInitializationException,有些则没有

    前言 我在单元测试中遇到了 LazyInitializationException 的问题 而且我很难理解它 正如你从我的问题中看到的那样Spring 中的数据库会话 https stackoverflow com questions 13
  • Java 正则表达式 - 字母数字,最多一个连字符,句点或下划线,七个字符长

    我是 Java 正则表达式工具的新手 尽管它们潜力巨大 但我很难完成这项任务 我想编写一个正则表达式来验证遵循以下语法的输入字符串 小写字母和数字的任意组合 仅一个下划线 一个破折号或一个句号 无其他特殊字符 最小长度为 5 我想出了以下解
  • JTable 和 JScrollpane 大小的问题

    我有一个JScrollPane with a JTable在里面 在里面JTable我最初有 3 行 稍后添加行 默认JTable我的 3 行很难看 因为JScrollPane calls getPreferredScrollableVie
  • 有多少种方法可以将位图转换为字符串,反之亦然?

    在我的应用程序中 我想以字符串的形式将位图图像发送到服务器 我想知道有多少种方法可以将位图转换为字符串 现在我使用 Base64 格式进行编码和解码 它需要更多的内存 是否有其他可能性以不同的方式做同样的事情 从而消耗更少的内存 现在我正在
  • 容器中的 JVM 计算处理器错误?

    最近我又做了一些研究 偶然发现了这一点 在向 OpenJDK 团队抱怨之前 我想看看是否有其他人观察到这一点 或者不同意我的结论 因此 众所周知 JVM 长期以来忽略了应用于 cgroup 的内存限制 众所周知 现在从 Java 8 更新某
  • Java-如何将黑白图像加载到二进制中?

    我在 FSE 模式下使用 Java 和 swing 我想将完全黑白图像加载为二进制格式 最好是二维数组 并将其用于基于掩码的每像素碰撞检测 我什至不知道从哪里开始 过去一个小时我一直在研究 但没有找到任何相关的东西 只需将其读入Buffer
  • 线程“main”中的异常 java.lang.StackOverflowError

    我有一段代码 但我无法弄清楚为什么它在线程 main java lang StackOverflowError 中给出异常 这是问题 Given a positive integer n prints out the sum of the
  • 异步迭代器

    我有以下代码 while slowIterator hasNext performLengthTask slowIterator next 由于迭代器和任务都很慢 因此将它们放入单独的线程中是有意义的 这是对迭代器包装器的快速而肮脏的尝试
  • 发生错误。请参阅日志文件 - eclipse juno

    每当我启动 Eclipse Juno 时 都会出现错误 发生错误 请查看日志文件 C Program Files eclipse configuration 1362989254411 log 有的网站说卸载jdk重新安装 我这样做了 但没
  • 我想在java中使用XQuery进行Xml处理

    我想用XQuery用于从 java 中的 Xml 获取数据 但我没有得到需要为此添加哪个 Jar 我在谷歌上搜索了很多 但没有得到任何有用的例子 例如我得到以下链接 https docs oracle com database 121 AD
  • 当您在数组列表上调用remove(object o)时,它如何比较对象?

    当您在 java 中的数组列表上调用remove object o 时 它如何比较对象以找到要删除的正确对象 它使用指针吗 或者它使用 Comparable 接口来比较对象吗 ArrayList remove 依赖于对象的实现Equal方法
  • Java中的回调接口是什么?

    SetObserver 接口的代码片段取自有效的Java 避免过度同步第67条 public interface SetObserver
  • 为什么这个私人浮动字段变为零?

    我有一些奇怪的行为 我很难向自己解释 称为 textureScale 的浮点字段变为零 如果某些代码正在更改该值 则可以解释这一点 然而 我希望能够通过将其设置为 私有最终浮点 来导致构建失败 或者至少是运行时异常 那么无论更改该值都将失败
  • Java:使用 Graph API 在线更新 Sharepoint 上的 docx 文件

    我在使用 Java 在线更新 Sharepoint 上的 docx 文件时遇到问题 首先 我检查了构建 PUT 请求的 URL 此处 并使用此请求 PUT drives drive id items item id content 我首先使

随机推荐

  • XML基本规则(XML语法规则)

    XML基本规则 XML语法规则 1 XML 文档必须包含在一个单一元素中 2 XML 元素不能重叠 必须正确的嵌套 3 不能省去任何结束标记 或者说标记必须成对 4 XML 元素是区分大小写的 也就是大小写敏感 5 XML 文档中的属性有两
  • 源码安装zabbix

    源码安装zabbix 1 zabbix简介 2 zabbix的主要功能 3 监控指标 4 zabbix配置文件 5 服务器端配置文件 6 客户端配置文件 7 部署zabbix 8 先安装apache 8 1 安装开发工具包 8 2 下载ap
  • python使用plt.savefig保存时图片保存不完整,四周留白太多

    问题 今天在给论文添加曲线图 使用matplotlib的savefig函数中遇到图片保存不完整 且留白太多的问题 插入到论文中很难看 左边是在pycharm里的截图 右边是通过savefig保存的图片 代码如下 保存图片 plt savef
  • 怎样在PB中实现文件的拷贝与删除 (转)

    怎样在PB中实现文件的拷贝与删除 转 more 怎样在PB中实现 文件的拷贝与删除 可借助外部 函数 可用 api函数实现 1 文件拷贝 函数声明 FUNCTION boolean CopyFileA ref string cfrom re
  • 安装及使用ceres遇到过的问题

    首先ceres安装及使用需要两个依赖库glog与gflags 这两个库安装时需要注意要么只用apt install要么只用源码编译安装 如果两个都装了用apt purge或者在 usr local lib及 usr local includ
  • 设置Unity的帧率

    问题描述 Xsens接收数据的频率是30Hz 为了接收到正确 完整的数据 要将Unity的帧率换成30帧 第一种方法 点击Editor gt Project Setting gt Quality 将VSync Count那选择Every S
  • 测试框架pytest教程(4)运行测试

    运行测试文件 pytest q test example py 会运行该文件内test 开头的测试方法 该 q quiet标志使输出保持简短 测试类 pytest的测试用例可以不写在类中 但如果写在类中 类名需要是Test开头 非Test开
  • C/C++中使用Base64编码解码(使用boost库)

    Base64是一种用64个字符来表示任意二进制数据的方法 用记事本打开exe jpg pdf这些文件时 我们都会看到一大堆乱码 因为二进制文件包含很多无法显示和打印的字符 所以 如果要让记事本这样的文本处理软件能处理二进制数据 就需要一个二
  • c++判断硬盘是否连接、修改指定盘符、读取配置文件、获取exe路径

    系统 win7 64 编译器 vs2010 mfc对话框程序 工程名 fixde 语言 c 涉及函数 GetPrivateProfileString 读取配置文件内容 类型为string GetDriveType 获取某驱动器状态 GetV
  • w5500 php,[W5500]搭建属于你的家庭网络实时监控

    图9 OV2640 SVGA模式下图像输出时序图 系统上电后 MCU配置OV2640的工作方式 在OV2640准备好图像后 VSYNC会被拉高一段时间 MCU通过PCLK上升沿中断按字节接收图像数据 接下来我们将对OV2640的初始化配置程
  • 编写测试用例的基本方法之边界值

    一般边界值分析是因为程序开发循环体时的取数可能会因为 lt lt 搞错 比如下面代码 for int i 0 i lt 100 i int j i 1 System out println 循环第 j 次 循环地做某件事情 这里的程序是循环
  • 如何点击按钮把光标定位到想要的el-input中

    1 el inpu
  • C语言-结构体面向对象编程技巧

    Keil4 C51工程网址 https yunpan 360 cn surl yrNkQSrCKyc 一 面向对象 面向对象是软件开发方法 是相对于面向过程来讲的 通过把数据与方法组织为一个整体来看待 从更高的层次来进行系统建模 更贴近事物
  • python3 数据类型归纳

    1 简介 1 1 python3 数据类型 类型 含义 示例 int 整型 1 float 浮点型 1 0 bool 布尔值 True或False complex 复数 a bj string 字符串 abc123 list 列表 a b
  • 别被骗了,win10家庭版MMC是无法创建管理单元的

    今天我的PC 是win10家庭版 无法出现gpedit msc 然后下载gpedit msc 后 又出现MMC无法创建管理单元 家庭版是没有组策略和注册表的 家庭版是没有组策略和注册表的 家庭版是没有组策略和注册表的 重要的事情说三遍 下面
  • 长轮询与长连接

    实现即时通讯主要有四种方式 它们分别是轮询 长轮询 comet 长连接 SSE WebSocket 它们大体可以分为两类 一种是在HTTP基础上实现的 包括短轮询 comet和SSE 另一种不是在HTTP基础上实现是 即WebSocket
  • Spring笔记【黑马】

    Spring day01 今日目标 掌握Spring相关概念 完成IOC DI的入门案例编写 掌握IOC的相关配置与使用 掌握DI的相关配置与使用 1 课程介绍 对于一门新技术 我们需要从为什么要学 学什么以及怎么学这三个方向入手来学习 那
  • 三点估算法评估开发工作量

    概述 开发人员在进行开发工作之前都需要给出一个工作量的评估 以便后续的工作任务可以基于该时间进行排期 大多数开发人员评估工作量主要是基于过往的工作经验拍脑袋决定 并会给自己预留出一定的Buffer时间 这样可能的问题就是过度依赖个人的开发经
  • selenium爬虫_selenium爬虫如何避免对isTrusted属性检测?

    1 前言 各位码友 有两天不见 想小码哥了没 哈哈哈 成都疫情在平静9个月之后 又死灰复燃 目前还未找到确切的源头 提醒各位成都的码友一定注意戴口罩 做好自我防护 相信有关部门的防疫措施 一起共渡难关 好了 今天咱们再继续selenium爬
  • MyBatis---缓存-提高检索效率的利器

    目录 让我们来看看官方文档 缓存 一 一级缓存 1 基本介绍 2 一级缓存 3 一级缓存失效分析 二 二级缓存 1 基本介绍 2 二级缓存快速入门 2 1快速入门 3 注意事项和使用陷阱 三 Mybatis 的一级缓存和二级缓存执行顺序 四