⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hibernate2 参考文档之一.txt

📁 Hibernate使用说明书
💻 TXT
📖 第 1 页 / 共 3 页
字号:
    PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">

<hibernate-configuration>

    <session-factory>

        <property name="connection.datasource">java:comp/env/jdbc/quickstart</property>
        <property name="show_sql">false</property>
        <property name="dialect">net.sf.hibernate.dialect.PostgreSQLDialect</property>

        <!-- Mapping files -->
        <mapping resource="Cat.hbm.xml"/>

    </session-factory>

</hibernate-configuration>
我们关闭了SQL命令的log,告诉Hibernate使用哪种SQL数据库方言(dialet),还有如何得到JDBC连接(通过声明数据源池绑定的JNDI地址)。方言是必需的,因为不同的数据库都和SQL "标准"有一些出入。Hibernate会替你照管这些差异之处,发行包包含了所有主流的商业和开放源代码数据库的方言。 

SessionFactory是Hibernate的概念,对应一个数据存储源,如果有多个数据库,可以创建多个XML配置文件,也在你的程序中创建多个Configuration和SessionFactory对象。 

在hibernate.cfg.xml中的最后一个元素声明了Cat.hbm.xml是一个Hibernate XML映射文件,对应持久化类Cat。这个文件包含了把POJO类映射到数据库表(或多个数据库表)的元数据。我们稍后就回来看这个文件。让我们先编写这个POJO类,再在声明它的映射元数据。 

1.2. 第一个可持久化类
s Hibernate让普通的Java对象(Plain Old Java Objects ,就是POJOs,有时候也称作Plain Ordinary Java Objects)变成持久化类。一个POJO很像JavaBean,属性通过getter和setter方法访问,对外隐藏了内部实现的细节。 

package net.sf.hibernate.examples.quickstart;

public class Cat {

    private String id;
    private String name;
    private char sex;
    private float weight;

    public Cat() {
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public float getWeight() {
        return weight;
    }

    public void setWeight(float weight) {
        this.weight = weight;
    }

}
Hibernate对属性使用的类型不加限制。所有的Java JDK类型和原始类型(比如String,char和float)都可以被映射,也包括Java 集合框架(Java collections framework)中的类。你可以把它们映射成为值,值集合,或者与其他实体相关联。id是一个特殊的属性,代表了这个类的数据库标识符(主键),它对于类似于Cat这样的实体是必需的。 

持久化类不需要实现什么特别的接口,也不需要从一个特别的持久化根类继承下来。Hibernate也不需要使用任何编译期处理,比如字节码增强操作,它独立的使用Java反射机制和运行时类增强(通过CGLIB)。所以,在Hibernate中,POJO的类不需要任何前提条件,我们就可以把它映射成为数据库表。 

1.3. 映射cat
Cat.hbm.xml映射文件包含了对象/关系映射所需的元数据。 

元数据包含了持久化类的声明和把它与其属性映射到数据库表的信息(属性作为值或者是指向其他实体的关联)。 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
    PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>

    <class name="net.sf.hibernate.examples.quickstart.Cat" table="CAT">

        <!-- A 32 hex character is our surrogate key. It's automatically
            generated by Hibernate with the UUID pattern. -->
        <id name="id" type="string" unsaved-value="null" >
            <column name="CAT_ID" sql-type="char(32)" not-null="true"/>
            <generator class="uuid.hex"/>
        </id>

        <!-- A cat has to have a name, but it shouldn' be too long. -->
        <property name="name">
            <column name="NAME" sql-type="varchar(16)" not-null="true"/>
        </property>

        <property name="sex"/>

        <property name="weight"/>

    </class>

</hibernate-mapping>
每个持久化类都需要一个标识属性(实际上,只是哪些代表一手对象的类,而不是代表值对象的类,后者会被映射称为一手对象中的一个组件)。这个属性用来区分持久化对象:如果catA.getId().equals(catB.getId())结果是true的话,两只猫就是相同的。这个概念称为数据库标识。Hiernate附带了几种不同的标识符生成器,用于不同的场合(包括数据库本地的顺序(sequence)生成器和hi/lo高低位标识模式)。我们在这里使用UUID生成器,并指定CAT表的CAT_ID字段(作为表的主键)存放生成的标识值。 

Cat的其他属性都映射到同一个表。对name属性来说,我们把它显式地声明映射到一个数据库字段。如果数据库schema是由映射声明使用Hibernate的SchemaExport工具自动生成的(作为SQL DDL指令),这特别有用。所有其它的属性都用Hibernate的默认值映射,大多数情况你都会这样做。数据库中的CAT表看起来是这样的: 

