Hibernate问题集锦: 概述

 

ImportNew注: 本文是ImportNew编译整理的Java面试题系列文章之一。你可以从这里查看全部的Java面试系列。

Q.怎么配置hibernate

A.Configuration类使用配置hibernate.cfg.xml(或者hibernate.properties)以及映射文件*.hbm.xml来创建(例如,配置和引导hibernate)SessionFactory,然后SessionFactory创建Session的实例。Session的实例是持久层服务对外提供的主要接口。

hibernate.cfg.xml(或者你也可以使用hibernate.properties):这两个文件都是用来配置hibernate服务(数据库连接的驱动类,连接URL,用户名,密码,方言等)。如果这两个文件同时存在于classpath里的话,那么hibernate.cfg.xml会覆盖hibernate.properties文件里的配置。

映射文件(*.hbm.xml):这些文件都是用来对持久层对象和关系数据库进行映射的。最好的方式是对每个对象都使用单独的映射文件(例如一个类一个文件),因为如果在一个文件里存放大量的持久层对象,那么这个文件就变得非常难管理和维护。约定的命名方式是映射文件名和持久层类名(POJO)保持一致。例如,Account.class的映射文件名为Account.hbm.xml。或者,你也可以在类文件的代码里加上hibernate的注解,从而不需要使用配置文件。

Q.什么是SessionFactory?它是线程安全的吗?

A.SessionFactory对应Hibernate的一个数据存储的概念,并且它是线程安全的,可以被多个线程并发访问,也可以请求session和单个数据库的不可变编译过的映射的缓存。SessionFactory一般只会在启动的时候构建。对于应用代码,最好对SessionFactory通过单例的模式进行封装以便于访问。

1
SessionFactory
sessionFactory =
new

Configuration( ).configure( ).buildSessionfactory( );

Q.Session是什么?两个线程能共享同一个session吗?

A.Session是一个轻量级非线程安全的对象(线程间不能共享session),它表示与数据库进行交互的一个工作单元。Session是被SessionFactory创建的,在任务完成之后它会被关闭。Session是持久层服务对外提供的主要接口。Session会延迟获取数据库连接(也就是在需要的时候才会获取)。为了避免创建太多的session,可以使用ThreadLocal来取得当前的session,无论你调用多少次currentSession()方法,返回的都是同一个session。下面是示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public

class

HibernateUtil {
 
    public

static

final

ThreadLocal local =
new

ThreadLocal();
 
    public

static

Session currentSession()
throws

HibernateException {
 
         Session
session = (Session) local.get();
 
         //open
a new session if this thread has no session
 
        if(session
==
null)
{
 
            session
= sessionFactory.openSession();
 
            local.set(session);
 
       }
 
        return

session;
 
    }
 
}

有一点很重要的就是如果一个工作单元完成了,你需要关闭你的session。注意:保持你的Hibernate Session API简单易用。比较常见的场景是,hibernate会和spring框架一起使用,通过HibernateTemplate来整合。

Q.解释hibernate对象的状态?解释hibernate对象的生命周期?

A.持久层(persistent )对象和集合都是存活时间短暂的单线程对象,它们保存持久层的状态。这些对象的状态会根据你的刷新规则(例如,一旦有setXXX()方法被调用了就自动刷新,或者有数据项从集合、列表等删除时就刷新,你也可以通过session.flush()和transaction.commit()这两个函数调用来定义你自己的同步策略)来与数据库保持同步。如果你从一个持久层的集合(例如Set)里删除一项,那么它要么被立即从数据库里删除,或者当flush()或则commit()方法被调用时删除,具体的表现取决于你的刷新策略。它们都是普通的Java对象(POJO,Plain Old JavaObject),只不过当前关联了一个session。一旦关联的session被关闭,持久层对象就成为了游离对象(detached object),这时候你就可以在随便使用它们了,就像是用在业务层,持久层等其他应用层面的数据传输对象一样。

游离(detached )对象和集合都是和session相关联的持久层对象的实例,只不过它们现在没有和session进行关联。这种对象可以被随便使用,它不会对你的数据库有任何影响。游离对象后面也可以通过调用类似session.update(),session.saveOrUpdate()等方法来依附到其他的session上,然后再次成为持久层对象。

瞬态(transient)对象和集合是从来没有和session相关联的持久层对象的实例。这些对象可以自由使用,并且不会对你的数据库造成任何影响。当通过session.save(),session.persist()方法来使得瞬态对象和一个session进行关联时,瞬态对象就成为了持久层对象。

Q.使用游离对象(detached object)有什么好处呢?

优点:

  • 当因用户的思考时间而需要使用长事务时,最好的方式是把长事务分成一个或者多个事务。你可以使用来自于第一个事务的游离对象来承载持久层的所有数据。这些游离的对象在事务外被修改,然后可以通过另一个session来加入到新的事务里。

缺点:

  • 一般来说,使用游离对象的方式是比较笨重的,并且如果可以的话最好不要使得session变得比较混乱。最好的方式是丢弃这些对象,然后在后面的请求里重新获取新的对象。这个方式不仅更具有移植性,而且更加高效——因为这些对象会留在Hibernate的缓存里。
  • 同时,从纯粹的富领域驱动的方式来看,比较推荐的方式是使用DTO(DataTransferObject)和DO(DomainObject)来保持Service层和UI层之间的分离。

Q.什么时候对象会变成游离的?

A.

1
2
3
4
5
Session
session1 = sessionFactory.openSession();
 
Car
myCar = session1.get(Car.
class,
carId);    
//“myCar”这个时候是一个持久层对象
 
session1.close();      
//当session关闭时,“myCar”就成为了游离对象

