mybatis延迟加载 | 缓存机制详解

2023-05-16

八,Mybatis延迟加载

1.概念

延迟加载:
就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载。

好处:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。

坏处:因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时间,所以可能造成用户等待时间变长,造成用户体验下降。

2.开启mybatis延迟加载策略

<!-- 开启延迟加载的支持 -->
<settings> 
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="aggressiveLazyLoading" value="false"/>
</settings>

3.需求

1)查询账户信息,但是不显示对应的用户信息
2)查询用户信息,但是不显示对应的账户信息

4.使用assocation实现一对一延迟加载策略

AccountDao

public interface AccountDao {
    List<Account> findAll();
}

AccountMapper.xml

<mapper namespace="com.atguigu.dao.AccountDao">
  <!-- 建立对应关系 -->
  <resultMap type="com.atguigu.domain.Account" id="accountMap">
    <id column="id" property="id"/>
    <result column="uid" property="uid"/>
    <result column="money" property="money"/>

    <association property="user" javaType="com.atguigu.domain.User"
                 column="uid" select="com.atguigu.dao.UserDao.findById">
    </association>
  </resultMap>

  <select id="findAll" resultMap="accountMap">
    select * from account
  </select>
</mapper>

UserDao

//根据id查询
User findById(Integer id);

UserMapper.xml

<!-- 抽取重复的语句代码片段 -->
<sql id="defaultSql">
  select * from user
</sql>

<!--根据id查询-->
<select id="findById" parameterType="int" resultType="com.atguigu.domain.User">
  <include refid="defaultSql"/>
  where  id = #{uid}
</select>

测试类

/**
 * 查询账户信息,不查询对应的用户信息。
*/
@Test
public void test(){
  List<Account> all = accountDao.findAll();
  for(Account account: all){
    System.out.println(account);
  }
}

5.使用collection实现多对一延迟加载

UserDao

//查询所有用户
List<User> findAll();

UserMapper.xml

<mapper namespace="com.atguigu.dao.AccountDao">   
	<resultMap type="com.atguigu.domain.User" id="userMap">
      <id column="id" property="id"></id>
      <result column="username" property="username"/>
      <result column="address" property="address"/>
      <result column="sex" property="sex"/>
      <result column="birthday" property="birthday"/>
      <!-- collection 是用于建立一对多中集合属性的对应关系
        ofType 用于指定集合元素的数据类型
        select 是用于指定查询账户的唯一标识(账户的 dao 全限定类名加上方法名称)
        column 是用于指定使用哪个字段的值作为条件查询
        -->
      <collection property="accounts" ofType="com.atguigu.domain.Account"
                  select="com.atguigu.dao.AccountDao.findById"
                  column="id">
      </collection>
    </resultMap>
    <select id="findAll" resultMap="userMap">
      select * from user;
    </select>
</mapper>

AccountDao

//根据id查询
Account findById(Integer id);

AccountMapper.xml

<select id="findById" resultType="com.atguigu.domain.Account" parameterType="int">
  select * from account where uid=#{id};
</select>

测试类

//查询账户信息,不查询对应的用户信息。
@Test
public void test(){
  List<User> all = userDao.findAll();
//        for(User user: all){
//            System.out.println(user);
//        }
}

九,缓存机制

1.简介

  1. 什么是缓存[ Cache ]?
    • 存在内存中的临时数据。
    • 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
  2. 为什么使用缓存?
    • 减少和数据库的交互次数,减少系统开销,提高系统效率。
  3. 什么样的数据能使用缓存?
    • 经常查询并且不经常改变的数据。

2.Mybatis缓存

  • MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。
  • MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存
    • 默认情况下,只有一级缓存开启。 (SqlSession级别的缓存, 也称为本地缓存)
    • 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
    • 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存

3.一级缓存

  • 一级缓存也叫本地缓存:
    • 与数据库同一次会话期间查询到的数据会放在本地缓存中。
    • 以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库;
    • 一级缓存是 SqlSession 级别的缓存,只要 SqlSession 没有 flush 或 close,它就存在。

