Hibernate总结以及在面试中的一些问题.
Hibernate总结以及在面试中的一些问题.
1.为什么要使用Hibernate开发你的项目呢?Hibernate的开发流程是怎么样的?
①.对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。②.Hibernate 是一个基于JDBC的主流持久化框架,是一个优秀的ORM 实现。他很大程度的简化DAO层的编码工作③.hibernate 的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。
2.什么是延迟加载?
3.说一下hibernate的缓存机制
(1)hibernate支持两个级别的缓存,默认只支持一级缓存;(2)每个Session内部自带一个一级缓存;(3)某个Session被关闭时,其对应的一级缓存自动清除;
(1) 二级缓存独立于session,默认不开启;
4.Hibernate的查询方式有哪些?
5.如何优化Hibernate?
6.Hibernate中GET和LOAD的区别?
7.说说在 hibernate中使用Integer做映射和使用int做映射之间有什么差别?
Integer是对象. code=null; 对象可以为空.int 是普通类型, 不可能=null.
你没理由hbm.xml里写 Integer,类里却写int
8.SQL和HQL有什么区别?
hql 面向对象查询
hql:from 后面跟的 类名+类对象 where 后 用 对象的属性做条件
sql:from 后面跟的是表名 where 后 用表中字段做条件
查询
在Hibernate中使用查询时,一般使用Hql查询语句。
HQL(Hibernate Query Language),即Hibernate的查询语言跟SQL非常相像。不过HQL与SQL的最根本的区别,就是它是面向对象的。
使用HQL时需要注意以下几点:
1.大小写敏感
因为HQL是面向对象的,而对象类的名称和属性都是大小写敏感的,所以HQL是大小写敏感的。HQL语句:from Cat as cat where cat.id > 1;与from Cat as cat where cat.ID > 1;是不一样的,这点与SQL不同。
from Cat,该句返回Cat对象实例,开发人员也可以给其加上别名,eg. from Cat as cat,对于多表查询的情况,可参考如下:from Cat as cat, Dog as dog其它方面都与SQL类似,在此不再赘述。
9.Hibernate的分页查询
q.setMaxResults(100);;
List l = q.list();;
q.setFirstResult(20000);;
10.Hibernate中Java对象的状态以及对应的特征有哪些?
持久化对象PO和OID
PO=POJO + hbm映射配置
编写规则
①必须提供无参数public构造器②所有属性private,提供public的getter和setter方法③必须提供标识属性,与数据表中主键对应,例如Customer类 id属性④PO类属性应尽量使用基本数据类型的包装类型(区分空值) 例如int---Integer long---Long⑤不要用final修饰(将无法生成代理对象进行优化)
* 例如内存中有两个PO对象,只要具有相同 OID, Hibernate认为同一个对象
* Hibernate 不允许缓存同样OID的两个不同对象
②持久态:存在持久化标识OID,与当前session有关联,并且相关联的session没有关闭 ,并且事务未提交
③脱管态(离线态、游离态):存在持久化标识OID,但没有与当前session关联,脱管状态改变hibernate不能检测到
// 获得SessionSession session =HibernateUtils.openSession();// 开启事务Transaction transaction = session.beginTransaction(); Book book =newBook();// 瞬时态(没有OID,未与Session关联)book.setName("hibernate精通");book.setPrice(56d); session.save(book);// 持久态(具有OID,与Session关联) // 提交事务,关闭Sessiontransaction.commit();session.close(); System.out.println(book.getId());// 脱管态(具有 OID,与Session断开关联)11.Hibernate中怎样处理事务?
Hibernate是对JDBC的轻量级对象封装,Hibernate本身是不具备Transaction 处理功能的,Hibernate的Transaction实际上是底层的JDBC Transaction的封装,或者是JTA Transaction的封装,下面我们详细的分析:
Hibernate可以配置为JDBCTransaction或者是JTATransaction,这取决于你在hibernate.properties中的配置:
#hibernate.transaction.factory_class net.sf.hibernate.transaction.JTATransactionFactory#hibernate.transaction.factory_class net.sf.hibernate.transaction.JDBCTransactionFactory
hibernate.transaction.factory_class net.sf.hibernate.transaction.JTATransactionFactory
将使用JTATransaction,不管你准备让Hibernate使用JDBCTransaction,还是JTATransaction,我的忠告就是什么都不配,将让它保持默认状态,如下:
#hibernate.transaction.factory_class net.sf.hibernate.transaction.JTATransactionFactory#hibernate.transaction.factory_class net.sf.hibernate.transaction.JDBCTransactionFactory
一、JDBC Transaction
看看使用JDBC Transaction的时候我们的代码例子:
Session session = sf.openSession();Transaction tx = session.beginTransactioin();...session.flush();tx.commit();session.close();
Hibernate2.0.3源代码中的类
net.sf.hibernate.transaction.JDBCTransaction:public void begin() throws HibernateException {...if (toggleAutoCommit) session.connection().setAutoCommit(false);...}
再来看
public void commit() throws HibernateException {...try {if ( session.getFlushMode()!=FlushMode.NEVER ) session.flush();try {session.connection().commit();committed = true;}...toggleAutoCommit();}
Connection conn = ...; <--- session = sf.openSession();conn.setAutoCommit(false); <--- tx = session.beginTransactioin();... <--- ...conn.commit(); <--- tx.commit(); (对应左边的两句)conn.setAutoCommit(true);conn.close(); <--- session.close();
12.简单的介绍一下Hibernate的核心API?
//方式一:去src 读取 hibernate.properties 属性配置文件Configuration cfg =newConfiguration(); //方式二:去src读取 hibernate.cfg.xml Configuration cfg =newConfiguration().configure(); Configuration cfg =newConfiguration().configure("自定义xml文件");去src 加载指定文件 org.hibernate.MappingException:Unknown entity: cn.itcast.domain.Customer //方式一:configuration.addResource("cn/itcast/domain/Customer.hbm.xml");加载hbm文件 //方式二:configuration.addClass(Customer.class);加载Class,自动搜索hbm映射文件//预定义SQL语句<sql-queryname="login"> <![CDATA[select * from user where username= ? and password =?]]></sql-query>save 完成插入update 完成修改delete完成删除get/load 根据主键字段查询createQuery、 createSQLQuery 创建查询对象Query接收HQL,SQLQuery接收SQLcreateCriteria() 面向对象条件查询//默认false
<property name="hibernate.connection.autocommit">false</property> 事务不提交<propertyname="hibernate.connection.autocommit">true</property> 事务提交开发代码步骤 获得HibernateSession对象 编写HQL语句 调用session.createQuery 创建查询对象 如果HQL语句包含参数,则调用Query的setXXX设置参数 调用Query对象的list()或uniqueResult()方法执行查询13.update与saveOrUpdate有什么区别?
update() 如果是对一个已经存在的托管对象进行更新那么肯定是要使用update()方法了,数据中有这个对象。
saveOrUpdate() 这个方法是更新或者插入,有主键就执行更新,如果没有主键就执行插入。【此方法慎用】
有两张表,表A和表B,这两张表的主键都是一样的,例如都是MASTER_ID,同时对应的BO里面属性都是masterID,现在要执行的操作是,以 MASTER_ID为条件将表A中的数据查询出来,然后将部分值插入到表B中,然后再更新表B,在查询表A后,session中已经存在masterID 了,这个时候再去对表B进行savaOrUpdate的时候,Hibernate会发现session中已经存在masterID了,所以执行的就是 update,但是实际上表B中根本不存在masterID这个值,当你执行完查询数据库的时候会发现没有插入数据,像这种情况,就得先用 masterID对表B进行查询,当返回的BO为NULL时,new一个新BO然后再进行插入,这个时候用到的就是createbo了。
14.Hibernate的inverse属性的作用?
inverse 决定是否把对对象中集合的改动反映到数据库中,所以inverse只对集合起作用,也就是只对one-to-many或many-to-many有效(因为只有这两种关联关系包含集合,而one-to-one和many-to-one只含有关系对方的一个引用)。
cascade决定是否把对对象的改动反映到数据库中,所以cascade对所有的关联关系都起作用(因为关联关系就是指对象之间的关联关系)。
inverse只存在于集合标记的元素中 。Hibernate提供的集合元素包括<set/> <map/> <list/> <array /> <bag />
Inverse属性的作用是:是否将对集合对象的修改反映到数据库中。 inverse属性的默认值为false,表示对集合对象的修改会被反映到数据库中;inverse=false 的为主动方,由主动方负责维护关联关系。 inverse=”true” 表示对集合对象的修改不会被反映到数据库中。为了维持两个实体类(表)的关系,而添加的一些属性,该属性可能在两个实体类(表)或者在一个独立的表里面,这个要看这双方直接的对应关系了: 这里的维护指的是当主控放进行增删改查操作时,会同时对关联关系进行对应的更新。
一对多: 该属性在多的一方。应该在一方的设置 inverse=true ,多的一方设置 inverse=false(多的一方也可以不设置inverse属性,因为默认值是false),这说明关联关系由多的一方来维护。如果要一方维护关 系,就会使在插入或是删除"一"方时去update"多"方的每一个与这个"一"的对象有关系的对象。而如果让"多"方面维护关系时就不会有update 操作,因为关系就是在多方的对象中的,直指插入或是删除多方对象就行了。显然这样做的话,会减少很多操作,提高了效率。
多对多: 属性在独立表中。inverse属性的默认值为false。在多对多关联关系中,关系的两端 inverse不能都设为false,即默认的情况是不对的,如果都设为false,在做插入操作时会导致在关系表中插入两次关系。也不能都设为 true,如果都设为true,任何操作都不会触发对关系表的操作。因此在任意一方设置inverse=true,另一方inverse=false。
一对一: 其实是一对多的一个特例,inverse 的设置也是一样的,主要还是看关联关系的属性在哪一方,这一方的inverse=false。
多对一: 也就是一对多的反过来,没什么区别。
级联操作:指当主控方执行某项操作时,是否要对被关联方也执行相同的操作。
注意:<one-to-many />和 <many-to-many />是用在集合标记内部的,所以是不需要cascade属性的。
4.inverse和cascade的区别
作用的范围不同:
Inverse是设置在集合元素中的。
Cascade对于所有涉及到关联的元素都有效。
<many-to-one/><ont-to-many/>没有inverse属性,但有cascade属性
执行的策略不同
Inverse 会首先判断集合的变化情况,然后针对变化执行相应的处理。
Cascade 是直接对集合中每个元素执行相应的处理
执行的时机不同
Inverse是在执行SQL语句之前判断是否要执行该SQL语句
Cascade则在主控方发生操作时用来判断是否要进行级联操作
执行的目标不同
Inverse对于<ont-to-many>和<many-to-many>处理方式不相同。
对于<ont-to-many>,inverse所处理的是对被关联表进行修改操作。
对于<many-to-many>,inverse所处理的则是中间关联表
Cascade不会区分这两种关系的差别,所做的操作都是针对被关联的对象。
总结:
<one-to-many>
<one-to-many>中,建议inverse=”true”,由“many”方来进行关联关系的维护
<many-to-many>中,只设置其中一方inverse=”false”,或双方都不设置
Cascade,通常情况下都不会使用。特别是删除,一定要慎重。
操作建议:
many-to-many关联关系中,一端设置inverse=”false”,另一端设置为inverse=”true”。在one-to-many关联关系中,设置inverse=”true”,由多端来维护关系表
Hibernate一级缓存相关问题
*private transient ActionQueue actionQueue; ----行动队列(标记数据活动)*private transient StatefulPersistenceContext persistenceContext;----持久化上下文 Book book =(Book) session.get(Book.class,1);// 第一次查询,缓存中没有System.out.println(book); Book book2 =(Book) session.get(Book.class,1);// 因为第一次查询,对象已经被放入1级缓存,不会查询数据System.out.println(book2); *生成一条SQL语句,返回同一个对象,第一次查询生成SQL,查询对象,将对象放入一级缓存,第二次查询,直接从一级缓存获得* 测试快照区的使用 */@Testpublicvoid demo3(){ // 获得SessionSession session =HibernateUtils.openSession();// 开启事务Transaction transaction = session.beginTransaction(); // 查询id 为1 的图书对象Book book =(Book) session.get(Book.class,1);// 第一次查询,将对象加入一级缓存System.out.println(book); book.setName("深入浅出Hibernate技术");// 修改书名(一级缓存被修改,自动update) // 没有手动执行update,因为快照区原因,自动更新 // 提交事务,关闭Sessiontransaction.commit();session.close();2)clear : 清除所有对象 一级缓存
@Test// Session 对于 一级缓存操作publicvoid demo4(){// 获得SessionSession session =HibernateUtils.openSession();// 开启事务Transaction transaction = session.beginTransaction(); // 查询id 为1 的图书对象Book book =(Book) session.get(Book.class,1);// 第一次查询,将对象加入一级缓存System.out.println(book); // book.setPrice(80d); // 修改一级缓存数据// 将缓存内容同步到数据库
// session.flush(); // 清除一级缓存所有数据// session.clear(); // 清除一级缓存中 指定对象// session.evict(book); book.setPrice(30d);// 一级缓存改变session.refresh(book);// 用数据库内容 覆盖快照区和一级缓存 // 提交事务,关闭Sessiontransaction.commit();session.close();}@Test// 理解 FlushMode作用publicvoid demo5(){// 获得SessionSession session =HibernateUtils.openSession(); // 设置 flushModesession.setFlushMode(FlushMode.MANUAL); // 开启事务Transaction transaction = session.beginTransaction(); // 查询id 为1 的图书对象Book book =(Book) session.get(Book.class,1);// 第一次查询,将对象加入一级缓存System.out.println(book); book.setPrice(1000d);// 修改价格 session.createQuery("from Book").list();// 查询所有图书 (AUTO 级别 flush) // 提交事务,关闭Sessiontransaction.commit();// (COMMIT 级别 flush) // session.flush(); // MANUAL 级别 flush session.close();}@Test// 脱管对象更新publicvoid demo6(){// 获得SessionSession session =HibernateUtils.openSession();// 开启事务Transaction transaction = session.beginTransaction(); Book book =newBook();// 瞬时book.setId(1);// 脱管book.setName("java入门");book.setPrice(40d); session.update(book);// 持久 session.flush(); // book.setPrice(50d); // 提交事务,关闭Sessiontransaction.commit();session.close();}<classname="cn.itcast.domain.firstcache.Book"table="book"catalog="hibernate3day2"select-before-update="true">@Test// 一级缓存 存在两个相同OID 持久态对象 报错publicvoid demo7(){// 获得SessionSession session =HibernateUtils.openSession();// 开启事务Transaction transaction = session.beginTransaction(); // 查询// Book b = (Book) session.get(Book.class, 1); // 持久 Book book =newBook();// 瞬时book.setId(1);// 脱管book.setName("java入门");book.setPrice(50d);session.update(book);// 持久 // 提交事务,关闭Sessiontransaction.commit();session.close();}@Test// PO对象,OID为 hbm文件 配置 unsaved-value 也是瞬时对象, saveOrUpdate 执行 save操作publicvoid demo8(){// 获得SessionSession session =HibernateUtils.openSession();// 开启事务Transaction transaction = session.beginTransaction(); Book book =newBook();// 瞬时book.setId(-1);// 存在OID , -1是unsaved-value 也是瞬时book.setName("xxx");book.setPrice(100d); session.saveOrUpdate(book); // 提交事务,关闭Sessiontransaction.commit();session.close();}Hibernate二级缓存相关问题
缓存好处: 将数据库或者硬盘数据,保存在内存中,减少数据库查询次数,减少硬盘交互,提高检索效率
hibernate 共有两个级别的缓存
* 一级缓存,保存Session中, 事务范围的缓存
* 二级缓存,保存SessionFactory ,进程范围的缓存
SessionFacoty 两部分缓存
内置 :Hibernate 自带的, 不可卸载. 通常在 Hibernate 的初始化阶段, Hibernate 会把映射元数据和预定义的 SQL 语句放到SessionFactory 的缓存中, 映射元数据是映射文件中数据的复制, 而预定义 SQL 语句时 Hibernate 根据映射元数据推到出来的. 该内置缓存是只读的.
外置 :一个可配置的缓存插件. 在默认情况下, SessionFactory 不会启用这个缓存插件. 外置缓存中的数据是数据库数据的复制, 外置缓存的物理介质可以是内存或硬盘,必须引入第三方缓存插件才能使用。
* 更新时间戳区域
* 查询缓存区域
** 一级缓存的操作会同步到二级缓存
更新时间戳区域
作用:记录数据最后更新时间,确保缓存数据是有效的
Hibernate 提供了和查询相关的缓存区域:
时间戳缓存区域存放了对于查询结果相关的表进行插入, 更新或删除操作的时间戳. Hibernate 通过时间戳缓存区域来判断被缓存的查询结果是否过期, 其运行过程如下:
T1 时刻执行查询操作, 把查询结果存放在 QueryCache 区域, 记录该区域的时间戳为 T1
T2 时刻对查询结果相关的表进行更新操作, Hibernate 把 T2 时刻存放在 UpdateTimestampCache 区域.
T3 时刻执行查询结果前, 先比较 QueryCache 区域的时间戳和 UpdateTimestampCache 区域的时间戳, 若 T2 >T1, 那么就丢弃原先存放在 QueryCache 区域的查询结果, 重新到数据库中查询数据, 再把结果存放到 QueryCache 区域; 若 T2 < T1, 直接从 QueryCache 中获得查询结果。
* 二级缓存缓存数据都是类对象数据,数据都是缓存在 "类缓存区域" ,二级缓存缓存PO类对象,条件(key)是id
查询缓存适用场合:
**应用程序运行时经常使用查询语句
**很少对与查询语句检索到的数据进行插入, 删除和更新操作
如果查询条件不是id查询, 缓存数据不是PO类完整对象 =====> 不适合使用二级缓存
查询缓存: 缓存的是查询数据结果, key是查询生成SQL语句 , 查询缓存比二级缓存功能更加强大
2)启用查询缓存 hibernate.cfg.xml
<property name="hibernate.cache.use_query_cache">true</property>query.setCacheable(true);transactional : 提供Repeatable Read事务隔离级别,缓存支持事务,发生异常的时候,缓存也能够回滚
read-write : 提供Read Committed事务隔离级别,更新缓存的时候会锁定缓存中的数据
nonstrict-read-write :导致脏读, 很少使用
read-only : 数据不允许修改,只能查询
* 很少被修改,不是很重要,允许偶尔的并发问题, 适合放入二级缓存。考虑因素(二级缓存的监控【后面学习】,它是是否采用二级缓存主要参考指标)
* OSCache
可作为进程范围内的缓存, 存放数据的物理介质可以是内存或硬盘, 提供了丰富的缓存数据过期策略, 对 Hibernate 的查询缓存提供了支持
* SwarmCache
可作为集群范围内的缓存, 但不支持 Hibernate 的查询缓存
* JBossCache
可作为集群范围内的缓存, 支持 Hibernate 的查询缓存
Hibernate总结以及在面试中的一些问题.的更多相关文章
- [Java面试八]Hibernate总结以及在面试中的一些问题.
1.为什么要使用Hibernate开发你的项目呢?Hibernate的开发流程是怎么样的? 为什么要使用 ①.对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码. ②.Hiber ...
- JAVA面试中问及HIBERNATE与 MYBATIS的对比,在这里做一下总结
我是一名java开发人员,hibernate以及mybatis都有过学习,在java面试中也被提及问道过,在项目实践中也应用过,现在对hibernate和mybatis做一下对比,便于大家更好的理解和 ...
- JAVA面试中问及HIBERNATE与 MYBATIS的对比,在这里做一下总结(转)
hibernate以及mybatis都有过学习,在java面试中也被提及问道过,在项目实践中也应用过,现在对hibernate和mybatis做一下对比,便于大家更好的理解和学习,使自己在做项目中更加 ...
- 如何回答面试中问到的Hibernate和MyBatis的区别
这边主要是写给那些准备去面试的(没什么经验的)应聘者看的,为了在面试中更好的回答这个问题,我做一个简单的梳理和总结. 作为一名职场新人,经历过多次的面试,由于在简历中提及了Hibernate和MyBa ...
- Struts,spring,hibernate三大框架的面试
Struts,spring,hibernate三大框架的面试 1.Hibernate工作原理及为什么要用? 原理: 1.读取并解析配置文件 2.读取并解析映射信息,创建SessionFactory 3 ...
- 面试题_125_to_133_Java 面试中其他各式各样的问题
这部分包含 Java 中关于 XML 的面试题,JDBC 面试题,正则表达式面试题,Java 错误和异常及序列化面试题 125)嵌套静态类与顶级类有什么区别?(答案)一个公共的顶级类的源文件名称与类名 ...
- 【转】Spring总结以及在面试中的一些问题
[转]Spring总结以及在面试中的一些问题. 1.谈谈你对spring IOC和DI的理解,它们有什么区别? IoC Inverse of Control 反转控制的概念,就是将原本在程序中手动创建 ...
- Spring总结以及在面试中的一些问题
Spring总结以及在面试中的一些问题. 1.谈谈你对spring IOC和DI的理解,它们有什么区别? IoC Inverse of Control 反转控制的概念,就是将原本在程序中手动创建Use ...
- 在面试中忽然发现DateTime的一些...
今天说说我面试中碰到的一个小问题,在我问起DateTime为什么无法赋值NULL值,一般第一反应都认为它是值类型,不是引用类型,但随后我查阅了度娘自我学习到它是结构类型,那么随之而然就无法赋值NULL ...
随机推荐
- leetcode-algorithms-34 Find First and Last Position of Element in Sorted Array
leetcode-algorithms-34 Find First and Last Position of Element in Sorted Array Given an array of int ...
- MapReduce(二)
MapReduce(二) mapreduce 将Text转化为对象进行处理数据. 根据一来说,将date,classname,name,subject,score变为对象属性 我的数据是:是有重复的. ...
- bool类型为什么可以当做int
实际上bool型变量占用了一个字节的内存,当值为false的时候,实际存储的是0x00,为true时实际存储的是0x01,因此可以作为int整型使用 bool型只分0与非0,0为false,其余的包括 ...
- 自签名证书说明——自签名证书的Issuer和Subject是一样的。不安全的原因是:没有得到专业SSL证书颁发的机构的技术支持?比如使用不安全的1024位非对称密钥对,有效期设置很长等
一般的数字证书产品的主题通常含有如下字段:公用名称 (Common Name) 简称:CN 字段,对于 SSL 证书,一般为网站域名:而对于代码签名证书则为申请单位名称:而对于客户端证书则为证书申请者 ...
- MFC CDHtmlDialog 加载本地资源
步骤:1.资源视图 项目右击选择资源添加,自定义添加新类型 如:JS(会增加JS文件夹)2. 选择1新建的文件夹右击 添加资源 导入 选择js文件引入3. 在资源文件Resource.h文件夹能找到资 ...
- axios API速查表
原来jq自带ajax方法,但是近期项目用vue,在vue项目中发送ajax请求原来用vue resource,现在更推荐使用axios,因为axios和vue更配! GET 请求 // Make a ...
- CAD绘制扶手5.6
用PL命令绘制出扶手的位置,如图 , “楼梯其他”“添加扶手”选择这条线,扶手宽度60,高度900,中间对齐.生成如图: 三维:
- spark使用正则表达式读入多个文件
String dir = "s3a://example/";String currentDir = dir + "{1[5-9],2[01]}/*.txt";J ...
- javaweb环境搭建
首先,在开始搭建MyEclipse的开发环境之前,还有三步工具的安装需要完成,只要在安装配置成功之后才可以进入下面的java Web项目开发环境的搭建. 1.安装工具 第一步,下载并安装JDK,到官网 ...
- Spring注入,Ioc的具体配置
Spring框架的IOC注入: 一.Java部分代码: Person实体类: package com.ioc; import java.util.List; import java.util.Map; ...