Java相关面试题总结+答案(七)
【Hibernate】
113. 为什么要使用 hibernate?
- hibernate 是对 jdbc 的封装,大大简化了数据访问层的繁琐的重复性代码。
- hibernate 是一个优秀的 ORM 实现,很多程度上简化了 DAO 层的编码功能。
- 可以很方便的进行数据库的移植工作。
- 提供了缓存机制,是程序执行更改的高效。
114. 什么是 ORM 框架?
ORM(Object Relation Mapping)对象关系映射,是把数据库中的关系数据映射成为程序中的对象。
使用 ORM 的优点:提高了开发效率降低了开发成本、开发更简单更对象化、可移植更强。
115. hibernate 中如何在控制台查看打印的 SQL 语句?
在 Config 里面把 hibernate. show_SQL 设置为 true 就可以。但不建议开启,开启之后会降低程序的运行效率。
116. hibernate 有几种查询方式?
三种:hql、原生 SQL、条件查询 Criteria。
117. hibernate 实体类可以被定义为 final 吗?
实体类可以定义为 final 类,但这样的话就不能使用 hibernate 代理模式下的延迟关联提供性能了,所以不建议定义实体类为 final。
118. 在 hibernate 中使用 Integer 和 int 做映射有什么区别?
Integer 类型为对象,它的值允许为 null,而 int 属于基础数据类型,值不能为 null。
119. hibernate 是如何工作的?
- 读取并解析配置文件。
- 读取并解析映射文件,创建 SessionFactory。
- 打开 Session。
- 创建事务。
- 进行持久化操作。
- 提交事务。
- 关闭 Session。
- 关闭 SessionFactory。
120. get()和 load()的区别?
- 数据查询时,没有 OID 指定的对象,get() 返回 null;load() 返回一个代理对象。
- load()支持延迟加载;get() 不支持延迟加载。
121. 说一下 hibernate 的缓存机制?
hibernate 常用的缓存有一级缓存和二级缓存:
一级缓存:也叫 Session 缓存,只在 Session 作用范围内有效,不需要用户干涉,由 hibernate 自身维护,可以通过:evict(object)清除 object 的缓存;clear()清除一级缓存中的所有缓存;flush()刷出缓存;
二级缓存:应用级别的缓存,在所有 Session 中都有效,支持配置第三方的缓存,如:EhCache。
122. hibernate 对象有哪些状态?
- 临时/瞬时状态:直接 new 出来的对象,该对象还没被持久化(没保存在数据库中),不受 Session 管理。
- 持久化状态:当调用 Session 的 save/saveOrupdate/get/load/list 等方法的时候,对象就是持久化状态。
- 游离状态:Session 关闭之后对象就是游离状态。
123. 在 hibernate 中 getCurrentSession 和 openSession 的区别是什么?
- getCurrentSession 会绑定当前线程,而 openSession 则不会。
- getCurrentSession 事务是 Spring 控制的,并且不需要手动关闭,而 openSession 需要我们自己手动开启和提交事务。
124. hibernate 实体类必须要有无参构造函数吗?为什么?
hibernate 中每个实体类必须提供一个无参构造函数,因为 hibernate 框架要使用 reflection api,通过调用 ClassnewInstance() 来创建实体类的实例,如果没有无参的构造函数就会抛出异常。
【MyBatis】
125. MyBatis 中 #{}和 ${}的区别是什么?
#{}是预编译处理,${}是字符替换。 在使用 #{}时,MyBatis 会将 SQL 中的#{}替换成“?”,配合 PreparedStatement 的 set 方法赋值,这样可以有效的防止 SQL 注入,保证程序的运行安全。
126. MyBatis 有几种分页方式?
分页方式:逻辑分页和物理分页。
- 逻辑分页: 使用 MyBatis 自带的 RowBounds 进行分页,它是一次性查询很多数据,然后在数据中再进行检索。
- 物理分页: 自己手写 SQL 分页或使用分页插件 PageHelper,去数据库查询指定条数的分页数据的形式。
127. RowBounds 是一次性查询全部结果吗?为什么?
RowBounds 表面是在“所有”数据中检索数据,其实并非是一次性查询出所有数据,因为 MyBatis 是对 jdbc 的封装,在 jdbc 驱动中有一个 Fetch Size 的配置,它规定了每次最多从数据库查询多少条数据,假如你要查询更多数据,它会在你执行 next()的时候,去查询更多的数据。就好比你去自动取款机取 10000 元,但取款机每次最多能取 2500 元,所以你要取 4 次才能把钱取完。只是对于 jdbc 来说,当你调用 next()的时候会自动帮你完成查询工作。这样做的好处可以有效的防止内存溢出。
Fetch Size 官方相关文档:http://t. cn/EfSE2g3
128. MyBatis 逻辑分页和物理分页的区别是什么?
- 逻辑分页是一次性查询很多数据,然后再在结果中检索分页的数据。这样做弊端是需要消耗大量的内存、有内存溢出的风险、对数据库压力较大。
- 物理分页是从数据库查询指定条数的数据,弥补了一次性全部查出的所有数据的种种缺点,比如需要大量的内存,对数据库查询压力较大等问题。
129. MyBatis 是否支持延迟加载?延迟加载的原理是什么?
MyBatis 支持延迟加载,设置 lazyLoadingEnabled=true 即可。
延迟加载的原理是调用的时候触发加载,而不是在初始化的时候就加载信息。比如调用 a. getB(). getName(),这个时候发现 a. getB() 的值为 null,此时会单独触发事先保存好的关联 B 对象的 SQL,先查询出来 B,然后再调用 a. setB(b),而这时候再调用 a. getB(). getName() 就有值了,这就是延迟加载的基本原理。
130. 说一下 MyBatis 的一级缓存和二级缓存?
- 一级缓存:基于 PerpetualCache 的 HashMap 本地缓存,它的声明周期是和 SQLSession 一致的,有多个 SQLSession 或者分布式的环境中数据库操作,可能会出现脏数据。当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认一级缓存是开启的。
- 二级缓存:也是基于 PerpetualCache 的 HashMap 本地缓存,不同在于其存储作用域为 Mapper 级别的,如果多个SQLSession之间需要共享缓存,则需要使用到二级缓存,并且二级缓存可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现 Serializable 序列化接口(可用来保存对象的状态)。
开启二级缓存数据查询流程:二级缓存 -> 一级缓存 -> 数据库。
缓存更新机制:当某一个作用域(一级缓存 Session/二级缓存 Mapper)进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。
131. MyBatis 和 hibernate 的区别有哪些?
- 灵活性:MyBatis 更加灵活,自己可以写 SQL 语句,使用起来比较方便。
- 可移植性:MyBatis 有很多自己写的 SQL,因为每个数据库的 SQL 可以不相同,所以可移植性比较差。
- 学习和使用门槛:MyBatis 入门比较简单,使用门槛也更低。
- 二级缓存:hibernate 拥有更好的二级缓存,它的二级缓存可以自行更换为第三方的二级缓存。
132. MyBatis 有哪些执行器(Executor)?
MyBatis 有三种基本的Executor执行器:
- SimpleExecutor:每执行一次 update 或 select 就开启一个 Statement 对象,用完立刻关闭 Statement 对象;
- ReuseExecutor:执行 update 或 select,以 SQL 作为 key 查找 Statement 对象,存在就使用,不存在就创建,用完后不关闭 Statement 对象,而是放置于 Map 内供下一次使用。简言之,就是重复使用 Statement 对象;
- BatchExecutor:执行 update(没有 select,jdbc 批处理不支持 select),将所有 SQL 都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个 Statement 对象,每个 Statement 对象都是 addBatch()完毕后,等待逐一执行 executeBatch()批处理,与 jdbc 批处理相同。
133. MyBatis 分页插件的实现原理是什么?
分页插件的基本原理是使用 MyBatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的 SQL,然后重写 SQL,根据 dialect 方言,添加对应的物理分页语句和物理分页参数。
134. MyBatis 如何编写一个自定义插件?
自定义插件实现原理
MyBatis 自定义插件针对 MyBatis 四大对象(Executor、StatementHandler、ParameterHandler、ResultSetHandler)进行拦截:
- Executor:拦截内部执行器,它负责调用 StatementHandler 操作数据库,并把结果集通过 ResultSetHandler 进行自动映射,另外它还处理了二级缓存的操作;
- StatementHandler:拦截 SQL 语法构建的处理,它是 MyBatis 直接和数据库执行 SQL 脚本的对象,另外它也实现了 MyBatis 的一级缓存;
- ParameterHandler:拦截参数的处理;
- ResultSetHandler:拦截结果集的处理。
自定义插件实现关键
MyBatis 插件要实现 Interceptor 接口,接口包含的方法,如下:
public interface Interceptor {
Object intercept(Invocation invocation) throws Throwable;
Object plugin(Object target);
void setProperties(Properties properties);
}
- setProperties 方法是在 MyBatis 进行配置插件的时候可以配置自定义相关属性,即:接口实现对象的参数配置;
- plugin 方法是插件用于封装目标对象的,通过该方法我们可以返回目标对象本身,也可以返回一个它的代理,可以决定是否要进行拦截进而决定要返回一个什么样的目标对象,官方提供了示例:return Plugin. wrap(target, this);
- intercept 方法就是要进行拦截的时候要执行的方法。
自定义插件实现示例
官方插件实现:
@Intercepts({@Signature(type = Executor. class, method = "query",
args = {MappedStatement. class, Object. class, RowBounds. class, ResultHandler. class})})public class TestInterceptor implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation. getTarget(); //被代理对象
Method method = invocation. getMethod(); //代理方法
Object[] args = invocation. getArgs(); //方法参数
// do something . . . . . . 方法拦截前执行代码块
Object result = invocation. proceed();
// do something . . . . . . . 方法拦截后执行代码块
return result;
}
public Object plugin(Object target) {
return Plugin. wrap(target, this);
}
}
Java相关面试题总结+答案(七)的更多相关文章
- Java相关面试题总结+答案(一)
[Java基础] 1. JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,即Java开发工具包,提供了Java 的开发环境和运行环境. JRE:Java Ru ...
- Java相关面试题总结+答案(二)
[容器] 18. Java 容器都有哪些? 19. Collection 和 Collections 有什么区别? Collection 是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法, ...
- Java相关面试题总结+答案(三)
[多线程] 35. 并行和并发有什么区别? 并行:多个处理器或多核处理器同时处理多个任务.(是真正的物理上的同时发生) 并发:多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执行,从逻辑上来 ...
- Java相关面试题总结+答案(九)
[MySQL] 164. 数据库的三范式是什么? 第一范式:强调的是列的原子性,即数据库表的每一列都是不可分割的原子数据项. 第二范式:属性完全依赖于主键(满足第一范式的前提下),即任意一个字段只依赖 ...
- Java相关面试题总结+答案(四)
[反射] 57. 什么是反射? 反射是在运行状态中,对于任意一个类,都能够知道该类的所有属性和方法,对于任意一个对象,都能够获得该对象的任一属性和方法:这种动态获取信息以及动态调用对象的方法的功能称之 ...
- Java相关面试题总结+答案(十)
[JVM] 194. 说一下 JVM 的主要组成部分?及其作用? 类加载器(ClassLoader) 运行时数据区(Runtime Data Area) 执行引擎(Execution Engine) ...
- Java相关面试题总结+答案(六)
[Spring/Spring MVC] 90. 为什么要使用 spring? spring 提供了 IOC 技术,spring 容器会帮你管理依赖的对象,从而不需要自己创建和管理依赖对象了,更轻松的实 ...
- Java相关面试题总结+答案(五)
[异常] 74. throw 和 throws 的区别? throw 是真实抛出一个异常: throws 是声明可能会抛出一个异常. 75. final.finally.finalize 有什么区别? ...
- Java相关面试题总结+答案(八)
[RabbitMQ] 135. RabbitMQ 的使用场景有哪些? 抢购活动,削峰填谷,防止系统崩塌. 延迟信息处理,比如 10 分钟之后给下单未付款的用户发送邮件提醒. 解耦系统,对于新增的功能可 ...
随机推荐
- 牛客练习赛14 A n的约数 (数论)
链接:https://ac.nowcoder.com/acm/contest/82/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288 ...
- Springboot读取properties配置文件数据
一.使用@ConfigurationProperties来读取 1.Coffer entity @Configuration @ConfigurationProperties(prefix = &qu ...
- iOS各别版本new Date().getTime 获取时间戳为null问题
正常逻辑 new Date('2019-9-8').getTime() 注意日期格式 yyyy--mm-dd 因为yyyy/mm/dd也有兼容性问题 但是各别iOS版本不支持 // IOS 获取时间戳 ...
- 2018微信小程序开发遇到的坑
第一个坑:wx.showModal(OBJECT) wx.showModal在安卓手机里,如果点击遮罩的话会关闭弹窗,不会有任何回调.而苹果的情况下则是点击遮罩不会有任何反应. 这样会有什么问题呢? ...
- JS中的流程控制语句
什么叫做语句? 语句:可以理解为语言中一句一句完整的话,程序是由一条条语句构成的,语句是按照自上往下的顺序执行的. 在JavaScript可以使用{ }来为语句进行分组.同一{ }中的语句称为一组 ...
- 弹性盒子FlexBox简介(一)
一.理解弹性盒子 弹性盒子是CSS3的一种新的布局模式. CSS3弹性盒子(Flexible Box或flexbox),是一种当页面需要适应不同的屏幕大小以及设备类型时,确保元素拥有恰当的行为的布局方 ...
- 在 centos7.5 使用 DockerFile 构建镜像时报错 "Error parsing reference:"microsoft/dotnet:2.2-aspnetcore-runtime AS base"is not a valid repository/tag: invalid reference format"
运行 dockerfile 时报出的错误 FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base Error parsing reference: & ...
- Floyd求解最短路
Floyd算法适用于求解全源最短路.也就是能够求解任意两点间的最短路径并且是适用于含有负权边的图,但是含有负环则不行了!空间复杂度为O(n2).时间复杂度为O(n3).其具体的原理在百度能够找到很多, ...
- 跳马(Knight Moves), ZOJ1091, POJ2243 x
跳马(Knight Moves), ZOJ1091, POJ2243 题目描述: 给定象棋棋盘上两个位置 a 和 b,编写程序,计算马从位置 a 跳到位置 b 所需步数的最小值. 输入描述: 输入文件 ...
- 【bzoj3295】[Cqoi2011]动态逆序对
题目描述: 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆 ...