资深java面试题及答案,java高频面试题精讲
如何解决写爬虫IP受阻的问题?立即使用。
什么是ORM?(推荐学习:java面试题目)
对象关系映射(ORM)是一种解决程序的面向对象模型与数据库的关系模型不匹配问题的技术。
简单地说,ORM自动将程序中的对象持久化到关系数据库中,或者通过使用描述对象和数据库之间映射的元数据(XML或Java中的注释)将关系数据库表中的行转换成Java对象。本质上,ORM将数据从一种形式转换成另一种形式。
Hibernate中SessionFactory是线程安全的吗?Session是线程安全的吗(两个线程能够共享同一个Session吗)?
Session对应于Hibernate的一个数据存储概念,它是线程安全的,可以被多个线程并发访问。SessionFactory通常只在启动时构建。对于应用程序,最好通过singleton模式封装SessionFactory,以便于访问。
Session是一个轻量级的非线程安全对象(线程之间不能共享任何会话)。它表示与数据库交互的工作单元。会话是由SessionFactory创建的,它将在任务完成后关闭。会话是持久层服务提供的主要接口。
会话将延迟数据库连接的获取(即,仅在需要时获取)。为了避免创建太多的会话,您可以使用ThreadLocal将会话绑定到当前线程,以便同一个线程总是获得同一个会话。
Hibernate 3中SessionFactory的getCurrentSession()方法可以做到。
Session的save()、update()、merge()、lock()、saveOrUpdate()和persist()方法分别是做什么的?有什么区别?
Hibernate对象有三种状态:瞬态、持久和分离。
瞬态的实例可以通过调用save()、persist()或saveOrUpdate()方法变成持久状态;
处于自由状态的实例可以通过调用update()、saveOrUpdate()、lock()或replicate()成为持久状态。Save()和persist()将触发SQL的INSERT语句,而update()或merge()将触发UPDATE语句。
save()和update()的区别在于,一个是把瞬态对象变成持久对象,一个是把自由对象变成持久对象。merge()方法可以完成save()和update()方法的功能,其意图是将新的状态合并到现有的持久对象中,或者创建一个新的持久对象。
对于persist()方法,按照官方文档的说明:
1.persist()方法持久化一个瞬态的实例,但不保证标识符会立即填充到持久化实例中,标识符的填充可能会延迟到刷新时间;
2.persist()方法确保在事务外部调用它时,不会触发INSERT语句。当需要封装长会话流程时,persist()方法是必要的;
3.save()方法不保证第2条,它返回标识符,所以它会立即执行INSERT语句,不管是在事务内部还是外部。
至于lock()方法和update()方法的区别,update()方法是把一个已经改变了失控状态的对象变成持久状态;lock()方法是让一个处于不变失控状态的对象变成持久状态。
阐述Session加载实体对象的过程。
1.在调用数据库查询函数之前,Session将首先在一级缓存中搜索实体类型和主键。如果一级缓存搜索命中,且数据状态合法,则直接返回;
2.如果在一级缓存中没有命中,那么Session会在当前的NonExists记录中进行搜索(相当于一个查询黑名单,如果有重复的无效查询,可以快速做出判断,从而提高性能)。如果非Exists中存在相同的查询条件,将返回null;
3.如果一级缓存查询失败,则查询二级缓存,如果二级缓存命中,则直接返回;
4.如果前面的查询都没有命中,则发送一条SQL语句。如果在查询中没有找到相应的记录,则将该查询添加到要记录的会话的非Exists中,并返回null;
5.根据映射配置和SQL语句获取结果集,并创建相应的实体对象;
6.将对象纳入会话(一级缓存)管理;
7.如果有对应的拦截器,执行拦截器的onLoad方法;
8.如果要使用二级缓存开启并设置,则将数据对象带入二级缓存;
9.返回数据对象。
#将所有传入数据视为字符串,它会自动引用传入数据;
$传入的数据直接在SQL中显示和生成。
注意:使用$占位符可能会导致SQL注入攻击。不要在可以使用#的地方使用$符号。编写order by子句时,应该使用$而不是#。
解释一下MyBatis中命名空间(namespace)的作用。
在大型项目中,可能会有大量的SQL语句,因此给每个SQL语句一个惟一的ID并不容易。
为了解决这个问题,在MyBatis中,可以为每个映射文件创建一个唯一的名称空间,这样在这个映射文件中定义的每个SQL语句就变成了在这个名称空间中定义的一个ID。
只要我们能保证这个ID在每个命名空间中是唯一的,那么即使不同映射文件中的语句ID相同,也不会再有冲突。
MyBatis中的动态SQL是什么意思?
对于一些复杂的查询,我们可能会指定多个查询条件,但这些条件可能存在,也可能不存在。如果不使用持久层框架,可能需要自己组装SQL语句,但是MyBatis提供了动态SQL的功能来解决这个问题。MyBatis中用于实现动态SQL的元素主要包括:
-if-choose/when/other-trim-where-set-foreach用法举例:
select id=foo 参数Type=Blog 结果Type=Blog
select * from t_blog其中1=1
if test=title!=null
并且title=#{title}
/如果
if test=content!=null
并且content=#{content}
/如果
if test=owner!=null
并且owner=#{owner}
/如果
/选择JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的?
1.JDBC:频繁地创建和释放数据库链接会浪费系统资源,影响系统性能。如果使用数据库连接池,这个问题可以解决。
MyBatis:在SqlMapConfig.xml中配置数据连接池,使用连接池管理数据库链接。
2.JDBC:Sql语句写在代码中,这使得代码很难维护。sql的实际应用可能会有很大的变化,sql的变化需要改变java代码。
MyBatis:将XXXXmapper.xml文件中的Sql语句配置为与java代码分离。
3.JDBC:给sql语句传递参数比较麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。
MyBatis: Mybatis自动将java对象映射到sql语句。
4.JDBC:解析结果集比较麻烦,sql的变化导致解析代码的变化,解析前需要遍历。将数据库记录封装到pojo对象中进行解析更加方便。
MyBatis:Mybatis自动将sql执行结果映射到java对象。
MyBatis与Hibernate有哪些不同?
1.与hibernate不同,mybatis不是一个ORM框架,因为Mybatis需要程序员自己编写Sql语句。但是MyBatis可以灵活配置sql语句通过XML或者注释运行,映射java对象和sql语句生成最终的sql,最后映射sql执行的结果生成java对象。
2.Mybatis学习门槛低,简单易学。程序员直接编写原生态sql,可以严格控制sql执行的性能,灵活性高。非常适合对关系数据模型要求不高的软件开发,比如互联网软件、企业运营软件等,因为这类软件的需求变化频繁,一旦需求发生变化,要求快速输出结果。
但是,灵活性的前提是mybatis不能独立于数据库。如果需要实现支持多个数据库的软件,需要定制多组sql映射文件,工作量很大。
3.hibernate具有很强的对象/关系映射能力和良好的数据库独立性。如果用Hibernate开发对关系模型要求高的软件(比如有固定需求的定制软件),可以节省大量代码,提高效率。
但是Hibernate的缺点是学习门槛高,熟练门槛较高,而如何设计O/R映射,如何平衡性能和对象模型,如何用好Hibernate,需要很强的经验和能力。
总之,根据用户的需求,只要能在有限的资源环境下做出具有良好可维护性和可扩展性的软件架构,就是好的架构,所以最好的框架才是合适的。
(这里你也可以根据自己的理解说出来,但是你不能接受你没有说出来的东西。)
简单的说一下MyBatis的一级缓存和二级缓存?
Mybatis首先去缓存查询结果集,如果没有,它将查询数据库,如果有,它将从缓存中取出返回的结果集,而不离开数据库。Mybatis内部存储缓存使用的是HashMap,关键是hashCode sqlId Sql语句。为从查询映射生成的值java对象
Mybatis的二级缓存是查询缓存,其作用域是mapper的一个命名空间,即在同一个命名空间查询sql可以从缓存中获取数据。L2缓存可以跨越SqlSession。以上是Java持久性面试话题的详细内容,更多请关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。