 Column |         Type          | Modifiers
--------+-----------------------+-----------
 cat_id | character(32)         | not null
 name   | character varying(16) | not null
 sex    | character(1)          |
 weight | real                  |
Indexes: cat_pkey primary key btree (cat_id)
你现在可以在你的数据库中首先创建这个表了,如果你需要使用SchemaExport工具把这个步骤自动化,请参阅Chapter 19, 工具箱指南。这个工具能够创建完整的SQL DDL,包括表定义,自定义的字段类型约束,惟一约束和索引。 

1.4. 与猫同乐
我们现在可以开始Hibernate的Session了。我们用它来从数据库中存取Cat。首先,我们要从SessionFactory中获取一个Session(Hibernate的工作单元)。 

SessionFactory sessionFactory =
            new Configuration().configure().buildSessionFactory();
SessionFactory负责一个数据库,也只对应一个XML配置文件(hibernate.cfg.xml)。 

这篇教程的关注点在于配置Tomcat的JDBC连接,绑定到JNDI上,以及Hibernate的基础配置。你可以用喜欢的任何方式编写一个Servlet,包含下面的代码,只要确保SessionFactory只创建一次。也就是说你不能把它作为你的Serlvet 的实例变量。一个好办法是用在辅助类中用一个静态的SessionFactory,例如这样: 

import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;

public class HibernateUtil {

    private static final SessionFactory sessionFactory;

    static {
        try {
            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (HibernateException ex) {
            throw new RuntimeException("Exception building SessionFactory: " + ex.getMessage(), ex);
        }
    }

    public static final ThreadLocal session = new ThreadLocal();

    public static Session currentSession() throws HibernateException {
        Session s = (Session) session.get();
        // Open a new Session, if this Thread has none yet
        if (s == null) {
            s = sessionFactory.openSession();
            session.set(s);
        }
        return s;
    }

    public static void closeSession() throws HibernateException {
        Session s = (Session) session.get();
        session.set(null);
        if (s != null)
            s.close();
    }
}
这个类不但在它的静态属性中使用了SessionFactory,还使用了ThreadLocal来为当前工作线程保存Session。 

Session不是线程安全的,代表与数据库之间的一次操作。Session通过SessionFactory打开,在所有的工作完成后,需要关闭: 

Session session = HibernateUtil.currentSession();

Transaction tx= session.beginTransaction();

Cat princess = new Cat();
princess.setName("Princess");
princess.setSex('F');
princess.setWeight(7.4f);

session.save(princess);
tx.commit();

HibernateUtil.closeSession();
在Session中,每个数据库操作都是在一个事务(transaction)中进行的,这样就可以隔离开不同的操作(甚至包括只读操作)。我们使用Hibernate的Transaction API来从底层的事务策略中(本例中是JDBC事务)脱身。这样,如果需要把我们的程序部署到一个由容器管理事务的环境中去(使用JTA),我们就不需要更改源代码。请注意,我们上面的例子没有处理任何异常。 

也请注意,你可以随心所欲的多次调用HibernateUtil.currentSession();,你每次都会得到同一个当前线程的Session。你必须确保Session在你的数据库事务完成后关闭,不管是在你的Servlet代码中,或者在ServletFilter中,HTTP结果返回之前。 

Hibernate有不同的方法来从数据库中取回对象。最灵活的方式是使用Hibernate查询语言(HQL),这是一种容易学习的语言,是对SQL的面向对象的强大扩展。 

Transaction tx= session.beginTransaction();

Query query = session.createQuery("select cat from Cat as cat where cat.sex = :sex");
query.setCharacter("sex", 'F');
for (Iterator it = query.iterate(); it.hasNext();) {
    Cat cat = (Cat) it.next();
    out.println("Female Cat: " + cat.getName() );
}

tx.commit();
Hibernate也提供一种面向对象的按条件查询API,可以执行公式化的类型安全的查询。当然,Hibernate在所有与数据库的交互中都使用PrepatedStatement和参数绑定。 

1.5. 结语
在这个短小的教程中,我们只描绘了Hibernate的基本面目。请注意我们没有在例子中包含Servlet相关代码。你必须自行编写Servlet,然后把你认为合适的Hibernate代码插入。 

请记住Hibernate作为数据库访问层,是与你的程序紧密相关的。一般,所有其他层次都依赖持久机制。请确信你理解了这种设计的含义。 


--------------------------------------------------------------------------------
Prev  Up  Next 
前言  Home  Chapter 2. 体系结构 


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -