资源描述
1.Hibernate工作原理及为何要用?
原理:
1.读取并解析配备文献
2.读取并解析映射信息,创建SessionFactory
3.打开Sesssion
4.创建事务Transation
5.持久化操作
6.提交事务
7.关闭Session
8.关闭SesstionFactory
为何要用:
1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作
3. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。
4. hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。
2.Hibernate是怎样延迟加载?
1. Hibernate2延迟加载实现:a)实体对象 b)集合(Collection)
2. Hibernate3 提供了属性的延迟加载功效
当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节约了服务器的内存开销,从而提升了服务器的性能。
3.Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系)
类与类之间的关系重要体目前表与表之间的关系进行操作,它们城市对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配备文献中的many-to-one、one-to-many、many-to-many、
4.说下Hibernate的缓存机制
1. 内部缓存存在Hibernate中又叫一级缓存,属于应用事物级缓存
2. 二级缓存:
a) 应用及缓存
b) 分布式缓存
条件:数据不会被第三方修改、数据大小在可接收范围、数据更新频率低、同一数据被系统频繁使用、非 核心数据
c) 第三方缓存的实现
5.Hibernate的查询方式
Sql、Criteria,object comptosition
Hql:
1、 属性查询
2、 参数查询、命名参数查询
3、 关联查询
4、 分页查询
5、 统计函数
6.怎样优化Hibernate?
1.使用双向一对多关联,不使用单向一对多
2.灵活使用单向一对多关联
3.不用一对一,用多对一取代
4.配备对象缓存,不使用集合缓存
5.一对多集合使用Bag,多对多集合使用Set
6. 继承类使用显式多态
7. 表字段要少,表关联不要怕多,有二级缓存撑腰
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
答案二:
hibernate工作原理:
1、通过Configuration().configure();读取并解析hibernate.cfg.xml配备文献。
2、由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml"/>读取解析映射信息。
3、通过config.buildSessionFactory();//得到sessionFactory。
4、sessionFactory.openSession();//得到session。
5、session.beginTransaction();//开启事务。
6、persistent operate;
6、session.getTransaction().commit();//提交事务
7、关闭session;
8、关闭sessionFactory;
hibernate优点:
1、封装了jdbc,简化了诸多重复性代码。
2、简化了DAO层编码工作,使开发更对象化了。
3、移植性好,支持各种数据库,假如换个数据库只要在配备文献中变换配备就能够了,不用变化hibernate代码。
4、支持透明持久化,因为hibernate操作的是纯粹的(pojo)java类,没有实现任何接口,没有侵入性。因此说它是一个轻量级框架。
hibernate延迟加载:
get不支持延迟加载,load支持延迟加载。
1、hibernate2对 实体对象和集合 实现了延迟加载
2、hibernate3对 提供了属性的延迟加载功效
hibernate延迟加载就是当使用session.load(User.class, 1)或者session.createQuery()查询对象或者属性的时候
这个对象或者属性并没有在内存中,只有当程序操作数据的时候,才会存在内存中,这么就实现延迟加载,节约了内存的开销,从而提升了服务器的性能。
Hibernate的缓存机制
一级缓存:session级的缓存也叫事务级的缓存,只缓存实体,生命周期和session一致。不能对其进行管理。
不用显示的调用。
二级缓存:sessionFactory缓存,也叫进程级的缓存,使用第3方插件实现的,也值缓存实体,生命周期和sessionFactory一致,能够进行管理。
首先配备第3放插件,我们用的是EHCache,在hibernate.cfg.xml文献中加入
<property name="hibernate.cache.user_second_level_cache">true</property>
在映射中也要显示的调用,<cache usage="read-only"/>
二级缓存之查询缓存:对一般属性进行缓存。假如关联的表发生了修改,那么查询缓存的生命周期也结束了。
在程序中必须手动启用查询缓存:query.setCacheable(true);
优化Hibernate
1、使用一对多的双向关联,尽也许从多的一端维护。
2、不要使用一对一,尽也许使用多对一。
3、配备对象缓存,不要使用集合缓存。
4、表字段要少,表关联不要怕多,有二级缓存撑腰。
(1)一般情况下,关系数据模型与对象模型之间有哪些匹配关系(多项选择)
A)表对应类B)统计对应对象C)表的字段对应类的属性
(2)如下有关SessionFactory的说法哪些正确?(多项选择)
)一个SessionFactory对象对应一个数据库存储源。C)SessionFactory是重量级的对象,不应当随意创建。假如系统中只有一个数据库存储源,只需要创建一个
(3)Customer类中有一个Set类型的orders属性,用来存储Order订单对象,在Customer.hbm.xml文献中,用哪个元素映射orders属性?
A) B) C) D)<:property>
(4)元素有一个cascade属性,假如希望Hibernate级联保存集合中的对象,casecade属性应当取什么值?(单项选择)
)save-update
(5)如下哪些属于Session的措施?
A)load()B)save()C)delete()D)update()E)open()F)close()
(6)如下程序的打印成果是什么?(单项选择)
1. tx = session.beginTransaction();
2. Customer c1=(Customer)session.load(Customer.class,new Long(1));
3. Customer c2=(Customer)session.load(Customer.class,new Long(1));
4. System.out.println(c1==c2);
5. mit();
6. session.close();
打印true
(7)如下程序代码对Customer的name属性修改了两次:
1. tx = session.beginTransaction();
2. Customer customer=(Customer)session.load(Customer.class,
3. new Long(1));
4. customer.setName(\"Jack\");
5. customer.setName(\"Mike\");
6. mit();
执行以上程序,Hibernate需要向数据库提交几条update语句?(单项选择)
B,1
(8)在持久化层,对象分为哪些状态?(多项选择)
A)暂时状态C)游离状态D)持久化状态
(9)对于如下程序,Customer对象在第几行变为持久化状态?(单项选择)
1. Customer customer=new Customer(); //line1
2. customer.setName(\"Tom\"); //line2
3. Session session1=sessionFactory.openSession(); //line3
4. Transaction tx1 = session1.beginTransaction(); //line4
5. session1.save(customer); //line4
6. mit(); //line5
7. session1.close(); //line6
A) line1 B)line2 C)line3 D)line4 E)line5 F)line6
(10)对于如下程序,Customer对象在第几行变为游离状态?(单项选择)
1. Customer customer=new Customer(); //line1
2. customer.setName(\"Tom\"); //line2
3. Session session1=sessionFactory.openSession(); //line3
4. Transaction tx1 = session1.beginTransaction(); //line4
5. session1.save(customer); //line4
6. mit(); //line5
7. session1.close(); //line6
)line6
(11)如下哪一个检索方略利用了外连结查询?(单项选择)
A)立即检索 B)延迟检索 C)迫切左外连结检索
(12)假设对Customer类的orders集合采取延迟检索方略,编译或运行如下程序,会出现什么情况(单项选择)
1. Session session=sessionFactory.openSession();
2. tx = session.beginTransaction();
3. Customer customer=(Customer)session.get(Customer.class,new Long(1));
4. mit();
5. session.close();
6. Iterator orderIterator=customer.getOrders().iterator();
A)编译犯错 B)编译通过,并正常运行 C)编译通过,但运行时抛出异常
(13)有关HQL与SQL,如下哪些说法正确?(多项选择)
A)HQL与SQL没什么差异B)HQL面对对象,而SQL操纵关系数据库C)在HQL与SQL中,都包括select,insert,update,delete语句D)HQL仅用于查询数据,不支持insert,update和delete语句
(14)事务隔离级别是由谁实现的?(单项选择)
A)Java应用程序 B)Hibernate C)数据库系统 D)JDBC驱动程序
(15)悲观锁与乐观锁,哪个具备很好的并发性能?(单项选择)
A)悲观锁 B)乐观锁
答案:
(1)A,B,C (2)B,C (3)A (4)D (5)A,B,C,D,F (6)C (7)B (8)A,C,D (9)D (10)F (11)C (12)C (13)B,D (14)C (15)B
Hibernate对象的三种状态是什么?
瞬时态(Transient)、 持久态(Persistent)、脱管态(Detached)。处在持久态的对象也称为PO(Persistence Object),瞬时对象和脱管对象也称为VO(Value Object)。
瞬时态
由new命令开辟内存空间的java对象,
eg. Person person = new Person(”amigo”, “女”);
假如没有变量对该对象进行引用,它将被java虚拟机回收。
瞬时对象在内存孤立存在,它是携带信息的载体,不和数据库的数据有任何关联关系,在Hibernate中,可通过session的save()或 saveOrUpdate()措施将瞬时对象与数据库有关联,并将数据对应的插入数据库中,此时该瞬时对象转变成持久化对象。
持久态
处在该状态的对象在数据库中具备对应的统计,并拥有一个持久化标识。假如是用hibernate的delete()措施,对应的持久对象就变成瞬时对象,因数据库中的对应数据已被删除,该对象不再与数据库的统计关联。
当一个session执行close()或clear()、evict()之后,持久对象变成脱管对象,此时持久对象会变成脱管对象,此时该对象虽然具备数据库识别值,但它已不在HIbernate持久层的管理之下。
持久对象具备如下特点:
1. 和session实例关联;
2. 在数据库中有与之关联的统计。
脱管态
当与某持久对象关联的session被关闭后,该持久对象转变为脱管对象。当脱管对象被重新关联到session上时,并再次转变成持久对象。
脱管对象拥有数据库的识别值,可通过update()、saveOrUpdate()等措施,转变成持久对象。
脱管对象具备如下特点:
1. 本质上与瞬时对象相同,在没有任何变量引用它时,JVM会在适当的时候将它回收;
2. 比瞬时对象多了一个数据库统计标识值。
Detached Object(游离对象)有什么好处?
Detached Object(游离对象)能够传递到任何层直到体现层而不是用任何DTO(Data Transfer Objects). 然后你还能够重新把游离对象赋给另外一个Session.
jdbc、hibernate、ibatis的区分?
jdbc:手动
手动写sql
delete、insert、update要将对象的值一个一个取出传到sql中,不能直接传入一个对象。
select:返回的是一个resultset,要从ResultSet中一行一行、一个字段一个字段的取出,然后封装到一个对象中,不直接返回一个对象。
ibatis的特点:半自动化
sql要手动写
delete、insert、update:直接传入一个对象
select:直接返回一个对象
hibernate:全自动
不写sql,自动封装
delete、insert、update:直接传入一个对象
select:直接返回一个对象
Hibernate怎样实现数据表映射的继承关系?
1、两个表,子类重复父类的属性。
2、一个表,子类父类共用一个表
<class name=”Users” table=”users” discriminator-value=”Users”>
<discriminator column=”DISCRIMINATOR_USERTYPE” type=”string”/>
<subclass name=”admin” discriminator-value=”admin”>
<property name=”adminRemark” column=”admin_remark” type=”string” />
</subclass>
</class>
3、两个表,子类引用父类的主键,享用公共的字段或属性。
<class name=”Users” table=”users”>
<id name=”userid” column=”USERID” type=”string”>
<generator class=”assigned”/>
</id>
<property name=”pwd” column=”pwd” type=”string” />
<joined-subclass name=”Guest” table=”guest”>
<key column=”USERID”/>
<property name=”guestRemark” column=”guest_remark” type=”string” />
</joined-subclass>
</class>
批量删除
Query query=session.createQuery(”update”或”delete”);
query.executeUpdate();
Hibernate中Query对象的使用
1 个或多个属性查询:
Query query=session.createQuery(”select customername,customerid from Customer”)
List l=query.list();
For(int i=0;i<l.size();i++)
{
Obejct[] object=(Object[])l.get(i);
Object[0] object[1]
}
}
分组: “select count(*),productname from Product group by productname order by productname”
取值与属性同样
配备的查询,在*.hbm.xml中
<query name=”sql”>
<![CDATA[
from Product where productid=:productid
]]>
</query>
Query query=session.getNamedQuery(sql);
联接1
”from Customer as customer join fetch customer.buySet”:将多的放到buySet属性中,得出的结是Customer有一个,Buy有多个
联接2
“from Customer as customer join customer.buySet”:得出的对象,customer与buy是1对1
子查询:
”from Customer as customer where (select count(*) from customer.buySet)>1″
Hibernate中Criteria 和DetachedCriteria的作用是什么?
Criteria c=session.createCriteria(Customer.class);
//设置条件
c.add(Expression.ge(“字段名”,”值对象”))
ge:>=
gt:>
le:<=
lt:<
eq:=
//排序
c.addOrder(Order.asc(“字段名”))
//分页
c.setFirstResult(1)//从第2行开始提取
c.setMaxResults(5)//返回5行
DetachedCriteria产生时不需要session
DetachedCriteria dc= DetachedCriteria.forClass(Customer.class)
Criteria c=Dc.getExecutableCriteria(session)
Hibernate中数据表映射关系重要有什么类型?
one-to-many
inverse:主控方,外键的关系有谁控制
inverse=false 是主控方,外键是由它控制的
inverse=true 是被控方,外键与它没关系
要想实现主控方的控制必须将被控方作为主控方的属性
cascade:级联
主表增从表增
主表修从表修
主表删从表删
lazy:延迟
lazy=false:一下将所有的内容取出,不延时(常用)
lazy=true:取出部分内容,其他内容动态去取
通过get能够取出对方的所有内容
hibernate的核心类是什么,它们的相互关系是什么?重要的措施是什么?
Configuration
SessionFactory
Session如下措施
Save
load
Update
Delete
Query q=CreateQuery(“from Customer where customerName=:customerName”)
beginTransaction
close
Transaction
Commit()
在myeclipse加入hibernate环境的全过程是什么?
1.Db-browers加入配备连接
2.新建工程
3.加入hibernate环境,指定*.hbm.xml及HibernateSessionFactory文献所在的位置
详细内容参见此前写的hibernate的第一个小例子
面试中常出现的两个Hibernate面试题及解答
1.在数据库中条件查询速度很慢的时候,怎样优化?
1.建索引
2.减少表之间的关联
3.优化sql,尽也许让sql很快定位数据,不要让sql做全表查询,应当走索引,把数据量大的表排在前面
4.简化查询字段,没用的字段不要,已经对返回成果的控制,尽也许返回少许数据
[2.在hibernate中进行多表查询,每个表中各取几个字段,也就是说查询出来的成果集并没有一个实体类与之对应,怎样处理这个问题?
处理方案一,按照Object[]数据取出数据,然后自己组bean
处理方案二,对每个表的bean写结构函数,例如表一要查出field1,field2两个字段,那么有一个结构函数就是Bean(type1 filed1,type2 field2) ,然后在hql里面就能够直接生成这个bean了。详细怎么用请看有关文档,我说的不是很清楚。
session.load()和session.get()的区分
Session.load/get措施均能够依照指定的实体类和id从数据库读取统计,并返回与之对应的实体对象。其区分在于:
假如未能发觉符合条件的统计,get措施返回null,而load措施会抛出一个ObjectNotFoundException。
Load措施可返回实体的代理类实例,而get措施永远直接返回实体类。
load措施能够充足利用内部缓存和二级缓存中的既有数据,而get措施则仅仅在内部缓存中进行数据查找,如没有发觉对应数据,将越过二级缓存,直接调用SQL完成数据读取。
Session在加载实体对象时,将通过的过程:
首先,Hibernate中维持了两级缓存。第一级缓存由Session实例维护,其中保持了Session目前所有关联实体的数据,也称为内部缓存。而第二级缓存则存在于SessionFactory层次,由目前所有由本 SessionFactory结构的Session实例共享。出于性能考虑,防止无谓的数据库访问,Session在调用数据库查询功效之前,会先在缓存中进行查询。首先在第一级缓存中,通过实体类型和id进行查找,假如第一级缓存查找命中,且数据状态合法,则直接返回。
之后,Session会在目前“NonExists”统计中进行查找,假如“NonExists”统计中存在同样的查询条件,则返回null。 “NonExists”统计了目前Session实例在之前所有查询操作中,未能查询到有效数据的查询条件(相称于一个查询黑名单列表)。如此一来,假如 Session中一个无效的查询条件重复出现,即可迅速作出判断,从而取得最佳的性能体现。
对于load措施而言,假如内部缓存中未发觉有效数据,则查询第二级缓存,假如第二级缓存命中,则返回。
如在缓存中未发觉有效数据,则发起数据库查询操作(Select SQL),如通过查询未发觉对应统计,则将本次查询的信息在“NonExists”中加以统计,并返回null。
依照映射配备和Select SQL得到的ResultSet,创建对应的数据对象。
将其数据对象纳入目前Session实体管理容器(一级缓存)。
执行Interceptor.onLoad措施(假如有对应的Interceptor)。
将数据对象纳入二级缓存。
假如数据对象实现了LifeCycle接口,则调用数据对象的onLoad措施。
返回数据对象。
Hibernate的主键生成机制
1) assigned
主键由外部程序负责生成,无需Hibernate参加。
2) hilo
通过hi/lo 算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态。
3) seqhilo
与hilo 类似,通过hi/lo 算法实现的主键生成机制,只是主键历史状态保存在Sequence中,适合用于支持Sequence的数据库,如Oracle。
4) increment
主键按数值次序递增。此方式的实现机制为在目前应用实例中维持一个变量,以保存着目前的最大值,之后每次需要生成主键的时候将此值加1作为主键。这种方式也许产生的问题是:假如目前有多个实例访问同一个数据库,那么因为各个实例各自维护主键状态,不一样实例也许生成同样的主键,从而导致主键重复异常。因此,假犹如一数据库有多个实例访问,此方式必须防止使用。
5) identity
采取数据库提供的主键生成机制。如DB2、SQL Server、MySQL中的主键生成机制。
6) sequence
采取数据库提供的sequence 机制生成主键。如Oralce 中的Sequence。
7) native
由Hibernate依照底层数据库自行判断采取identity、hilo、sequence其中一个作为主键生成方式。
8) uuid.hex
由Hibernate基于128 位唯一值产生算法生成16 进制数值(编码后以长度32 的字符串表示)作为主键。
9) uuid.string
与uuid.hex 类似,只是生成的主键未进行编码(长度16)。在某些数据库中也许出现问题(如PostgreSQL)。
10) foreign
使用外部表的字段作为主键。一般而言,利用uuid.hex方式生成主键将提供最佳的性能和数据库平台适应性。
这10中生成OID标识符的措施,increment 比较常用,把标识符生成的权力交给Hibernate处理.不过当同时多个Hibernate应用操作同一个数据库,甚至同一张表的时候.就推荐使用identity 依赖底层数据库实现,不过数据库必须支持自动增加,当然针对不一样的数据库选择不一样的措施.假如你不能确定你使用的数据库详细支持什么的情况下.能够选择用native 让Hibernate来帮选择identity,sequence,或hilo.
另外因为常用的数据库,如Oracle、DB2、SQLServer、MySql 等,都提供了易用的主键生成机制(Auto-Increase 字段或者Sequence)。我们能够在数据库提供的主键生成机制上,采取generator-class=native的主键生成方式。
不过值得注意的是,某些数据库提供的主键生成机制在效率上未必最佳,大量并发insert数据时也许会引起表之间的互锁。数据库提供的主键生成机制,往往是通过在一个内部表中保存目前主键状态(如对于自增型主键而言,此内部表中就维护着目前的最大值和递增量),之后每次插入数据会读取这个最大值,然后加上递增量作为新统计的主键,之后再把这个新的最大值更新回内部表中,这么,一次Insert操作也许导致数据库内部数次表读写操作,同时伴随的尚有数据的加锁解锁操作,这对性能产生了较大影响。因此,对于并发Insert要求较高的系统,推荐采取uuid.hex 作为主键生成机制
Struts,Spring,Hibernate面试题总结 收藏
Hibernate工作原理及为何要用?
原理:
1. 读取并解析配备文献
2. 读取并解析映射信息,创建SessionFactory
3. 打开Sesssion
4. 创建事务Transation
5. 持久化操作
6. 提交事务
7. 关闭Session
8. 关闭SesstionFactory
为何要用:
1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作
3. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。
4. hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。
2. Hibernate是怎样延迟加载?
1. Hibernate2延迟加载实现:a)实体对象 b)集合(Collection)
2. Hibernate3 提供了属性的延迟加载功效
当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节约了服务器的内存开销,从而提升了服务器的性能。
3. Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系)
类与类之间的关系重要体目前表与表之间的关系进行操作,它们城市对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配备文献中的many-to-one、one-to-many、many-to-many、
4. 说下Hibernate的缓存机制
1. 内部缓存存在Hibernate中又叫一级缓存,属于应用事物级缓存
2. 二级缓存:
a) 应用及缓存
b) 分布式缓存
条件:数据不会被第三方修改、数据大小在可接收范围、数据更新频率低、同一数据被系统频繁使用、非 核心数据
c) 第三方缓存的实现
5. Hibernate的查询方式
Sql、Criteria,object comptosition
Hql:
1、 属性查询
2、 参数查询、命名参数查询
3、 关联查询
4、 分页查询
5、 统计函数
6. 怎样优化Hibernate?
1. 使用双向一对多关联,不使用单向一对多
2. 灵活使用单向一对多关联
3. 不用一对一,用多对一取代
4. 配备对象缓存,不使用集合缓存
5. 一对多集合使用Bag,多对多集合使用Set
6. 继承类使用显式多态
7. 表字段要少,表关联不要怕多,有二级缓存撑腰
7. Struts工作机制?为何要使用Struts?
工作机制:
Struts的工作流程:
在web应用开启时就会加载初始化ActionServlet,ActionServlet从
struts-config.xml文献中读取配备信息,把它们存储到各种配备对象
当ActionServlet接收到一个客户祈求时,将执行如下流程.
-(1)检索和用户祈求匹配的ActionMapping实例,假如不存在,就返回祈求途径无效信息;
-(2)假如ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm 对象中;
-(3)依照配备信息决定是否需要表单验证.假如需要验证,就调用ActionForm的validate()措施;
-(4)假如ActionForm的validate()措施返回null或返回一个不包括ActionMessage的ActuibErrors对象, 就表示表单验证成功;
-(5)ActionServlet依照ActionMapping所包括的映射信息决定将祈求转发给哪个Action,假如对应的 Action实例不存在,就先创建这个实例,然后调用Action的execute()措施;
-(6)Action的execute()措施返回一个ActionForward对象,ActionServlet在把客户祈求转发给 ActionForward对象指向的JSP组件;
-(7)ActionForward对象指向JSP组件生成动态网页,返回给客户;
为何要用:
JSP、Servlet、JavaBean技术的出现给我们构建强大的企业应用系统提供了也许。但用这些技术构建的系统非常的繁乱,因此在此之上,我们需要一个规则、一个把这些技术组织起来的规则,这就是框架,Struts便应运而生。
基于Struts开发的应用由3类组件组成:控制器组件、模型组件、视图组件
8. Struts的validate框架是怎样验证的?
在struts配备文献中配备详细的错误提示,再在FormBean中的validate()措施详细调用。
9. 说下Struts的设计模式
MVC模式: web应用程序开启时就会加载并初始化ActionServler。用户提交表单时,一个配备好的Action
展开阅读全文