您的位置:首页 > 其它

Hibernate 学习笔记(对关键知识点的系统化总结,亲,百分百对你有帮助哦!)

2013-07-21 19:58 627 查看

Q1:Hibernate 是什么?优势在哪里?相关概念:持久化、ORM?

 A1:Hibernate 是一个优秀的Java 持久化层解决方案,是当今主流的对象—关系映射(ORM)工具

优势:a、一个开发源代码的对象关系映射框架;
         b、对JDBC进行了非常轻量级的对象封装, 简化了JDBC 繁琐的编码;

Session session = HiberanteUtil.getSession();
             Query query = session.createQuery("from User");
             List<User> users =(List<User>)query.list();

c、将JavaBean对象和数据库的表建立对应关系。

体对象的三种状态:

瞬时态(Transient):不曾进行持久化,未与任何Session相关联,保存在内存的程序数据,程序退出后,数据就消失了,称为瞬时状态;

持久态(Persistent):已被持久化,且加入到Session缓存中,保存在磁盘上的程序数据,程序退出后依然存在,称为程序数据的持久状态;

游离态(也称脱管态,Detached):已经被持久化,但不再处于Session的缓存中,既没有与任何Session相关联。

注:三种状态之间的转换:

持久化:将程序数据在瞬时状态和持久状态之间转换的机制。

ORM(对象-关系映射):是持久化的一种解决方案,主要是把对象模型和关系型数据库关系模型映射起来,并且使用元数据对这些映射进行描述。

Q2:如何为系统同配置Hibernate支持?
A2:第一步:创建项目并导入jar包



第二步:创建Hibernate主配置文件:用于配置数据库连接、运行时所需的各种属性、默认文件名为“hibernate.cfg.xml”
<?xml version='1.0' encoding='utf-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<!-- 数据库连接URL -->

<property name="connection.url">jdbc:oracle:thin:@localhost:1521:XE</property>

<!-- 数据库用户名 -->

<property name="connection.username">oa</property>

<!-- 数据库密码 -->

<property name="connection.password">oa123</property>

<!-- 数据库JDBC驱动类名 -->

<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>

<!-- 数据库方言 -->

<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>

<!-- ddl语句自动建表 -->

<property name="hbm2ddl.auto">none</property>

<!-- 是否输出Hibernate生成的SQL语句,开发阶段一般需要开启 -->

<property name="show_sql">true</property>

<!-- 是否对输出SQL进行格式化 -->

<property name="format_sql">true</property>

<!-- 连接池配置 -->

<property name="hibernate.connection.provider_class">

org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider

</property>

<!-- 这是C3P0随时准备好的最少的JDBC连接数量 -->

<property name="hibernate.c3p0.min_size">5</property>

<!-- 连接池中JDBC连接的最大数量 -->

<property name="hibernate.c3p0.max_size">20</property>

<!-- 超时周期,在它之后,闲置连接将从池中移除 -->

<property name="hibernate.c3p0.timeout">300</property>

<!-- 最多高速缓存100个预编译语句,该属性是使Hibernate获得较好性能的要素。 -->

<property name="hibernate.c3p0.max_statements">100</property>

<!-- 连接被自动验证前,以秒为单位的闲置时间 -->

<property name="hibernate.c3p0.idle_test_period">3000</property>

<!-- 注册ORM实体类映射文件-->

<mapping resource="实体类映射文件路径" />

</session-factory>

</hibernate-configuration>
注:1、数据库连接信息:驱动程序类名、URL、用户名、密码。

2、 Hibernate相关特性:dialect(方言)、show_SQL(输出SQL语句到控制台)、format_SQL(格式化SQL语句)。

3、 连接池相关信息。

4、 实体类映射文件:实体类与数据库表之间的逻辑映射。
第三步:测试连接

[html]view plaincopyprint?

<SPAN style="FONT-SIZE: 18px">public class HibernateTest {
public static void main(String[] args) {
//获取配置,默认读取classpath根目录下名为hibernate.cfg.xml的文件
Configuration cfg = new Configuration().configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();
//创建SessionFactory
SessionFactory factory = cfg.buildSessionFactory(serviceRegistry);
//获取session
System.out.println(factory.openSession());
}
}</SPAN>

public class HibernateTest {
	public static void main(String[] args) {
		//获取配置,默认读取classpath根目录下名为hibernate.cfg.xml的文件
		Configuration cfg = new Configuration().configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();
		//创建SessionFactory
		SessionFactory factory = cfg.buildSessionFactory(serviceRegistry); 
		//获取session
		System.out.println(factory.openSession());
	}
}
Q3:如何使用Hibernate完成数据增删改操作?

A3: 第一步:创建实体类。实体类(也称持久化类)是一个带有一些属性的JavaBean类,实体类对属性的存取方法(getter and setter method)使用了标准JavaBean命名约定,同时把类属性的访问级别设成私有的。为了通过反射机制来实例化类的对象,我们需要提供一个无参的构造器,所有的实体类都要求有无参的构造器,因为Hibernate需要使用Java反射机制来为你创建对象。最后要为实体类实现Java.io.Serializable
接口,以便Hibernate能更好的缓存实体对象。
第二步:创建和配置映射文件。通过实体映射文件,Hibernate知道怎样去加载和存储实体类的对象,知道应该访问数据库里面的哪个表及应该使用表里面的哪些字段。

[html]view plaincopyprint?

<SPAN style="FONT-SIZE: 18px"> "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="org.ijob.bean.Seeker" table="ijob_seeker"></SPAN>

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="org.ijob.bean.Seeker" table="ijob_seeker">


[html]view plaincopyprint?

<SPAN style="FONT-SIZE: 18px"> <!-- 主键映射 -->
<id name="id" type="string">
<column name="id" length="32"></column>
<generator class="uuid" />
</id>
<!—属性映射 -->
<property name="email" type="string">
<column name="email" length="100"></column>
</property>
<property name="password" type="string">
<column name="password" length="20"></column>
</property>

<property name="name" type="string">
<column name="name" length="10"></column>
</property></SPAN>

<!-- 主键映射 -->
		<id name="id" type="string">
			<column name="id" length="32"></column>
			<generator class="uuid" />
		</id>
      <!—属性映射 -->
		<property name="email" type="string">
			<column name="email" length="100"></column>
		</property>
		<property name="password" type="string">
			<column name="password" length="20"></column>
		</property>
		
		<property name="name" type="string">
			<column name="name" length="10"></column>
		</property>


[html]view plaincopyprint?

<SPAN style="FONT-SIZE: 18px"> <!—此处省略系列属性映射 -->
</class>
</hibernate-mapping></SPAN>

<!—此处省略系列属性映射 -->
	</class>
</hibernate-mapping>
第三步:在主配置文件中添加实体映射文件路径。将映射文件的路径信息添加到hibernate.cfg.xml中。<mapping resource=“***/***/***.hbm.xml" />

第四步:测试
第五步:数据库操作(1、获取配置;2、创建SessionFactory;3、打开Session;4、开始一个事务;5、持久化操作(save()、update()、delete()、find())6、提交事务;7、关闭Session)

[html]view plaincopyprint?

<SPAN style="FONT-SIZE: 18px"> // 1、获取配置
Configuration cfg = new Configuration().configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(cfg.getProperties()).buildServiceRegistry();
// 2、创建SessionFactory
SessionFactory factory = cfg.buildSessionFactory(serviceRegistry);
// 3、获取session
Session session = factory.openSession();
Transaction tx = session.getTransaction();
try {
// 4、开启事务
tx.begin();
Seeker seeker = new Seeker();
seeker.setEmail("abc@163.com");
seeker.setPassword("abc");
// 5、保存seeker对象
session.save(seeker);
// 6、提交事务
session.getTransaction().commit();
} catch (Exception e) {
tx.rollback();
e.printStackTrace();
} finally {
// 7、关闭session
session.close();
}
}</SPAN>

// 1、获取配置
	Configuration cfg = new Configuration().configure();
	ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
			.applySettings(cfg.getProperties()).buildServiceRegistry();
	// 2、创建SessionFactory
	SessionFactory factory = cfg.buildSessionFactory(serviceRegistry);
	// 3、获取session
	Session session = factory.openSession();
	Transaction tx = session.getTransaction();
	try {
		// 4、开启事务
		tx.begin();
		Seeker seeker = new Seeker();
		seeker.setEmail("abc@163.com");
		seeker.setPassword("abc");
		// 5、保存seeker对象
		session.save(seeker);
		// 6、提交事务
		session.getTransaction().commit();
	} catch (Exception e) {
		tx.rollback();
		e.printStackTrace();
	} finally {
		// 7、关闭session
		session.close();
	}
}
Q4:Hibernate中包括哪些关联关系?关联关系在映射文件(hbm.xml)中如何体现?

A4:(1)单项多对一(many-to-one)。即:many的一端应持有one的一端的对象(引用)。

[html]view plaincopyprint?

<SPAN style="FONT-SIZE: 18px">映射文件例:
<hibernate-mapping>
<class name="org.ijob.bean.Resume" table="ijob_resume">
<!—省略主键映射及属性映射 -->
<!-- 多对一关联 -->
<many-to-one name="seeker" class="org.ijob.bean.Seeker"> 1
<column name="seeker_id"></column> 2
</many-to-one>
</class>
</hibernate-mapping>
1、name为属性名,class为“one”端类名
2、外键列列名</SPAN>

映射文件例:
<hibernate-mapping>
	<class name="org.ijob.bean.Resume" table="ijob_resume">
		<!—省略主键映射及属性映射 -->
		<!-- 多对一关联 -->
		<many-to-one name="seeker" class="org.ijob.bean.Seeker">       1
			<column name="seeker_id"></column>                 2
		</many-to-one>
	</class>
</hibernate-mapping>
1、name为属性名,class为“one”端类名
2、外键列列名
(2)单向一对多关联(one-to-many)。one的一端应持有many端的对象集合。

[html]view plaincopyprint?

<SPAN style="FONT-SIZE: 18px">映射文件例:
<hibernate-mapping>
<class name="org.ijob.bean.Seeker" table="ijob_seeker">
<!—省略主键映射及属性映射 -->
<set name="resumes" > 1
<key column="seeker_id"></key> 2
<one-to-many class="org.ijob.bean.Resume"/> 3
</set>
</class>
</hibernate-mapping>
代码解析:
1、set集合节点适用于配置一对多关联关系, name属性指定one的一端对应属性名。
2、外键列列名。
3、class属性指定many端的全限定类名。
</SPAN>

映射文件例:
<hibernate-mapping>
	<class name="org.ijob.bean.Seeker" table="ijob_seeker">
		<!—省略主键映射及属性映射 -->
		<set name="resumes" >                                                1
			<key column="seeker_id"></key>                           2
			<one-to-many class="org.ijob.bean.Resume"/>              3
		</set>
</class>
</hibernate-mapping>
代码解析:
1、set集合节点适用于配置一对多关联关系, name属性指定one的一端对应属性名。
2、外键列列名。
3、class属性指定many端的全限定类名。
(3)双向一对多/一对一关联。双向一对多特别简单,就是同时配置了单向的一对多和单向的多对一。

(4)一对一关联
(5)多对多关联。将其转换成两个一对多。

[html]view plaincopyprint?

<SPAN style="FONT-SIZE: 18px">如果中间表是联合主键:
<!-- 联合主键 -->
<composite-id>
<!--同时表达这是外键-->
<key-many-to-one name=“book” column=“book_id" class=“entity.Book" ></key-many-to-one>
<key-many-to-one name=“student” column=“stu_id" class=“entity.Book" ></key-many-to-one>
</composite-id></SPAN>

