Session interface
The
Session
interface is the primary interface used by Hibernate applications. An
instance of
Session
is lightweight and is inexpensive to create and destroy. This is
important because your application will need to create and destroy sessions all the
time, perhaps on every request. Hibernate sessions are not threadsafe and should
by design be used by only one thread at a time.
The Hibernate notion of a session is something between connection and transaction.
It may be easier to think of a session as a cache or collection of loaded objects
relating to a single unit of work. Hibernate can detect changes to the objects in this
unit of work. We sometimes call the
Session
a persistence manager because it’s also
the interface for persistence-related operations such as storing and retrieving
objects. Note that a Hibernate session has nothing to do with the web-tier
HttpSession
.
When we use the word session in this book, we mean the Hibernate session.
We sometimes use user session to refer to the
HttpSession
object.
We describe the
Session
interface in detail in chapter 4, section 4.2, “The persistence
manager.”
Session
是
Hibernate
中最主要的接口。
Session
实例是轻量级的,便于创建和销毁(
inexpensive to create and destroy
)。这很重要,因为你的应用程序会需要一直不断的创建和销毁
Session
,可能每个
request
都要这样做。
Hibernate Session
不是线程安全的,应当设计成一次只有一个线程在使用。
Hibernate
的
session
概念是介于
connection
和
transaction
之间的东西。更容易理解的方式是把
Session
看作是和一个工作单元相关的
cache
或者
collection of loaded objects
。
Hibernate
能够探测到这个单元中的对象的更改。我们有时把
session
成为
persistence manager
,应为它也是进行诸如存取对象这样的持久化操作的接口。注意:
hibernate
的
session
和
web-tier
中的
HttpSession
没有任何关系。
SessionFactory interface
The application obtains
Session
instances from a
SessionFactory
. Compared to
the
Session
interface, this object is much less exciting.
The
SessionFactory
is certainly not lightweight! It’s intended to be shared
among many application threads. There is typically a single
SessionFactory
for the
whole application—created during application initialization, for example. However,
if your application accesses multiple databases using Hibernate, you’ll need
a
SessionFactory
for each database
SessionFactory
不是轻量级的。应当别多个线程共享。典型方法是整个应用程序都使用一个
SessionFactory
——在应用程序初始化的时候创建。不过,在应用程序访问多个数据库的时候,需要每个数据库有一个
SessionFactory
。
Query and Criteria interfaces
The
Query
interface allows you to perform queries against the database and control
how the query is executed. Queries are written in
HQL
or in the native
SQL
dialect of your database. A
Query
instance is used to bind query parameters, limit
the number of results returned by the query, and finally to execute the query.
The
Criteria
interface is very similar; it allows you to create and execute objectoriented
criteria queries.
使用
Query
接口对数据库进行查询操作,并且控制查询的执行。
Queries
使用
HQL
或者本地
SQL
进行编写。
Query
实例用来绑定查询参数,限制返回结果集的数目,以及最后执行查询。
Criteria
接口和
Query
类似,使用它可以创建面向对象的查询条件。
Retrieving objects
Retrieving persistent objects from the database is one of the most interesting (and
complex) parts of working with Hibernate. Hibernate provides the following ways
to get objects out of the database:
■
Navigating the object graph, starting from an already loaded object, by
accessing the associated objects through property accessor methods such as
aUser.getAddress().getCity()
. Hibernate will automatically load (or preload)
nodes of the graph while you navigate the graph if the
Session
is open.
■
Retrieving by identifier, which is the most convenient and performant
method when the unique identifier value of an object is known.
■
Using the Hibernate Query Language (
HQL
), which is a full object-oriented
query language.
■
Using the, Hibernate
Criteria
API
, which provides a type-safe and objectoriented
way to perform queries without the need for string manipulation.
This facility includes queries based on an example object.
■
Using native
SQL
queries, where Hibernate takes care of mapping the
JDBC
result sets to graphs of persistent objects.
Hibernate
提供了下述方式从数据库中取得持久化对象:
Ø
通过对象图表(
graph
),从一个已经载入的对象开始,通过使用
setter/getter
方法访问关联的对象。如果
session
是打开的话,
hibernate
会在你访问图表的时候自动载入
(
或者提前载入
)
图表中的节点;
Ø
通过标识符,当已知对象的唯一标识符的值时,这是最简便的方法;
Ø
使用
HQL
,完全面向对象的查询语言;
Ø
使用
Criteria API
,它提供了一种不需字符串操作的,类型安全和面向对象的方式进行查询。
Ø
使用本地
SQL
查询。
4.4.3 Query by criteria
The Hibernate query by criteria (
QBC
)
API
lets you build a query by manipulating criteria
objects at runtime. This approach lets you specify constraints dynamically
without direct string manipulations, but it doesn’t lose much of the flexibility or
power of
HQL
. On the other hand, queries expressed as criteria are often less readable
than queries expressed in
HQL
.
Retrieving a user by first name is easy using a
Criteria
object:
Criteria criteria = session.createCriteria(User.class);
criteria.add( Expression.like("firstname", "Max") );
List result = criteria.list();
A
Criteria
is a tree of
Criterion
instances. The
Expression
class provides static factory
methods that return
Criterion
instances. Once the desired criteria tree is
built, it’s executed against the database.
Many developers prefer
QBC
, considering it a more object-oriented approach.
They also like the fact that the query syntax may be parsed and validated at compile
time, whereas
HQL
expressions aren’t parsed until runtime.
The nice thing about the Hibernate
Criteria
API is the
Criterion
framework.
This framework allows extension by the user, which is difficult in the case of a query
language like
HQL
.
QBC
使你可以在运行时通过操作
criteria
对象构造一个查询。这个方法使你可以动态指定约束条件而不必直接进行字符串操作,同时又不失去机动性
(flexibility)
或者
HQL
的优势。不过,使用
criteria
构造的查询条件没有直接的
HQL
易读。
使用
criteria
对象根据姓名取得一个
user
对象很简单:
Criteria criteria = session.createCriteria(User.class);
criteria.add( Expression.like("firstname", "Max") );
List result = criteria.list();
许多程序员更喜欢
QBC
,认为它是一种面向对象的解决方式。
他们也喜欢在编译时对查询语法进行解析和验证,相对地,
HQL
表达式直到运行时才进行解析。
另外,
Criterion
framework
允许用户扩展,而像
HQL
这样的查询语言很难做到这点。
10.1. Hibernate object states
Hibernate defines and supports the following object states:
•
Transient - an object is transient if it has just been instantiated using the new operator, and it is not associated with a Hibernate Session. It has no persistent representation in the database and no identifier value has been assigned. Transient instances will be destroyed by the garbage collector if the application doesn't hold
a reference anymore. Use the Hibernate
Session
to make an object persistent (and let Hibernate take care of
the SQL statements that need to be executed for this transition).
• Persistent - a persistent instance has a representation in the database and an identifier value. It might just
have been saved or loaded, however, it is by definition in the scope of a
Session
. Hibernate will detect any
changes made to an object in persistent state and synchronize the state with the database when the unit of
work completes. Developers don't execute manual
UPDATE
statements, or
DELETE
statements when an object
should be made transient.
• Detached - a detached instance is an object that has been persistent, but its
Session
has been closed. The
reference to the object is still valid, of course, and the detached instance might even be modified in this
state. A detached instance can be reattached to a new
Session
at a later point in time, making it (and all the
modifications) persistent again. This feature enables a programming model for long running units of work
that require user think-time. We call them application transactions, i.e. a unit of work from the point of
view of the user.
Hibernate
定义和支持下列对象状态
(object state)
:
Ø
Transient– 刚刚使用new操作符初始化,还没有和一个Hibernate Session关联的对象处于Transient状态中。这个对象在数据库中没有对应的数据,也没有被分配任何标识值。如果应用程序不再保存任何对Transient instances的引用,Transient instances将被垃圾回收。使用Hibernate Session持久化一个对象(让Hibernate处理需要执行的SQL语句)
Ø
Persistent
–
一个持久化对象在数据库中有相应的数据,还有一个标识值。它有可能是刚刚保存或者载入的,但是,根据定义它存在于一个
Session
的作用范围内。
Hibernate
会检测到任何对于持久化对象的更改,并且在工作单元结束后把更改同步到数据库中。当一个对象应当被置为
transient
状态时,开发者不执行任何手动
UPDATE
或者
DELETE
语句。
Ø
Detached
- detached instance
是一个已经被持久化的对象,但是它的
Session
已经关闭了。当然,这个对象的引用仍然有效,而且,
detached instance
甚至可以被更改。晚些时候,
detached instance
可以重新绑定到一个新的
Session
,使它
(
和所有的修改
)
持久化。这个特征使一种变成模型成为可能,即允许需要用户思考时间的运行时间较长的用户工作单元。我们把这种模型称作
application transaction
,用户角度的工作单元。