以下是小编整理的hibernate面试题(共含11篇),欢迎阅读分享,希望对大家有帮助。同时,但愿您也能像本文投稿人“heweida”一样,积极向本站投稿分享好文章。
1. 请解释Hibernate3.2主键的生成方式中,native和identity方式的区别。
Native主键生成方式会根据不同的底层数据库自动选择Identity、Sequence、Hilo主键生成方式
特点:根据不同的底层数据库采用不同的主键生成方式。由于Hibernate会根据底层数据库采用不同的映射方式,因此便于程序移植,项目中如果用到多个数据库时,可以使用这种方式。
Identity根据底层数据库,来支持自动增长,不同的数据库用不同的主键增长方式。
特点:与底层数据库有关,要求数据库支持Identity,如
MySQl中是auto_increment,
SQL Server 中是Identity,支持的数据库有MySql、SQL Server、DB2、Sybase和HypersonicSQL。
Identity无需Hibernate和用户的干涉,使用较为方便,但不便于在不同的数据库之间移植程序。
2. 请解释为什么SessionFactory一般以单利方式使用。
SessionFactory是一个大型对象,而且线程安全。在一个程序中只需要一个
3. 请解释说明hibernate配置文件中dialect属性的确切含义。
数据库方言:多种数据库拥有不同的语言语法,通过设置dialect指定所用的数据库,并生成对应语法和语言的sql语句。
4,请解释说明Hibernate控制下的POJO<对象>会呈现三种状态,分别是transient、persistenet和detached,请解释这三种状态。
暂态:数据库中没数据。跟session不相关。没存过。
游离态:在数据库中有记录,但是在session中没有。需要手工同步。
持久态:数据库中有记录,session中也有这记录。自动更新
5. 请解释Session的load方法和get方法的不同;
load 在加载的时候会根据加载策略来加载东西,加载策略默认为延迟加载,即只加载id.,如果需要用其它数据,必须在session关闭之前,去加载某一 个属性。lazy=“true” or “false” 如果加载策略是立即加载,那么它在加载时会把数据信息全部加载,这个时候即使,关闭session,因为数据已经全部加载了,也能取得数据
get 会直接采用立即加载策略加载数据,不管你配置的是延迟加载还是立即加载
关于立即加载和延迟加载 不仅只对自己这张表,将来表与表之间有关系时,一样会起作用。
如果对象不存在 get返回null load抛异常
6.请解释cascade属性和-orphan的区别。
: 在执行 时进行关联操作。
all--orphan: 当一个节点在对象图中成为孤儿节点时,删除该节点。比如在一个一对多的关系中,Student包含多个book,当在对象关系中删除一个book时,此book即成为孤儿节点。
7.请解释inverse属性的作用
inverse表“是否放弃维护关联关系”(在Java里两个对象产生关联时,对数据库表的影响),在one-to-many和many-to-many的集合定义中使用,inverse=“true”表示该对象不维护关联关系;该属性的值一般在使用有序集合时设置成false(注意hibernate的缺省值是false)。 one-to-many维护关联关系就是更新外键。many-to-many维护关联关系就是在中间表增减记录。
8.请解释Hibernate查询中出现的N+1问题,并提出解决方案。
Hibernate在检索与Customer关联的Order对象时,使用了默认的立即检索策略。这种检索策略存在两大不足:
(1) select语句的数目太多,需要频繁的访问数据库,会影响检索性能。如果需要查询n个Customer对象,那么必须执行n+1次select查询语句。这就是经典的n+1次select查询问题。
(2)在应用逻辑只需要访问Customer对象,而不需要访问Order对象的场合,加载Order对象完全是多余的操作,这些多余的Order对象白白浪费了许多内存空间。
为了解决以上问题,Hibernate提供了其他两种检索策略:延迟检索策略和迫切左外连接检索策略。延迟检索策略能避免多余加载应用程序不需要访问的关联对象,迫切左外连接检索策略则充分利用了SQL的外连接查询功能,能够减少select语句的数目。
9.请简要的描述一下使用Hibernate进行大批量更新的经验;
直接使用hibernate API 进行批量更新和批量删除都不推荐,而直接通过JDBC API执行相关的SQl语句或调用相关的存储过程是最佳的方式。
10,请简要的描述一下使用Hibernate二级高速缓存的经验
1.Hibernate3的二级缓存和session级别的缓存一样都只对实体对象做缓存,不对属性级别的查询做缓存;二级缓存的生命周期和sessionFactory的生命周期是一样的,sessionFactory可以管理二级缓存;
2.sessionFactory级别的缓存,需要手动配置;所有的session可以共享sessionFactory 级别的缓存;(一般把一些不经常变化的实体对象放到sessionFactory级别的缓存中,适合放不经常变化的实体对象。)
3.Hiberante3二级缓存的配置和使用方法如下:
必须把ehcache.jar包导入,然后到Hibernate3.2的etc文件下把ehcache.xml复制到工程src目录下(ehcache.xml里边的参数里边有详细英文说明);
说明:ehcache.jar是第三方法的缓存产品,hiberante只是把它做了集成,还有好多第三方hibernate集成的缓存产品,相关说明请查阅hiberante3开发手册;ehcache是不支持分布应用的,如果有分布式需求,请换成支持分布式的二级缓存产品,hiberate3开发手册都有相头说明。配置方法都类似);
4.Hibernate3的二级缓存默认是开起的,也可以指定开起。
11,Query的list和iterator方法的不同。
list不会使用缓存,而iterate会先取数据库select id出来,然后一个id一个id的load,如果在缓存里面有,就从缓存取,没有的话就去数据库load。
不管是list方法还是iterate方法,第一次查询的时候,它们的查询方式很它们平时的方式是一样的,list执行一条sql,iterate执行1+N条,多出来的行为是它们填充了缓存
查询缓存需要打开相关类的class缓存。list和iterate方法第一次执行的时候,都是既填充查询缓存又填充class缓存的。
这里还有一个很容易被忽视的重要问题,即打开查询缓存以后,即使是list方法也可能遇到1+N的问题!
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,objectcomptosition
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。用户提交表单时,一个配置好的ActionForm对象被创建,并被填入表单相应的数据,ActionServler根据Struts-config.xml文件配置好的设置决定是否需要表单验证,如果需要就调用ActionForm的Validate()验证后选择将请求发送到哪个Action,如果Action不存在,ActionServlet会先创建这个对象,然后调用Action的execute()方法。Execute()从ActionForm对象中获取数据,完成业务逻辑,返回一个ActionForward对象,ActionServlet再把客户请求转发给ActionForward对象指定的jsp组件,ActionForward对象指定的jsp生成动态的网页,返回给客户。
10.spring工作机制及为什么要用?
1.springmvc请所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进行真正的处理工作。
2.DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的Controller.
3.DispatcherServlet请请求提交到目标Controller
4.Controller进行业务逻辑处理后,会返回一个ModelAndView
5.Dispathcher查询一个或多个ViewResolver视图解析器,找到ModelAndView对象指定的视图对象
6.视图对象负责渲染返回给客户端。
为什么用:
{AOp让开发人员可以创建非行为性的关注点,称为横切关注点,并将它们插入到应用程序代码中。使用AOp后,公共服务(比如日志、持久性、事务等)就可以分解成方面并应用到域对象上,同时不会增加域对象的对象模型的复杂性。
IOC允许创建一个可以构造对象的应用环境,然后向这些对象传递它们的协作对象。正如单词倒置所表明的,IOC就像反过来的JNDI。没有使用一堆抽象工厂、服务定位器、单元素(singleton)和直接构造(straightconstruction),每一个对象都是用其协作对象构造的。因此是由容器管理协作对象(collaborator)。
Spring即使一个AOp框架,也是一IOC容器。Spring最好的地方是它有助于您替换对象。有了Spring,只要用JavaBean属性和配置文件加入依赖性(协作对象)。然后可以很容易地在需要时替换具有类似接口的协作对象。}
Spring框架是一个分层架构,由7个定义良好的模块组成。Spring模块构建在核心容器之上,核心容器定义了创建、配置和管理bean的方式,如图1所示。
组成Spring框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:
☆核心容器:核心容器提供Spring框架的基本功能。核心容器的主要组件是BeanFactory,它是工厂模式的实现。BeanFactory使用控制反转(IOC)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
☆Spring上下文:Spring上下文是一个配置文件,向Spring框架提供上下文信息。Spring上下文包括企业服务,例如JNDI、EJB、电子邮件、国际化、校验和调度功能。
☆SpringAOp:通过配置管理特性,SpringAOp模块直接将面向方面的编程功能集成到了Spring框架中。所以,可以很容易地使Spring框架管理的任何对象支持AOp。SpringAOp模块为基于Spring的应用程序中的对象提供了事务管理服务。通过使用SpringAOp,不用依赖EJB组件,就可以将声明性事务管理集成到应用程序中。
☆SpringDAO:JDBCDAO抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。SpringDAO的面向JDBC的异常遵从通用的DAO异常层次结构。
☆SpringORM:Spring框架插入了若干个ORM框架,从而提供了ORM的对象关系工具,其中包括JDO、Hibernate和iBatisSQLMap。所有这些都遵从Spring的通用事务和DAO异常层次结构。
☆SpringWeb模块:Web上下文模块建立在应用程序上下文模块之上,为基于Web的应用程序提供了上下文。所以,Spring框架支持与JakartaStruts的集成。Web模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
☆SpringMVC框架:MVC框架是一个全功能的构建Web应用程序的MVC实现。通过策略接口,MVC框架变成为高度可配置的,MVC容纳了大量视图技术,其中包括JSp、Velocity、Tiles、iText和pOI。
Spring框架的功能可以用在任何J2EE服务器中,大多数功能也适用于不受管理的环境。Spring的核心要点是:支持不绑定到特定J2EE服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同J2EE环境(Web或EJB)、独立应用程序、测试环境之间重用。
IOC和AOp
控制反转模式(也称作依赖性介入)的基本概念是:不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。容器(在Spring框架中是IOC容器)负责将这些联系在一起。
在典型的IOC场景中,容器创建了所有对象,并设置必要的属性将它们连接在一起,决定什么时间调用方法。下表列出了IOC的一个实现模式。
Spring框架的IOC容器采用类型2和类型3实现。
面向方面的编程
面向方面的编程,即AOp,是一种编程技术,它允许程序员对横切关注点或横切典型的职责分界线的行为(例如日志和事务管理)进行模块化。AOp的核心构造是方面,它将那些影响多个类的行为封装到可重用的模块中。
AOp和IOC是补充性的技术,它们都运用模块化方式解决企业应用程序开发中的复杂问题。在典型的面向对象开发方式中,可能要将日志记录语句放在所有方法和Java类中才能实现日志功能。在AOp方式中,可以反过来将日志服务模块化,并以声明的方式将它们应用到需要日志的组件上。当然,优势就是Ja
[java经典面试题struts,hibernate,spring]
一、Annotaion配置
小实验1:
(1)编写hunsband.java,属性为id,name,wife,id是主键
(2)编写wife.java,属性为id,name。id是主键
(3)实现方式:在husband.java中,用wife作为外键关联wife.java中的主键id
Husband.java
package com.zgy.hibernate.model;import javax.persistence.Entity;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.OneToOne;@Entitypublic class Husband {private int id;private String name;private Wife wife;@Idpublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@OneToOne@JoinColumn(name=“wifeId”)public Wife getWife() {return wife;}public void setWife(Wife wife) {this.wife = wife;}}Wife.javapackage com.zgy.hibernate.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;@Entitypublic class Wife {private int id;private String name;@Idpublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}
Junit测试
package com.zgy.hibernate.model;import static org.junit.Assert.*;import java.util.Date;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.AnnotationConfiguration;import org.junit.AfterClass;import org.junit.BeforeClass;import org.junit.Test;public class ORMapppingTest {public static SessionFactory sf = null;@BeforeClasspublic static void beforeClass(){sf = new AnnotationConfiguration().configure().buildSessionFactory();}@Testpublic void test() {Husband h = new Husband();Wife w = new Wife();Session session2 = sf.openSession();session2.beginTransaction();w.setId(1);w.setName(“李四”);session2.save(w);session2.getTransaction().commit();Session session1 = sf.openSession();session1.beginTransaction();h.setId(1);h.setName(“张三”);h.setWife(w);session1.save(h);session1.getTransaction().commit();}@AfterClasspublic static void afterClass(){sf.close();}}
观察结果:
1、观察hibernate生成的sql语句:
Hibernate: create table Husband (id integer not null, name varchar(255), wifeId integer, primary key (id))Hibernate: create table Wife (id integer not null, name varchar(255), primary key (id))Hibernate: alter table Husband add constraint FK_kruq9jfxa0jrc2od8dbh09mia foreign key (wifeId) references Wife (id)
2、如果不加@JoinColumn(name=“wifeId”),在husband表将增加了关联wife表主键的外键wife_id。
3、使用sql语句:show create table husband;可以看到如下sql语句
CREATE TABLE `husband` (`id` int(11) NOT NULL,`name` varchar(255) DEFAULT NULL,`wife_id` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `FK_4565w2c4f1cj082spdiok0w6` (`wife_id`),CONSTRAINT `FK_4565w2c4f1cj082spdiok0w6` FOREIGN KEY (`wife_id`) REFERENCES `wife` (`id`))
4、加入@JoinColumn(name=“wifeId”)可以修改husband表中外键的列的名称。再次运行show create table husband;可以看到如下片段
CREATE TABLE `husband` (`id` int(11) NOT NULL,`name` varchar(255) DEFAULT NULL,`wifeId` int(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `FK_kruq9jfxa0jrc2od8dbh09mia` (`wifeId`),CONSTRAINT `FK_kruq9jfxa0jrc2od8dbh09mia` FOREIGN KEY (`wifeId`) REFERENCES `wife` (`id`))
二、xml配置
在xml中配置one2one的方法如下:
观察结果: 1.在xml中配置的是many-to-one和 unique=“true” 1.使用如下的Annotation设置一对一单项主键关联(目前没有成功过,Hibernate文档上所写,但是没有成功实现过) @OneToOne @PrimaryKeyJoinColumn 2.xml中的配置 person 一、Annotation配置 1.在一对一双向外键关联的时候,可以使用@OneToOne(mappedBy=“对象名”)的方式设置。 2.凡是双向关联,必设MappedBy Husband.javapackage com.zgy.hibernate.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.OneToOne;@Entitypublic class Husband {private int id;private String name;private Wife wife;@Id@GeneratedValuepublic int getId {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@OneToOnepublic Wife getWife() {return wife;}public void setWife(Wife wife) {this.wife = wife;}}Wife.javapackage com.zgy.hibernate.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.OneToOne;@Entitypublic class Wife {private int id;private String name;private Husband husband;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@OneToOne(mappedBy=“wife”)public Husband getHusband() {return husband;}public void setHusband(Husband husband) {this.husband = husband;}} 二、xml设置: 范例: 一、Annotation配置 1.在wife.java中使用id和name作为联合主键 2.在husband.java中关联到wife.java中的联合主键 范例: Wife.java package com.zgy.hibernate.model;import java.io.Serializable;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.IdClass;import javax.persistence.OneToOne;import javax.persistence.PrimaryKeyJoinColumn;@Entity@IdClass(WifePK.class)public class Wife {private int id;private String name;private int age;@Idpublic int getId() {return id;}@Idpublic void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}} Wife类的联合主键类WifePK.java package com.bjsxt.hibernate;import java.io.Serializable;public class WifePK implements Serializable {private int id;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}Huaband.javapackage com.zgy.hibernate.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinColumns;import javax.persistence.OneToOne;@Entitypublic class Husband {private int id;private String name;private Wife wife;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@OneToOne@JoinColumns({@JoinColumn(name=“wifeId”,referencedColumnName=“id”),@JoinColumn(name=“wifeName”,referencedColumnName=“name”)})public Wife getWife() {return wife;}public void setWife(Wife wife) {this.wife = wife;}} 观察结果: 1.在husband.java中,只使用@OneToOne,则会在husband表中自动生成wife_id ,wife_name两个字段。show create table husband; CREATE TABLE `husband` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`wife_id` int(11) DEFAULT NULL,`wife_name` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`),KEY `FK_4565w2c4f1cj082spdiok0w6` (`wife_id`),CONSTRAINT `FK_4565w2c4f1cj082spdiok0w6` FOREIGN KEY (`wife_id`) REFERENCES `wife` (`id`)) 2.使用@JoinColumns( {@JoinColumn(name=“wifeId”,referencedColumnName=“id”),@JoinColumn(name=“wifeName”,referencedColumnName=“name”)}) 可以自定义husband表中关联联合主键的列的名称 2.加入以上Annotation之后,再观察结果show create table husband; CREATE TABLE `husband` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`wifeId` int(11) DEFAULT NULL,`wifeName` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`),KEY `FK_sdshifqwgidsm93jdh5kfl0e4` (`wifeId`,`wifeName`),CONSTRAINT `FK_sdshifqwgidsm93jdh5kfl0e4` FOREIGN KEY (`wifeId`, `wifeName`) REFERENCES `wife` (`id`, `name`)) 一、Annotation配置 1.不将wife.java作为实体类 2.在husband.java中,使用组件映射,关联wife.java中的wifeName和age 范例: Wife.java中,不将wife作为是实体类 package com.zgy.hibernate.model;import java.io.Serializable;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.IdClass;import javax.persistence.OneToOne;import javax.persistence.PrimaryKeyJoinColumn;public class Wife {private String wifeName;private int age;public String getWifeName {return wifeName;}public void setWifeName(String wifeName) {this.wifeName = wifeName;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}Husband.java中使用@Embeddedpackage com.zgy.hibernate.model;import javax.persistence.Embedded;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinColumns;import javax.persistence.OneToOne;@Entitypublic class Husband {private int id;private String name;private Wife wife;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Embeddedpublic Wife getWife() {return wife;}public void setWife(Wife wife) {this.wife = wife;}} 观察结果: 使用show create table husband; CREATE TABLE `husband` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`age` int(11) NOT NULL,`wifeName` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)) 二、xml配置 <?xml version=“1.0”?> A、多对一单向关联 例如:一个人可以有多个梦想 可以有如下设计 1、person表 2、dream表 错误的做法: I、错误的做法:在一方加冗余 person表 personid personname dream 1 zhangsan 1 1 zhangsan 2 dream表 dreamid dreamdesc 1 Make money 2 Eat a lot 正确的做法: 数据表设计:在多方加外键 小实验1: 1.设计一个Group.java类,此类包含id、name属性 2.设计一个User.java类,此类包含id、name、group属性 3.对应关系:一个用于属于一个组,一个组含有多个用户,user对group的关系就是many-to-one单项映射关系 4.Group.java package com.zgy.hibernate.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.Table;@Entity@Table(name=“t_group”)public class Group {private int id;private String name;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}} 5.User.java package com.zgy.hibernate.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.Table;@Entity@Table(name=“t_user”)public class User {private int id;private String name;private Group group;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@ManyToOne@JoinColumn(name=“groupId”)public Group getGroup() {return group;}public void setGroup(Group group) {this.group = group;}} 6.Junit测试 package com.zgy.hibernate.model;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.AnnotationConfiguration;import org.junit.AfterClass;import org.junit.BeforeClass;import org.junit.Test;public class ORMapppingTest {public static SessionFactory sf = null;@BeforeClasspublic static void beforeClass(){sf = new AnnotationConfiguration().configure().buildSessionFactory();}@Testpublic void test() {Group g = new Group();User u = new User();Session session1 = sf.openSession();session1.beginTransaction();g.setId(1);g.setName(“第一组”);session1.save(g);session1.getTransaction().commit();Session session2 = sf.openSession();session2.beginTransaction();u.setId(1);u.setName(“张三”);session2.save(u);session2.getTransaction().commit();}@AfterClasspublic static void afterClass(){sf.close();}} 7.观察产生的sql语句: Hibernate: create table t_group (id integer not null auto_increment, name varchar(255), primary key (id))Hibernate: create table t_user (id integer not null auto_increment, name varchar(255), groupId integer, primary key (id))Hibernate: alter table t_user add constraint FK_7ktm6l2qkykpqrf6oq01ys8wy foreign key (groupId) references t_group (id) 1.Group.hbm.xml <?xml version=“1.0”?> 3.观察产生的sql语句 Hibernate: create table t_group (id integer not null auto_increment, name varchar(255), primary key (id))Hibernate: create table t_user (id integer not null auto_increment, name varchar(255), groupId integer, primary key (id))Hibernate: alter table t_user add constraint FK_7ktm6l2qkykpqrf6oq01ys8wy foreign key (groupId) references t_group (id) B、一对多单向关联 1.类:在一的一方存在多的一方的集合 2.数据库同上 i、Group.java package com.zgy.hibernate.model;import java.util.HashSet;import java.util.Set;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.OneToMany;import javax.persistence.Table;@Entity@Table(name=“t_group”)public class Group {private int id;private String name;private Set ii、User.java package com.zgy.hibernate.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.Table;@Entity@Table(name=“t_user”)public class User {private int id;private String name;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}} iii、观察生成的sql Hibernate: create table t_group (id integer not null auto_increment, name varchar(255), primary key (id))Hibernate: create table t_user (id integer not null auto_increment, name varchar(255), groupId integer, primary key (id))Hibernate: alter table t_user add constraint FK_7ktm6l2qkykpqrf6oq01ys8wy foreign key (groupId) references t_group (id) i、Group.hbm.xml <?xml version=“1.0”?> ii、User.hbm.xml <?xml version=“1.0”?> iii、观察生成的sql语句 Hibernate: create table t_group (id integer not null auto_increment, name varchar(255), primary key (id))Hibernate: create table t_user (id integer not null auto_increment, name varchar(255), groupId integer, primary key (id))Hibernate: alter table t_user add constraint FK_7ktm6l2qkykpqrf6oq01ys8wy foreign key (groupId) references t_group (id) C、一对多,多对一双向关联 1.Group.java package com.zgy.hibernate.model;import java.util.HashSet;import java.util.Set;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.OneToMany;import javax.persistence.Table;@Entity@Table(name=“t_group”)public class Group {private int id;private String name;private Set 2.User.java package com.zgy.hibernate.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.Table;@Entity@Table(name=“t_user”)public class User {private int id;private String name;private Group group;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@ManyToOnepublic Group getGroup() {return group;}public void setGroup(Group group) {this.group = group;}} 3.查看生成的sql语句 Hibernate: create table t_group (id integer not null auto_increment, name varchar(255), primary key (id))Hibernate: create table t_user (id integer not null auto_increment, name varchar(255), groupId integer, primary key (id))Hibernate: alter table t_user add constraint FK_7ktm6l2qkykpqrf6oq01ys8wy foreign key (groupId) references t_group (id) 1.Group.hbm.xml <?xml version=“1.0”?> 3.查看生成的sql语句 Hibernate: create table t_group (id integer not null auto_increment, name varchar(255), primary key (id))Hibernate: create table t_user (id integer not null auto_increment, name varchar(255), groupId integer, primary key (id))Hibernate: alter table t_user add constraint FK_7ktm6l2qkykpqrf6oq01ys8wy foreign key (groupId) references t_group (id) 六、继承映射 Single_Table 1、当多个类存在继承关系的时候,这时候建表的方案有3种, 2、第一种是父类中包含全部的属性,任何子类的信息都由父类对应的数据表来存储。在该表中,增加一个用于表示不同的子类及父类的字段,这样就可以对父类和子类数据进行区分。这种设计成为Single_Table。如下实验: (1)设计一个父类Person.java。其中定义共有的属性id,name package com.zgy.hibernate.model; import javax.persistence.DiscriminatorColumn; import javax.persistence.DiscriminatorType; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; @Entity @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name=“discriminator”,discriminatorType=DiscriminatorType.STRING) @DiscriminatorValue(“person”) public class Person { private int id; private String name; @Id @GeneratedValue public int getId { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } (2)定义Student.java,定义自己的私有属性score package com.zgy.hibernate.model; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; @Entity @DiscriminatorValue(“student”) public class Student extends Person{ private int score; public int getScore() { return score; } public void setScore(int score) { this.score = score; } } (3)定义Teacher.java,定义自己的私有属性title package com.zgy.hibernate.model; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; @Entity @DiscriminatorValue(“teacher”) public class Teacher extends Person{ private String title; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } } (4)测试save()方法 package com.zgy.hibernate.model; import java.util.Map; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; public class ORMapppingTest { public static SessionFactory sf = null; @BeforeClass public static void beforeClass(){ Configuration configure =new Configuration().configure(); new SchemaExport(configure).create(true, true); sf = configure.buildSessionFactory(); } @Test public void testSave() { Student s = new Student(); s.setName(“s1”); s.setScore(80); Teacher t = new Teacher(); t.setName(“t1”); t.setTitle(“中级”); Session session = sf.openSession(); session.beginTransaction(); session.save(s); session.save(t); session.getTransaction().commit(); session.close(); } @AfterClass public static void afterClass(){ sf.close(); } } (5)查看SQL语句: create table Person ( discriminator varchar(31) not null, id integer not null auto_increment, name varchar(255), score integer, title varchar(255), primary key (id) ) Hibernate: insert into Person (name, score, discriminator) values (?, ?, ‘student‘) Hibernate: insert into Person (name, title, discriminator) values (?, ?, ‘teacher‘) 可以看出,在Person表中,产生了所有子类的字段,并且在保存数据的时候,每条数据都加入了对应的标识。 @Inheritance(strategy=InheritanceType.SINGLE_TABLE)用于定义存储的策略使用的是单表存储 @DiscriminatorColumn(name=“discriminator”,discriminatorType=DiscriminatorType.STRING)定义标识列,该列的类型是String类型 @DiscriminatorValue(“person”)定义Person类的数据在标识列discriminator中的取值是“person” @DiscriminatorValue(“student”)定义Student类的数据对应的表示是“student” @DiscriminatorValue(“teacher”)定义Teacher类的数据对应的表示是“teacher” 测试读取数据: @Test public void testLoad() { testSave(); Session session = sf.openSession(); session.beginTransaction(); Student s = (Student)session.load(Student.class, 1); Person t = (Person)session.load(Person.class, 2); System.out.println(s.getScore()); System.out.println(t.getName()); session.getTransaction().commit(); session.close(); } 查看SQL语句: Hibernate: select student0_.id as id2_0_0_, student0_.name as name3_0_0_, student0_.score as score4_0_0_ from Person student0_ where student0_.id=? and student0_.discriminator=‘student‘ 80 Hibernate: select person0_.id as id2_0_0_, person0_.name as name3_0_0_, person0_.score as score4_0_0_, person0_.title as title5_0_0_, person0_.discriminator as discrimi1_0_0_ from Person person0_ where person0_.id=? t1 Table_Per_Class (1)修改Person.java中的ID生成策略,使用Table生成主键 package com.zgy.hibernate.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.TableGenerator; @Entity @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) @TableGenerator( name=“t_gen”, table=“t_gen_table”, pkColumnName=“t_pk”, valueColumnName=“t_value”, pkColumnValue=“person_pk”, initialValue=1, allocationSize=1 ) public class Person { private int id; private String name; @Id @GeneratedValue(generator=“t_gen”,strategy=GenerationType.TABLE) public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } (2)修改Student.java package com.zgy.hibernate.model; import javax.persistence.Entity; @Entity public class Student extends Person{ private int score; public int getScore() { return score; } public void setScore(int score) { this.score = score; } } (3)修改Teacher.java package com.zgy.hibernate.model; import javax.persistence.Entity; @Entity public class Teacher extends Person{ private String title; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } } (4)测试save()方法 @Test public void testSave() { Student s = new Student(); s.setName(“s1”); s.setScore(80); Teacher t = new Teacher(); t.setName(“t1”); t.setTitle(“中级”); Session session = sf.openSession(); session.beginTransaction(); session.save(s); session.save(t); session.getTransaction().commit(); session.close(); } (5)观察生成的SQL语句 create table Person ( id integer not null, name varchar(255), primary key (id) ) create table Student ( id integer not null, name varchar(255), score integer not null, primary key (id) ) create table Teacher ( id integer not null, name varchar(255), title varchar(255), primary key (id) ) create table t_gen_table ( t_pk varchar(255), t_value integer ) Hibernate: insert into Student (name, score, id) values (?, ?, ?) Hibernate: insert into Teacher (name, title, id) values (?, ?, ?) (6)测试load()方法 @Test public void testLoad() { testSave(); Session session = sf.openSession(); session.beginTransaction(); Student s = (Student)session.load(Student.class, 1); Teacher t = (Teacher)session.load(Teacher.class, 2); System.out.println(s.getScore()); System.out.println(t.getName()); session.getTransaction().commit(); session.close(); } (7)观察SQL语句 Hibernate: select student0_.id as id1_0_0_, student0_.name as name2_0_0_, student0_.score as score1_1_0_ from Student student0_ where student0_.id=? 80 Hibernate: select teacher0_.id as id1_0_0_, teacher0_.name as name2_0_0_, teacher0_.title as title1_2_0_ from Teacher teacher0_ where teacher0_.id=? t1 Joined (1)修改Person.java package com.zgy.hibernate.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; @Entity @Inheritance(strategy=InheritanceType.JOINED) public class Person { private int id; private String name; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } (2)Student.java和Teacher只保留@Entity (3)测试save()方法 @Test public void testSave() { Student s = new Student(); s.setName(“s1”); s.setScore(80); Teacher t = new Teacher(); t.setName(“t1”); t.setTitle(“中级”); Session session = sf.openSession(); session.beginTransaction(); session.save(s); session.save(t); session.getTransaction().commit(); session.close(); } (4)查看SQL语句 create table Person ( id integer not null auto_increment, name varchar(255), primary key (id) ) create table Student ( score integer not null, id integer not null, primary key (id) ) create table Teacher ( title varchar(255), id integer not null, primary key (id) ) alter table Student add constraint FK_ohs43dct8k52ch2exlmf4bs3l foreign key (id) references Person (id) alter table Teacher add constraint FK_g6jmt7fcm6gfd0jvhimb9xy84 foreign key (id) references Person (id) Hibernate: insert into Person (name) values (?) Hibernate: insert into Student (score, id) values (?, ?) Hibernate: insert into Person (name) values (?) Hibernate: insert into Teacher (title, id) values (?, ?) (5)测试load()方法 @Test public void testLoad() { testSave(); Session session = sf.openSession(); session.beginTransaction(); Student s = (Student)session.load(Student.class, 1); Teacher t = (Teacher)session.load(Teacher.class, 2); System.out.println(s.getScore()); System.out.println(t.getName()); session.getTransaction().commit(); session.close(); } (6)观察SQL语句 Hibernate: select student0_.id as id1_0_0_, student0_1_.name as name2_0_0_, student0_.score as score1_1_0_ from Student student0_ inner join Person student0_1_ on student0_.id=student0_1_.id where student0_.id=? 80 Hibernate: select teacher0_.id as id1_0_0_, teacher0_1_.name as name2_0_0_, teacher0_.title as title1_2_0_ from Teacher teacher0_ inner join Person teacher0_1_ on teacher0_.id=teacher0_1_.id where teacher0_.id=? hibernate进行级联处理时,关于一对一的关系应该注意的问题, 1、假如有奖品项item和奖品aword,他们之间的对应关系是 1)item 1:1 aword 奖品项与奖品是一对一的关系,一个奖品项只能包含一个奖品。 2)aword 1:n item 奖品与奖品项是一对多的关系,一个奖品可以出现在多个奖品项中。 2、在进行hibernate注解配置的时候,他们的关系应该如下: 1)entity Item //红包,一对一//将在item表中创建awordId字段。 //级联只选择更新,表示数据更新时,item更新,这里不要级联删除,因为奖品项删除不会影响到奖品@ManyToOne(cascade = {CascadeType.REFRESH}, fetch = FetchType.LAZY,optional = true)@JoinColumn(name = awordId)private Aword aword;2)entity aword //红包与转盘的奖品项是一对多的关系,如果删除红包,那么红包对应的所有大转盘奖项也应该删除。 //mappedBy字段表明关联到item表中的aword,关联关系有aword来维护,如果奖品删除了,那么对应的所有的奖品项也要删除 @OneToMany(mappedBy=aword , cascade = {CascadeType.REMOVE,CascadeType.REFRESH},fetch = FetchType.LAZY) private List 1)在数据库中,需要在奖品项item中添加外键字段awordId,因此可以通过这个奖品id取出对应的奖品。 2)在做奖品aword删除时,切记要使用hibernate的delete删除方法,如果删除多个奖品,就用for循环删除。不能使用hibernate调用query方法,不能去使用sql删除数据,否则会绕过hibernate机制,不会进行级联删除等操作。有些类似于spring的session,如果你自己openSession,那么这个session就需要自己打开关闭,并且还需要放在事务中处理。但是如果使用getCurrentSession,那么spring会帮你管理这个session,前提你需要在spring配置文件中配置事务。 4、hibernate如果使用延迟加载机制,如果使用调试,那么调试的数据是看不到的,需要打印,如奖品项item,如果使用延迟加载,调试是看不到item的数据的,如果想看item的某一个数据,可以打印这个数据。 hibernate延迟加载只会将数据保存在session中(未确认),那么如果你在dao层去数据,那么在service层使用数据时,数据可能报错,原因时数据取出来后session就会关闭,那么其他层,或者web就不能得到数据。解决这个问题的方法是,让延迟加载的范围扩大到一次请求,可以在web.xml中配置 进行处理。 Hibernate中get和load有什么不同之处? 把get和load放到一起进行对比是Hibernate面试时最常问到的问题,这是因为只有正确理解get()和load()这二者后才有可能高效地使用Hibernate。get和load的最大区别是,如果在缓存中没有找到相应的对象,get将会直接访问数据库并返回一个完全初始化好的对象,而这个过程有可能会涉及到多个数据库调用;而load方法在缓存中没有发现对象的情况下,只会返回一个代理对象,只有在对象getId()之外的其它方法被调用时才会真正去访问数据库,这样就能在某些情况下大幅度提高性能。你也可以参考 Hibernate中get和load的不同之处, 此链接给出了更多的不同之处并对该问题进行了更细致的讨论。 Hibernate中save、persist和saveOrUpdate这三个方法的不同之处? 除了get和load,这又是另外一个经常出现的Hibernate面试问题。 所有这三个方法,也就是save()、saveOrUpdate()和persist()都是用于将对象保存到数据库中的方法,但其中有些细微的差别。例如,save()只能INSERT记录,但是saveOrUpdate()可以进行 记录的INSERT和UPDATE。还有,save()的返回值是一个Serializable对象,而persist()方法返回值为void。你还可以访问 save、persist以及saveOrUpdate,找到它们所有的不同之处。 Hibernate中的命名SQL查询指的是什么? Hibernate的这个面试问题同Hibernate提供的查询功能相关。命名查询指的是用标签在影射文档中定义的SQL查询,可以通过使用Session.getNamedQuery()方法对它进行调用。命名查询使你可以使用你所指定的一个名字拿到某个特定的查询。 Hibernate中的命名查询可以使用注解来定义,也可以使用我前面提到的xml影射问句来定义。在Hibernate中,@NameQuery用来定义单个的命名查询,@NameQueries用来定义多个命名查询。 Hibernate中的SessionFactory有什么作用? SessionFactory是线程安全的吗? 这也是Hibernate框架的常见面试问题。顾名思义,SessionFactory就是一个用于创建Hibernate的Session对象的工厂。SessionFactory通常是在应用启动时创建好的,应用程序中的代码用它来获得Session对象。作为一个单个的数据存储,它也是 线程安全的,所以多个线程可同时使用同一个SessionFactory。Java JEE应用一般只有一个SessionFactory,服务于客户请求的各线程都通过这个工厂来获得Hibernate的Session实例,这也是为什么SessionFactory接口的实现必须是线程安全的原因。还有,SessionFactory的内部状态包含着同对象关系影射有关的所有元数据,它是 不可变的,一旦创建好后就不能对其进行修改了。 Hibernate中的Session指的是什么? 可否将单个的Session在多个线程间进行共享? 前面的问题问完之后,通常就会接着再问这两个问题。问完SessionFactory的问题后就该轮到Session了。Session代表着Hibernate所做的一小部分工作,它负责维护者同数据库的链接而且 不是线程安全的,也就是说,Hibernage中的Session不能在多个线程间进行共享。虽然Session会以主动滞后的方式获得数据库连接,但是Session最好还是在用完之后立即将其关闭。 hibernate中sorted collection和ordered collection有什么不同? T这个是你会碰到的所有Hibernate面试问题中比较容易的问题。sorted collection是通过使用 Java的Comparator在内存中进行排序的,ordered collection中的排序用的是数据库的order by子句。对于比较大的数据集,为了避免在内存中对它们进行排序而出现 Java中的OutOfMemoryError,最好使用ordered collection。 ★ 数据库面试题 ★ 学生会面试题 ★ php 面试题 ★ 医师面试题 ★ 谷歌面试题 ★ 腾讯面试题 ★ 会计面试题 ★ 卫生系统面试题 ★ 华为面试题篇4:Hibernate――ORMapping
篇5:Hibernate――ORMapping
篇6:Hibernate――ORMapping
篇7:Hibernate――ORMapping
篇8:Hibernate――ORMapping
一、Annotation配置
二、xml配置
一、Annotation配置
二、Xml配置
一、Annotation配置
二、Xml配置
篇9:Hibernate关系映射
篇10:hibernate级联处理问题
篇11:Hibernate常见面试问题