现在你可以把“myCar”对象传到一直传到表示层里。它可以被修改并且对数据库表没有影响。

1
myCar.setColor(“Red”);
//对数据库没有影响

当你需要把修改持久化到数据库时,可以把游离对象加入到另外一个session里,示例如下:

1
2
3
4
5
6
7
8
9
Session
session2 = sessionFactory.openSession();
 
Transaction
tx = session2.beginTransaction();
 
session2.update(myCar);             
//游离对象”myCar“加入到session
 
tx.commit();                     
//修改被同步到数据库
 
session2.close()

Q.Hibernate怎么区别瞬态对象(例如,刚实例化的)和游离对象?

A.

  • 如果存在”version”这个属性的话,Hibernate会使用它来进行区别。
  • 如果不存在的话,会使用标识符值(identifier value)来进行判断。没有标识符表示这是一个新对象。这只适合Hibernate管理代理主键(surrogate key)的场景,不适合于使用自然主键(natural key)或者assigned代理主键(没有被Hibernate管理)的场景。
  • 通过InterceptorisUnsaved()来实现你自己的策略。

注意:当你重新关联游离的对象时,你必须保证依赖的对象也都被重新进行关联。

注意:这些问题都是来自于我的《Java/J2EE Job Interview Companion》一书。

Hibernate问题集锦: 概述的更多相关文章

  1. (转) Hibernate检索方式概述

    http://blog.csdn.net/yerenyuan_pku/article/details/70554816 Hibernate检索方式概述 我们在对数据库的操作中,最常用的是select, ...

  2. Hibernate面试问题集锦: 概述

    ImportNew注: 本文是ImportNew编译整理的Java面试题系列文章之一.你可以从这里查看全部的Java面试系列. Q.怎么配置Hibernate? A.Configuration类使用配 ...

  3. 【转】Hibernate面试问题集锦: 概述

    ImportNew注: 本文是ImportNew编译整理的Java面试题系列文章之一.你可以从这里查看全部的Java面试系列. Q.怎么配置Hibernate? A.Configuration类使用配 ...

  4. 【Hibernate一】概述及入门

    Hibernate学习框架: 1.基本部分      crud的操作      主键的生成机制      类型      持久化类      映射文件 *.hbm.xml      配置文件 hibe ...

  5. Hibernate 异常 集锦

    异常1.Error parsing JNDI name [foo] 异常信息摘要: org.hibernate.engine.jndi.JndiException: Error parsing JND ...

  6. Hibernate学习笔记(一)

    2016/4/18 19:58:58 Hibernate学习笔记(一) 1.Hibernate框架的概述: 就是一个持久层的ORM框架. ORM:对象关系映射.将Java中实体对象与关系型数据库中表建 ...

  7. Hibernate框架笔记01_环境搭建_API_CRUD

    目录 1. Hibernate框架的概述 1.1 什么是框架 1.2 经典三层架构 1.3 Hibernate框架 2 Hibernate入门 2.1 下载Hibernate的开发包 2.2 创建项目 ...

  8. Hibernate(1)基本知识

    hibernate初步 1.概述 ①hibernate是java应用和关系数据库之间的桥梁,是一个开源的对象关系映射框架,可用来把对象模型表示的java对象 映射到关系型数据库表中去. ②hibern ...

  9. Hibernate框架第一天

    **框架和CRM项目的整体介绍** 1. 什么是CRM * CRM(Customer Relationship Management)客户关系管理,是利用相应的信息技术以及互联网技术来协调企业与顾客间 ...

随机推荐

  1. 超详细 Linux 下编译安装Redis 以及php配套使用

    一.Linux 下安装Redis 下载地址:http://redis.io/download,下载最新文档版本. 把鼠标移到上图的绿色框上,就会显示下图提示:(直接右键复制链接就好) 本教程使用的旧版 ...

  2. Autofac is designed to track and dispose of resources for you.

    https://autofaccn.readthedocs.io/en/latest/best-practices/ Autofac is designed to track and dispose ...

  3. LeetCode——single-number系列

    LeetCode--single-number系列 Question 1 Given an array of integers, every element appears twice except ...

  4. fix LayerKit framework不能提交App Store

    - 问题: - 原因 x86_64, i386是ios模拟器用的architectures.发布时,不支持这两种.但是,默认编译出来的layerkit framework支持这两种编译器 - 解决办法 ...

  5. Android各种屏幕分辨率(VGA、HVGA、QVGA、WQVGA、WVGA、FWVGA) 详解 .

    http://blog.csdn.net/lucherr/article/details/8498400 看资料的时候经常看到各种VGA,全都混了,无奈,找了些资料总结了下,分享给大家: 这些术语都是 ...

  6. POJ 入门

    先复习一下C的一些基本概念 1.C标准化输出:scanf int m,n; scanf("%d%d",&n,&m); 实际上scanf是有返回值的,且返回值的类型为 ...

  7. MSSQL复制表操作

    1:复制表结构及数据到新表 select * into 目的数据库名.dbo.目的表名 from 原表名 select * into my0735home.dbo.infoMianTest from ...

  8. 使用springmvc报错Required int parameter 'age' is not present

    仔细检查jsp代码 <a href="springmvc/testRequestParam?username=atguigu$age=11">Test RequestP ...

  9. X2.5 添加自定义数据调用模块(简单方法)

    Discuz!X系列的diy功能还是相当不错的,在对其进行二次开发的过程中,或许需要加入新的数据调用模块,这样可以使你开发的功能模块也像原来的模块一样,只需要点点鼠标,填写一些简单的信息,就可以在各个 ...

  10. c#实现验证某个IP地址是否能ping通

    using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Net ...