您的位置 首页 java

java面试-ssh-2

hibernate 介绍

hibernate是一个开源框架,它是对象关联关系映射的框架,它对 JDBC 做了轻量级的封装,而我们 Java 程序员可以使用面向对象的思想来操纵数据库。

Hibernate核心接口

Hibernate核心接口

1.session:负责被持久化对象CRUD操作

2.sessionFactory:负责初始化hibernate,创建session对象

3. Configuration :负责配置并启动hibernate,创建SessionFactory

4.Transaction:负责事物相关的操作

5. Query 和Criteria接口:负责执行各种数据库查询

详解:

1.Session接口:Session 接口负责执行被持久化对象的CRUD操作。 但需要注意的是 Session 对象是非线程安全的。

2.SessionFactory接口:SessionFactroy接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Sessio对象。

这里用到了工厂模式。 需要注意的是 SessionFactory 并不是轻量级的, 因为一般情况下, 一个项目通常只需要一个 SessionFactory 就够,

当需要操作多个数据库时,可以为每个数据库指定一个 SessionFactory。

3.Configuration 接口:Configuration 接口负责配置并启动 Hibernate,创建SessionFactory对象。

在Hibernate的启动的过程中, Configuration 类的实例首先定位映射文档位置、读取配置, 然后创建 SessionFactory 对象。

4.Transaction 接口:Transaction 接口负责事务相关的操作。它是可选的,开发人员也可以设计编写自己的底层事务处理代码。

5.Query 和 Criteria 接口:Query 和 Criteria 接口负责执行各种数据库查询。它可以使用 HQL

Hibernate工作原理及作用

1.读取并解析hibernate.cfg.xml配置文件:通过Configuration config = new Configuration().configure();

2.读取并解析映射信息:由hibernate.cfg.xml中的<mapping resource=”com/xx/User.hbm.xml”/>

3.创建SessionFactory:通过SessionFactory sf = config.buildSessionFactory();

4.打开Sesssion:Session session = sf.openSession();

5.创建并启动事务Transation:Transaction tx = session.beginTransaction();

6.操作数据,持久化操作:增删改查

7.提交事务tx.commit();

8.关闭Session

9.关闭SesstionFactory

怎样构建SessionFactory

Hibernate配置文件分为两种格式,一种是xml格式的配置文件,另一种是Java属性文件格式的配置文件

1.创建一个Configuration对象,并通过该对象的configura()方法加载Hibernate配置文件,代码如下。

Configuration config = new Configuration().configure();

configura()方法:用于告诉Hibernate加载hibernate.cfg.xml文件。Configuration在实例化时默认加载classpath中的hibernate.cfg.xml,当然也可以加载名称不是hibernate.cfg.xml的配置文件,例如wghhibernate.cfg.xml,可以通过以下代码实现。

Configuration config = new Configuration().configure(“wghhibernate.cfg.xml”);

2.完成配置文件和映射文件的加载后,将得到一个包括所有Hibernate运行期参数的Configuration实例,通过Configuration实例的buildSessionFactory()方法可以构建一个惟一的SessionFactory,代码如下:

SessionFactory sessionFactory = config.buildSessionFactory();

构建SessionFactory要放在静态代码块中,因为它只在该类被加载时执行一次。

3.从Java属性文件读取配置信息构建SessionFactory的具体步骤如下: [难]

1.创建一个Configuration对象,此时Hibernate会默认加载classpath中的配置文件hibernate.properties,代码如下。

Configuration config = new Configuration();

2.由于在配置文件中缺少相应的配置映射文件的信息,所以此处需要通过编码方式加载,这可以通过Configuration对象的addClass()方法实现, config.addClass(BranchForm.class);

addClass()方法用于加载实体类。

3.完成配置文件和映射文件的加载后,将得到一个包括所有Hibernate运行期参数的Configuration实例,通过Configuration实例的buildSessionFactory()方法可以构建一个惟一的SessionFactory,代码如下。

SessionFactory sessionFactory = config.buildSessionFactory();

为什么要用hibernate:

1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。

2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作

3. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。

4. hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。

Hibernate比JDBC的优点

1. 能使用JDBC的地方都能使用Hibernate

2. 对JDBC轻量封装,面向对象地操作数据库

3. 对不同的数据库比JDBC移植性好

4. 具有缓存机制(一级缓存和 二级缓存

5. 提供方便的HQL查询语言

配置文件

配置hibernate.cfg..xml:包含数据库URL,数据库用户名,密码,数据库,JDBC驱动

配置.hbm.xml:Hibernate根据.hbm.xml配置文件生成对应的SQL语句。

配置多表查询

一对多关联:在User.hbm.xml中配置<many-to-one=”dept”column=”deptid”class=”Dept” not-null=”true”/>

一对多:在多的一方的.hbm.xml使用<many-to-one>,在一方使用<one-to-many>

查询方式

1.HQL:面向对象: from User as user where user.age>20

2.QBC条件查询方式:Query by Criteria。主要有Criteria接口,Criterion接口,Expression类组成

Criteria criteria=session.createCriteria(User.class);

Criterition criterion =Expression.like(“username”,”%tome%”);

certeria.add(criterion);

List userList=query.list();

3.本地SQl查询:当应用程序需要数据库底层的数据库方言来执行特殊的SQL时

SQLQuery query=session.createSQLQuery(“select * from tb …”);

query.setParameter(“username”,”%tom%”);

List userList=query.list();

Hibernate如何延迟加载

1.当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,从而提高了服务器的性能。

在读取一个对象时,跟它相关联的对象有时也会执行。在实体的映射配置文件中的<class lazy=”true”>

对于Hibernate get方法,Hibernate会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在二级缓存中查找,还没有就查询数据库,数据库中没有就返回null。

2. Hibernate load方法加载实体对象的时候,根据映射文件上类级别的lazy属性的配置(默认为true),分情况讨论:

(1)若为true,则首先在Session缓存中查找,看看该id对应的对象是否存在,不存在则使用延迟加载,返回实体的代理类对象(该代理类为实体类的子类,由CGLIB动态生成)。等到具体使用该对象的时候,再查询二级缓存和数据库,若仍没发现符合条件的记录,则会抛出一个ObjectNotFoundException。

(2)若为false,就跟Hibernateget方法查找顺序一样,只是最终若没发现符合条件的记录,则会抛出一个ObjectNotFoundException。

get和load有两个重要区别:

1.如果未能发现符合条件的记录,Hibernate get方法返回null,而load方法会抛出一个ObjectNotFoundException。

load方法可返回没有加载实体数据的代理类实例,而get方法永远返回有实体数据的对象。

总之对于get和load的根本区别,一句话,hibernate对于 load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常;而对于get方法,hibernate一定要获取到真实的数据,否则返回null。

2.get()方法在内部缓存中没有打到相对应的数据时装直接执行SQL语句进行查询

load()方法查询数据时会先找Hibernate的内部缓存和二级缓存中的现有数据,

Hibernate如何实现类与类之间的关系(一对多,多对多)

类与类之间的关系主要体现在表与表之间的关系进行操作,它们都是对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、one-to-many、many-to-many进行映射

Hibernate的缓存机制

Hibernate经常访问物理磁盘数据,为了降低访问频次,使用缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据加快访问速度。

Hibernate缓存包括两大类:Hibernate一级缓存和Hibernate二级缓存。

1.Hibernate一级缓存又称为“Session的缓存”,由Hibernate管理。由于Session对象的生命周期通常对应一个数据库事务,因此它的缓存是事务范围的缓存。在第一级缓存中,持久化类的每个实例都具有唯一的OID。

2.Hibernate二级缓存又称为“SessionFactory的缓存”,由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此Hibernate二级缓存是进程范围或者集群范围的缓存,有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。第二级缓存是可选的,进可以行配置和更改, 并且可以动态加载和卸载。在默认情况下,SessionFactory不会启用这个插件。

Hibernate 中提供了两级 Cache, 配置二级缓存的主要步骤

1.第一级缓存:启用缓存的方式只要应用程序通过 Session 接口来执行保存、 更新、 删除、 加载和查询数据库数据的操作,Hibernate 就会启用第一级缓存,当应用程序调用 Session 的 save()、 update()、 savaeOrUpdate()、 get()或 load(), 以及调用查询接口的 list()、 iterate()或 filter()方法时, 如果在 Session 缓存中还不存在相应的对象, Hibernate 就会把该对象加入到第一级缓存中。

2. 二级缓存的管理:

1.条件查询的时候,总是发出一条select * from table_name where.. )这样的 SQL 语句查询数据库,一次获得所有的数据对象。

2.把获得的所有数据对象根据 ID放入到第二级缓存中。

3.当Hibernate根据ID访问数据对象的时候,首先从Session 一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;

查不到,再查询数据库,把结果按照ID放入到缓存。

4.删除、 更新、 增加数据的时候, 同时更新缓存。

3.Hibernate的二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无作用。 为此, Hibernate提供了针对条件查询的Query Cache。

什么样的数据适合存放到第二级缓存中?

1 很少被修改的数据

2 不会被并发访问的数据

如果类的实例被经常读但很少被修改, 就可以考虑使用第二级缓存。 只有为某个类或集合配置了第二级缓存, Hibernate 在运行时才会把它的实例加入到第二级缓存中。

Hibernate的查询方式

Sql、Criteria,Hql:

1、 属性查询

2、 参数查询、命名参数查询

3、 关联查询

4、 分页查询

5、 统计函数

如何优化Hibernate

1.使用双向一对多关联,不使用单向一对多

2.灵活使用单向一对多关联

3.不用一对一,用多对一取代

4.配置对象缓存,不使用集合缓存

5.一对多集合使用Bag,多对多集合使用Set

6. 继承类使用显式多态

7. 表字段要少,表关联不要怕多,有二级缓存撑腰

什么是 Hibernate 的并发机制? 怎么去处理并发问题

a、 Hibernate的Session对象是非线程安全的,对于单个请求,单个会话,单个线程,它通常只使用一次, 然后就丢弃。

如果一个Session实例允许共享的话,那些支持并发运行的,例如 Http request,session beans 将会导致出现资源争用。

如果在 HttpSession中有hibernate的Session的话,就可能会出现同步访问 Http Session。

只要用户足够快的点击浏览器的“刷新” , 就会导致两个并发运行的线程使用同一个Session。

b、 多个事务并发访问同一块资源,可能会引发第一类丢失更新,脏读,幻读 不可重复读,第二类丢失更新一系列的问题。

解决方案: 设置事务隔离级别。

Serializable: 串行化。 隔离级别最高

Repeatable Read: 可重复读

Read Committed: 已提交数据读

Read Uncommitted:未提交数据读。 隔离级别最差

设置锁: 乐观锁 和悲观锁。

为了解决这些并发带来的问题。 我们需要引入并发控制机制。

乐观锁: 乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测。在<class>的映射中设置 optimistic-lock=”all”。使用数据库版本和时间戳机制。

悲观锁: 假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。Hibernate 总是使用数据库的锁定机制, 从不在内存中锁定对象!只要为JDBC 连接指定一下隔离级别,然后让数据库去搞定一切就够了。

类LockMode 定义了 Hibernate 所需的不同的锁定级别:

LockMode.UPGRADE,LockMode.UPGRADE_NOWAIT,LockMode.READ;

Hibernate 与 jdbc 的联系

Hibernate是一个持久层的ORM的框架jdbc的轻量级封装,运用了面向对象的思想,将Java中的实体类与数据库的关系表建立一个映射.就可以操作Java中对象,从而操作数据库。HQL语句也是面向对象的,它的查询语句不是查询数据库而是查询类。

Hibernate 自带的分页机制是什么

hibernate 自带的分页机制:获得Session对象后,从Session中获得Query对象。

用Query.setFirstResult():设置要显示的第一行数据, Query.setMaxResults():设置要显示的最后一行数据。

不使用 hibernate 自带的分页,可采用sql语句分页。

5:为每页显示的记录,2 为当前页: select * top 5 from table where tabId not in (select tabId top (2-1)*5 from table);

update( )和 saveOrUpdate( )的区别

update()和 saveOrUpdate()是用来对跨Session的PO进行状态管理的。

update:更新操作,没有主键时会抛异常。也就是说, 如果此对象在数据库中不存在的话,就不能使用 update()方法。update()方法操作的对象必须是持久化了的对象。

saveOrUpdate:保存和更新,没有主键就执行插入操作。

Hibernate 的三种状态之间如何转换

1.Hibernate三种状态之一:瞬时状态(Transient):,在一个对象刚被创建的时候,比如People people = new People(),它没有持久化,并没有处于Session的缓存中,这种状态的对象叫就是临时对象;

2.Hibernate三种状态之二:持久化状态(Persistent):已经执行了session的save()方法,已经持久化,加入到了Session缓存中,并且在数据库中具有对应的记录,并拥有一个持久化标识。处于此状态的对象叫持久对象。

此时如果使用hibernate的delete()方法,对应的持久对象就变成上面的瞬时对象,因为数据库中的对应数据已被删除,该对象不再与数据库的记录关联。

当一个session执行close()或clear()、evict()之后,持久对象变成下面要讲的脱管对象,此时持久对象会变成脱管对象,此时该对象虽然具有数据库识别值,但它已不在Hibernate持久层的管理之下,也就是它在session缓存中的记录已经被删除了。

3.Hibernate三种状态之三:脱管状态(Detached):持久化对象脱离了Session的对象。如当session关闭时,Session缓存被清空的对象。特点:已经持久化,但不在Session缓存中。处于此状态的对象叫游离对象;因关闭session而变成游离态的可以通过lock、save、update变成持久态 。

session对象的evict()和clear()的区别、refresh()和flush()的区别。

1.flush() flush只会操作持久化状态的对象,或者说只会操作一级缓存中的对象。flush只是执行了sql语句,但没有执行commit方法。对于临时对象和游离对象不做任何操作。

2.refresh() 和flush类似,只不过是方向相反。flush是把session缓存中的对象往数据库中更新,而refresh是把数据库中的对象往session缓存中更新。

3.evict() 该方法是从一级缓存中把持久化对象移除。

4.clear() 清理session中的所有缓存。

Hibernate 主键介绍

1.Assigned方式由程序生成主键值,并且要在session.save()之前指定否则会抛出异常特点:主键的生成值完全由用户决定,与底层数据库无关。

2.Hilo 使用高低位算法生成主键,高低位算法使用一个高位值和一个低位值, 然后把算法得到的两个值拼接起来作为数据库中的唯一主键。

3.Increment方式对主键值采取自动增长的方式生成新的主键值,但要求底层数据库的支持 Sequence

4.Identity 当时根据底层数据库,来支持自动增长,不同的数据库用不同的主键增长方式。

特点:与底层数据库有关,要求数据库支持Identity,如 MySQl 中是auto_increment, SQL Server 中是 Identity, 支持的数据库有 MySql、 SQL Server、 DB2、 Sybase 和 HypersonicSQL。 Identity无需 Hibernate 和用户的干涉, 使用较为方便, 但不便于在不同的数据库之间移植程序。

5.Sequence需要底层数据库支持 Sequence 方式

6.Native主键生成方式会根据不同的底层数据库自动选择 Identity、 Sequence、 Hilo 主键生成方式

7.UUID使用 128 位 UUID 算法生成主键, 能够保证网络环境下的主键唯一性, 也就能够保证在不同数据库及不同服务器下主键的唯一性。

事务控制:

1. 获取Session:session = sessionFactory.openSession();

2. 开始事务:Transacation ts=session.beginTransacation();

3. 数据库操作

4. 提交事务:ts.commit();

5. 事务回滚:ts.rollback();

6. 关闭session:session.close()

Hibernate 的抓取策略

抓取策略是指当应用程序需要利用关联关系进行对象获取的时候。

Hibernate中映射文件<hibernate-mapping> inverse属性和cascade属性的区别

1.inverse属性只存在于集合标记的元素中集合元素包括<set/>,<map/>,<list/>,<array/>,<bag/>

Inverse属性的作用是是否将对集合对象的修改反射到数据库中 inverse=”false”时修改反射到数据库中 inverse=”true” 时修改不反射到数据库中

2.Cascade属性的作用是描述关联对象进行操作时的级联特性,因此只有涉及到关系的元素才有cascade属性

如果希望Hibernate级联保存集合中的对象,<set>元素有一个cascade属性应该取save-update

Spring 是什么? 根据你的理解详细谈谈你的见解

*Spring框架是对三大框架的整合,可以将简单的组件配置、组合成为复杂的应用。

有对三层的每层解决方案:* web层:Spring MVC.* 持久层:JDBC Template * 业务层:Spring的Bean管理.

Spring是一个集合框架,是用来管理类的框架,利用一些编程思想,比如AOP和IOC,来管理它们之间的互相调用和依赖关系。

针对接口编程而不是针对类编程可以实现解耦;通过DAO层和关系映射更好的和hibernate进行整合;还提供了MVC框架,更好的和Struts整合。

总的来说,spring是一个集成了许多第三方框架的大杂烩,其核心技术是IOC(控制反转,也称依赖注入)和AOP(面向切面编程)。

Spring的七个模块

Spring core,Spring AOP,Spring ORM,Spring WEB,Spring MVC,Spring DAO,Spring Context

(1) spring AOP –面象切面编程

(2)spring DAO –数据访问对象

(3)spring ORM –对象关系影射

(4)spring Contect — 上下文配置,向Spring框架提供上下文信息

(5)spring WEB – -WEB上下文模块

(6)\spring WEB-MVC –实现了MVC

(7)spring CORE –核心容器提供Spring框架基本功能

Spring核心接口和类

1. BeanFactory:getBean,getType等。定义了IOC容器的基本功能,负责读取bean配置文档,管理bean加载实例化和生命周期。

2. XmlBeanFactory类:继承DefaultListableBeanFactory。一个与XMl相关的BeanFactory实现类

ClassPathResource res =newClassPathResource(“cintainer.xml”);

XMLBeanFactory factory = new XmlFactory(res);

3. ApplicationContext类:高级形态的IOC容器。支持国际化,支持监听机制

4. Resource接口:访问文件资源。常用ClassPathResource,FileSystemResource,ServletContextResource

5. ThrowsAdvice接口:标记接口

Spring的优点:

1. Spring的Ioc机制降低了代码的耦合性

2. 独立于各种应用服务器,可以实现一次编写,到处运行。

3. 开发人员可以自行使用Spring部分模块

XML配置文件

<?xml version=”1.0” encoding=”UTF-8”?>

<beans xmlns=””

xmlns:xsi=””

xsi:shcemaLoaction=”

”>

<beans id = “” class=””>

<bean></bean>

</beans>

数据源配置 :

<bean id =”dataSource” class=”org.springframework.jdbc.datasource.DriverManagerDataSource”>

<property name=”driverClassName”>

<value>com.mysql.jdbc.Driver</value>

</property>

url,username,password

</bean>

事务配置

1. 传播策略:propagation

2. 隔离性:isolation

3. 超时时间:timeout

4. 只读:readOnly

文章来源:智云一二三科技

文章标题:java面试-ssh-2

文章地址:https://www.zhihuclub.com/184018.shtml

关于作者: 智云科技

热门文章

网站地图