1)一级缓存的步骤

  1. 开启日志功能。
<settings>
  <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
  1. 测试在一个Session中查询两次相同记录

userDao

/**
  * 根据id查询用户信息
  * 验证一级缓存,SQLSession作用范围
  */
 User queryById(@Param("id") int id);

userMapper.xml

<select id="queryById" resultType="User">
   select * from user where id = #{id}
 </select>

测试类

@Test
 public void testQueryById(){
   SqlSession sqlSession = MybatisUtils.getSqlSession();
   UserMapper mapper = sqlSession.getMapper(UserMapper.class);
 
   User user = mapper.queryById(1);
   System.out.println(user);
   System.out.println("============");
   User user1 = mapper.queryById(1);
   System.out.println(user1);
   System.out.println(user== user1);
 
   sqlSession.close();
 }

结论

虽然在上面的代码中我们查询了两次,但最后只执行了一次数据库操作,这就是 Mybatis 提供给我们的一级缓存在起作用了。因为一级缓存的存在,导致第二次查询 id 为 1 的记录时,并没有发出 sql 语句从数据库中查询数据,而是从一级缓存中查询。

缓存失效的情况

  1. 查询不同的东西
  2. 增删改操作,可能会改变原来的数据,所以必会刷新缓存
    在这里插入图片描述
  3. 查询不同的Mapper.xml
  4. 手动清理缓存
sqlSession.clearCache();//手动清理缓存。

小结:一级缓存默认是开启的,只在一次SqlSession中有效,也就是拿到连接到关闭连接这个区间段。

2)一级缓存的清空

    一级缓存是 SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存。
    第一次发起查询用户 id 为 1 的用户信息,先去找缓存中是否有 id 为 1 的用户信息,如果没有,从数据库查询用户信息。得到用户信息,将用户信息存储到一级缓存中。
    如果 sqlSession 去执行 commit 操作(执行插入、更新、删除),清空 SqlSession 中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。
    第二次发起查询用户 id 为 1 的用户信息,先去找缓存中是否有 id 为 1 的用户信息,缓存中有,直接从缓存中获取用户信息。

4.二级缓存

  • 二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存。
  • 基于namespace级别的缓存,一个名称空间,对应一个二级缓存;
  • 工作机制
    • 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
    • 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;
    • 新的会话查询信息,就可以从二级缓存中获取内容;
    • 不同的mapper查出的数据会放在自己对应的缓存(map) 中;
    二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个SqlSession 
    可以共用二级缓存,二级缓存是跨 SqlSession 的。

二级缓存的使用步骤

主配置文件中开始全局缓存

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

在要使用二级缓存的Mapper中开启

<mapper namespace="com.kuang.mapper.UserMapper">

    <!--在当前Mapper.xml中使用二级缓存-->
    <!--<cache/>-->
    <!--官网写的-->
    <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>

  	<!-- 在此处将userCache属性设置为true -->
    <select id="queryById" resultType="User" useCache="true">
        select * from user where id = #{id}
    </select>
</mapper>
  • 标签表示当前这个 mapper 映射将使用二级缓存,区分的标准就看 mapper 的 namespace 值。
  • 将 UserDao.xml 映射文件中的标签中设置 useCache=”true”代表当前这个 statement 要使用二级缓存,如果不使用二级缓存可以设置为 false。

注意:针对每次查询都需要最新的数据 sql,要设置成 useCache=false,禁用二级缓存。

测试二级缓存

@Test
public void testQueryById1(){
  SqlSession sqlSession1 = MybatisUtils.getSqlSession();
  SqlSession sqlSession2 = MybatisUtils.getSqlSession();

  UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
  User user = mapper1.queryById(1);
  System.out.println(user);
  sqlSession1.close();

  UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
  User user1 = mapper2.queryById(1);
  System.out.println(user1);
  sqlSession2.close();

  System.out.println(user==user1);
}

在这里插入图片描述

注意

  • 当我们在使用二级缓存时,所缓存的类一定要实现 java.io.Serializable 接口,这种就可以使用序列化方式来保存对象。否则会报java.io.NotSerializableException

小结

  • 只要开启了二级缓存,在同一个Mapper下就有效;
  • 所有的数据都会先放在一级缓存中;
  • 只有当会话提交,或者关闭的时候,才会提交到二级缓存中。

5.缓存原理图

在这里插入图片描述

6.自定义缓存 - ehcache

Ehcache是一种广泛使用的开源Java分布式缓存。主要是面向通用缓存。

使用步骤

导入jar包

    <dependency>
      <groupId>org.mybatis.caches</groupId>
      <artifactId>mybatis-ehcache</artifactId>
      <version>1.1.0</version>
    </dependency>

Mapper.xml配置文件

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

ehcache.xml

<?xml version="1.0" encoding= "UTF-8"?>
<ehcache xmIns:xsi="http://www.w3.org/2001/XMLSchema-instance"
			xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
			updateCheck="false">
	<!--
		diskStore:为缓存路径。ehcache 分为内存和磁盘两级,此属性定义磁盘的缓存位置。参数解释如下:
		user.home - 用户主目录
		user.dir - 用户当前工作目录
		java.io.tmpdir - 默认临时文件路径
	-->
	<diskStore path="./tmpdir/Tmp_EhCache"/>

	<defaultCache
		eternal="false"
		maxElementsInMemory="10000"
		overflowToDisk="false"
		diskPersistent="false" 
		timeToIdleSeconds="1800"
		timeToLiveSeconds="259200"
		memoryStoreEvictionPolicy="LRU"/>
		
	<cache
		name="cloud_user"
		eternal="false"
		maxElementsInMemory="5000"
		overflowToDisk="false"
		diskPersistent="false"
		timeToIdleSeconds="1800"
		timeToLiveSeconds="1800"
		memoryStoreEvictionPolicy="LRU"/>

	<!--
		defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策略。只能定义一个。
	-->	
	<!--
		name:缓存名称。
		maxELementsInMemory:缓存最大数目
		maxELementsOnDisk:硬盘最大缓存个数。
		eternal:对象是否永久有效,一旦设置I,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(较少使用)。
		clear0nFLush:内存数量最大时是否清除。
		memoryStoreEvictionPolicy:可选策略有: LRU (最近最少使用,默认策略)、FIFO (先进先出)、LFU (最少访问次数)。
		FIFO, first in first out,这个是大家最熟的,先进先出。
		LFU,Less Frequently Used, 就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
		LRU,Least Recently Used, 最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
		-->
</ehcache>

Mybatis后续的学习:
mybatis 概述 | 配置文件详解:https://blog.csdn.net/weixin_45606067/article/details/107368570
mybatis 事务 | 动态SQL | 多表查询:https://blog.csdn.net/weixin_45606067/article/details/107368642
mybatis 注解开发版:https://blog.csdn.net/weixin_45606067/article/details/107368743
mybatis 逆向工程的使用:https://blog.csdn.net/weixin_45606067/article/details/107368781
pageHelper分页技术:https://blog.csdn.net/weixin_45606067/article/details/107368847


如果有收获!!! 希望老铁们来个三连,点赞、收藏、转发
创作不易,别忘点个赞,可以让更多的人看到这篇文章,顺便鼓励我写出更好的博客
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mybatis延迟加载 | 缓存机制详解 的相关文章

  • 集合框架(3):set | HashSet | LinkedHashSet | TreeSet的底层源码

    文章目录 一 Set练习题 xff1a 在list内去除重复数据值 二 HashSet三 LinkHashSet四 TreeSet1 自然排序2 定制排序 文章链接Java语法https blog csdn net weixin 45606
  • 单例设计模式

    目录 一 设计模式1 理解2 常用设计模式 23种经典的设计模式 二 单例设计模式1 概念 xff1a 2 如何实现 xff1f 3 饿汉式和懒汉式的区别4 应用场景 xff1a 三 模板方法的设计模式1 解决的问题2 举例3 应用场景 一
  • PageHelper实现分页详细版、整合SSM应用

    在项目开发中我们经常要实现分页技术 xff0c 传统的开发过于繁琐 xff0c 这里我们讲解MyBatis中引进的PageHelper实现分页 简单易懂 xff0c 便于上手 xff01 xff01 xff01 参照官网 完成以下分页技术的
  • 最详细IDEA 的安装、配置与使用

    目录 IDEA 的安装 配置与使用一 IntelliJ IDEA 介绍1 IntelliJ IDEA 介绍2 官网 xff1a 3 IDEA 的下载地址 xff1a 官网 4 官网提供的详细使用文档 xff1a 二 windows 下载安装
  • 对遗传算法(GA)的一些理解

    目录 1 遗传算法的原理 2 遗传算法的主要流程 3 对遗传算法中的选择 编码 交叉及变异的理解 1 遗传算法的原理 基因以染色体为载体在种群间得以传播 xff0c 而基因在相当程度上决定了个体的表现型 性状 xff0c 这个传播过程常常伴
  • 最详细IDEA 常用配置、布局说明

    目录 一 创建 Java 工程 xff0c 分析页面布局1 设置显示常见的视图2 工程界面展示3 查看项目配置 二 常用配置 以idea 2019为例 1 设置主题2 设置字体大小 xff08 1 xff09 非代码窗口设置UI样式和字体
  • Springboot整合阿里云短信服务

    文章目录 开通阿里云了解阿里云用户权限操作开通阿里云短信服务添加短信模板添加签名 Springboot整合短信到项目中1 创建一个SpringBoot的项目2 导入依赖3 配置文件4 主启动类5 工具类6 控制器7 业务层8 测试 最好有S
  • 使用JS实现表单验证

    目录 表单页面展示FormCheck jsp CSS样式Register css JavaScript代码FormCheck js 效果图展示 平时我们在注册账号的时候经常看到有提示xxx不得法 xff0c 请重新填写字样 xff0c 本文
  • 对Spring深入的理解 | 概念的总结

    一 Spring的概述 官网 xff1a https spring io projects spring framework overview 官方下载地址 xff1a https docs spring io spring docs 4
  • Spring AOP详解

    1 简述 AOP 概念 AOP xff1a Aspect Oriented Program xff0c 面向 方面 切面的编程 xff1b Filter 过滤器 也是一种 AOP AOP 是一种新的方法论 xff0c 是对传统 OOP Ob
  • Spring IOC详解

    一 IOC的基本概念 1 简述 IOC 概念 IOC Invert Of Control xff0c 控制反转 也成为 DI 依赖注入 其思想是反转资源获取的方向 传统的资源查找方式要求组件向容器发起请求查找资源 作为回应 容器适时的返回资
  • Spring 声明式事务

    文章目录 1 回顾事务2 spring的事务管理3 Spring事务的种类4 基于XML的事务配置1 使用说明2 代码如下 5 基于注解的事务配置1 使用说明2 代码如下 6 基于XML和注解的事务配置代码如下 7 64 Transacti
  • Spring 依赖注入详解

    一 IOC 依赖注入 1 什么是Spring的依赖注入 依赖注入 xff0c 是IOC的一个方面 xff0c 是个通常的概念 xff0c 它有多种解释 这概念是说你不用创建对象 xff0c 而只需要描述它如何被创建 你不在代码里直接组装你的
  • JDBC(1) API详细说明

    目录 一 JDBC概述1 什么是 JDBC2 JDBC API3 JDBC 程序编写步骤 二 用使用 JDBC API1 引入 JDBC 驱动程序1 1 如何获取 JDBC 驱动程序1 2 在Java Project 项目应用中添加数据库驱
  • JDBC(2) 工具类 | PreparedStatement详细说明

    目录 一 JDBC 工具类使用 JDBC API 操作数据库的基本步骤编写工具类 JDBCUtils 二 PreparedStatement1 PreparedStatement 概述2 Statement 的不足3 PreparedSta
  • python: image.paste函数的理解

    目录 image paste函数 举例说明 xff1a image paste函数 python中PIL库中的paste函数的作用为将一张图片覆盖到另一张图片的指定位置去 函数的声明如下 xff1a def paste self im bo
  • JDBC(3)实现通用的增删改查方法

    编写通用的增删改查方法 不明白的可以看代码中注释 xff0c 写的很详细 1 通用的增删改 span class token comment 通用的更新数据库的方法 xff1a insert update delete 语句时 span s
  • JDBC(4)DBCP数据源 | C3P0 数据源

    1 DBCP 数据源 DBCP 是 Apache 软件基金组织下的开源连接池实现 xff0c 该连接池依赖该组织下的另一个开源系统 xff1a Common pool 如需使用该连接池实现 xff0c 应在系统中增加如下两个 jar 文件
  • JDBC(5)DBUtils类详解

    1 DbUtils 类 DbUtils xff1a 提供如关闭连接 装载 JDBC 驱动程序等常规工作的工具类 xff0c 里面的所有方法都是静态的 主要方法如下 xff1a public static void close throws
  • 验证码实现 - html页面版

    前言 图片验证码是我们日常经常用到的 xff0c 本文将介绍如何实现以及其原理 xff0c 并没有过多注重css样式 xff0c 单纯实现验证码功能 如果对滑块验证码感兴趣的可以看这篇文章 xff1a 滑块验证码实现及原理 如果对验证码实现

随机推荐

  • 验证码实现 - 工具类调用版

    前言 图片验证码是我们日常经常用到的 xff0c 本文将介绍如何实现以及其原理 xff0c 以注册页面为例实现功能 如果对滑块验证码感兴趣的可以看这篇文章 xff1a 滑块验证码实现及原理 如果对验证码实现感兴趣的可以看这篇文章 xff1a
  • 滑块验证码实现

    前言 滑块验证码也是生活中常见的 xff0c 本文会介绍如何实现以及原理 如果对验证码实现感兴趣的可以看这篇文章 xff1a 验证码实现 html页面版 如果对验证码实现感兴趣的可以看这篇文章 xff1a 验证码实现 工具类调用版 代码实现
  • MySQL(1)的使用 | SQL

    目录 MySQL 的使用1 启动和停止服务方式一 xff1a 图形化方式方式二 xff1a 命令行 2 客户端登录方式一 xff1a MySQL 自带客户端方式二 xff1a 命令行方式三 xff1a 可视化工具 SQL1 SQL 的语言规
  • MySQL(2)DDL详解

    一 DDL 1 1 操作 Database 注意 xff1a database 不能改名 一些可视化工具可以改名 xff0c 它是建新库 xff0c 把所有表复制到新库 xff0c 再删旧库完成的 1 创建数据库 create databa
  • MySQL(4)运算符 | 关联查询详解

    一 MySQL 的运算符 xff08 1 xff09 算术运算符 xff1a 43 xff08 除也可以写成 div xff08 取模可以写成 mod xff09 xff08 2 xff09 比较运算符 xff1a 61 gt gt 61
  • MySQL(5)条件查询 | 单行函数 | 事务详解

    一 select 的 的 5 个子句 1 where 条件查询 从原表中的记录中进行筛选 2 group by 分组查询 很多情况下 xff0c 用户都需要进行一些汇总操作 xff0c 比如统计整个公司的人数或者统计每一个部门的人数等 聚合
  • python:tqdm——进度条显示操作

    在代码执行过程中 xff0c 如果想要看到代码的实时运行进度 xff0c 可以使用tqdm库来进行进度条可视化 tqdm的安装 xff1a pip install tqdm 举一个常用参数的使用例子 xff1a from tqdm impo
  • MySQL(3)DML详解

    一 DML 数据操纵语言 xff08 DML xff09 DML 用于插入 修改 删除数据记录 xff0c 包括如下 SQL 语句 xff1a INSERT xff1a 添加数据到数据库中 UPDATE xff1a 修改数据库中的数据 DE
  • 泛型的使用与通配符

    文章目录 泛型的使用1 jdk1 5新特性泛型2 为什么要使用泛型 xff1f 3 在集合中使用泛型 自定义泛型结构 xff1a 泛型类 xff0c 泛型接口 xff1b 泛型方法泛型类被某个类继承自定义泛型的注意点泛型方法 泛型在继承方面
  • IO流详解

    文章目录 File类1 File类的使用2 如何创建File类的实例3 常用方法 IO流1 概述2 节点流 字符流FileReader读入数据的操作FileWriter写出数据的操作使用FileReader和FileWriter实现文本文件
  • TCP的三次握手和四次挥手详解

    1 三次握手 三次握手 xff08 Three way Handshake xff09 其实就是指建立一个TCP连接时 xff0c 需要客户端和服务器总共发送3个包 进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常 指定自
  • 多线程 / 高并发 高频考点

    1 stop 和 suspend 方法为何不推荐使用 xff1f 反对使用stop xff0c 是因为它不安全 它会解除由线程获取的所有锁定 xff0c 而且如果对象处于一种不连贯状态 xff0c 那么其他线程能在那种状态下检查和修改它们
  • Synchronized、Lock、ReentrantLock详解

    一 synchronized的缺陷 synchronized是java中的一个关键字 xff0c 也就是说是java语言内置的特性 那么为什么会出现Lock呢 xff1f 如果一个代码块被synchronized修饰了 xff0c 当一个线
  • HashMap在JDK1.7和1.8中的实现

    一 初窥HashMap HashMap是应用更广泛的哈希表实现 xff0c 而且大部分情况下 xff0c 都能在常数时间性能的情况下进行put和get操作 要掌握HashMap xff0c 主要从如下几点来把握 xff1a jdk1 7中底
  • JDK8新特性(Lambda、Stream、Optional)

    文章目录 1 为什么使用Lambda表达式 xff1f 2 Lambda表达式的使用3 函数式 xff08 functional xff09 接口4 方法引用与构造器引用方法引用的使用构造器引用的使用 5 Stream APIStream
  • Java JUC

    Java JUC 1 Java JUC简介 在 Java 5 0 提供了 java util concurrent xff08 简称 JUC xff09 包 xff0c 在此包中增加了在并发编程中很常用的实用工具类 xff0c 用于定义类似
  • mybatis 概述 | 配置文件详解

    一 xff0c Mybatis入门和自定义Mybatis 1 框架概述 1 xff09 什么是框架 它是我们软件开发中的一套解决方案 xff0c 不同的框架解决的是不同的问题 使用框架的好处 xff1a 框架封装了很多的细节 xff0c 使
  • PyTorch:torch.zeros_like()的用法

    作用 xff1a 产生一个与a相同shape的Tensor 举例 xff1a import torch a 61 torch rand 3 4 产生一个3行4列的0 1的随机Tensor b 61 torch zeros like a 产生
  • mybatis 事务 | 动态SQL | 多表查询

    四 xff0c Mybatis连接池和事务深入 1 连接池 在 WEB 课程中学习过连接池技术 xff0c 而在 Mybatis 中也有连接池技术 xff0c 但是它采用的是自己的连接池技术 在 Mybatis 的主配置文件中 xff0c
  • mybatis延迟加载 | 缓存机制详解

    八 xff0c Mybatis延迟加载 1 概念 延迟加载 xff1a 就是在需要用到数据时才进行加载 xff0c 不需要用到数据时就不加载数据 延迟加载也称懒加载 好处 xff1a 先从单表查询 xff0c 需要时再从关联表去关联查询 x