如果中间表是联合主键:
<!-- 联合主键 -->
<composite-id>
	<!--同时表达这是外键-->
	<key-many-to-one name=“book” column=“book_id" class=“entity.Book" ></key-many-to-one>
	<key-many-to-one name=“student” column=“stu_id" class=“entity.Book" ></key-many-to-one>
</composite-id>
Q5:Hibernate的主要查询方式有哪些?

A5:主要支持两种查询方式:(1)HQL查询(Hibernate Query Languge,Hibernate 查询语言):是一种面向对象的查询语言,其中没有表和字段的概念,只有类、对象和属性的概念,应用较为广泛;注意:HQL中没有表和字段的概念,只有类、对象和属性的概念,这点需要大家好好体会。(2)Criteria查询:又称为“对象查询”,它用面向对象的方式将构造查询的过程做了封装(了解)。
附:HQL查询使用方法:a、得到Session;b、编写HQL语句;c、创建Query对象,Query接口是HQL 查询接口。它提供了各种的查询功能;d、执行查询,得到结果
Q6:关于Hibernate加载计划和策略。
A6:Hibernate提供了下列方法从数据库中获取对象:1、通过get()或load()方法按照id获取对象; 2、从一个已经加载的对象开始,通过系列的get方法访问被关联的对; 3、HQL查询获取单个或系列对象; 4、Criteria查询获取单个或系列对象; 5、原生SQL查询获取单个或系列对象。
关于加载计划:为了加以区别,我们称第一层次的查询目标为“主对象”。现在我们要关注的是主对象及其关联对象的加载计划和加载策略,即数据何时被加载以及数据被怎样加载的问题。

涉及到加载计划(何时加载)的关注点有以下几个:1、主对象的关联对象何时被加载;2、主对象的关联集合何时被加载;3、主对象本身何时被加载;4、主对象的属性何时被加载。
对于上面提到的关注点,Hibernate都有默认的加载计划。具体来说,是这样的:1、关联对象和关联集合的默认加载计划是:延迟加载,即加载主对象时它们不会被立即加载,而是直到使用这些对象和集合时才发送SQL语句、获取数据、初始化对象和集合;2、主对象本身是否延迟加载取决于使用的是load()方法还是其它方法,load()方法是延迟的,而get()方法或其它方法是立即的;3、主对象的属性默认是被立即加载的。

Q7:重点:Hibernate中的Session操作解释。
A7:public interface Session extendsSerializable
Java应用程序与Hibernate之间的主要运行时接口。它是抽象了持久化服务概念的核心抽象API类。

Session的生命周期绑定在一个物理的事务(tansaction)上面。(长的事务可能跨越多个数据库事物。)

Session的主要功能是提供对映射的实体类实例的创建,读取和删除操作。实例可能以下面三种状态存在:

自由状态(transient): 不曾进行持久化,未与任何Session相关联

持久化状态(persistent): 仅与一个Session相关联

游离状态(detached): 已经进行过持久化,但当前未与任何Session相关联

游离状态的实例可以通过调用save()、persist()或者saveOrUpdate()方法进行持久化。持久化实例可以通过调用
delete()变成游离状态。通过get()或load()方法得到的实例都是持久化状态的。游离状态的实例可以通过调用update()、0saveOrUpdate()、lock()或者replicate()进行持久化。游离或者自由状态下的实例可以通过调用merge()方法成为一个新的持久化实例。

save()和persist()将会引发SQL的INSERT,delete()会引发SQLDELETE,而update()或merge()会引发SQLUPDATE。对持久化(persistent)实例的修改在刷新提交的时候会被检测到,它也会引起SQLUPDATE。saveOrUpdate()或者replicate()会引发SQLINSERT或者UPDATE。

其具体实现并不一定是线程安全的。每个线程/事务应该从一个SessionFactory获取自己的session实例。

如果其持久化对象类是可序列化的,则Session实例也是可序列化的。



See Also:
SessionFactory








Session管理:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: