Hibernate使用简介

Hibernate的优点是:符合Java习惯的关系数据库持久化;直接、方便;基于JDBC抽象,适合大多数系统,无需关心具体实现。缺点:项目复杂时,需要可视化工具支持,否则效率降低。

 

持久化

  • 持久化:持久保存,掉电等情况下可重新获得数据。
  • 持久化实现:
  • 硬盘文件、数据库。
  • 关系数据库与对象数据库区别,关系数据库定义。
  • 持久化是状态保存的一种形式。

 

持久化和对象

  • 实现方式:JDBC、实体Bean和O/R Mapping
  • 对象通过JDBC SQL语句逐个字段保存到数据库中。
  • O/R mapping:?Hibernate/TopLink?JDO
  • 实体Bean中CMP,类似O/R Mapping,有着非常坚实的事务机制,支持ACID。

 

 

SQL优缺点

  • 优点:精简,类似数学公式,通过抽象符合完成逻辑操作。
  • 缺点:理解和维护不便,因为对于抽象符号的逻辑表达,不是每个人理解;如果存储过程很复杂,可能只有作者理解。

 

阻抗

  • 关系数据库和对象存在阻抗。
  • 关系数据库是一种数学范畴解决方案,使用数据结构以及关系等类似数学公式抽象方案。
  • 对象方法则是符合人类自然思维方式,例如:归纳、分类。代表一种哲学范畴解决方案。
  • 两者思考路径不一致。
  • 历史原因。数据库出现较早,先入为主。

 

 

mapping技术?

  • 对象
  • 普通对象 POJO:

Package com.jdon.sample;

public class Perso{

private String id;

private String name;

public String getId() {?returid;?}

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

 

public String getName() {?returname;?}

public void setName(String name) {

this.name = name;

}

}

映射配置文件

<?xml version="1.0" encoding="UTF-8"?>

<mapping>

<description>这是Person映射</description>

<class name=" com.jdon.sample.Person">

<map-to xml="body"/>

<field name=“id" type="string" />

<field name=“name" type="string" />

</class>

</mapping>

 

结果通过Castor 等Mapping工具映射输出

<person>

<id>12345678</id>

<name>xxx</name>

</person>

该XML可作为文件保存到硬盘,实现硬盘文件的持久化。

 

 

数据表定义

数据表名为person_table

Id?| character(32) | not null

name | character varying(16) | not null Indexes: pkey primary key btree (id) ;

数据库名XXXX。

 

数据库Mapping实现

SQL插入:

String sql =“insert into person_table (id, name) values(?, ?)”;

prepstmt = conn.prepareStatement(sql);

prepstmt.setString(1, person.getId());

prepstmt.setString(2, person.getName());

需要分解Java对象,当Java对象字段很多时,非常琐碎。

使用O/R mapping技术,只需要一句话:

session.save(person);

 

 

Hibernate实现

 

<hibernate-mapping>

<class name=“com.jdon.sample.Person" table=" person_table ">

 

<property name=“id”/>?//映射相同id

 

<property name=“name”> //person定义

<columname=“NAME” length=“16” not-null=“true”/>//数据表

</property>

 

</class>

</hibernate-mapping>

 

 

Hibernate实现映射代码

SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

//获得一个Sessio

Session?sessio= sessionFactory.openSession();

Transactiotx= session.beginTransaction();
Persoprincess = new Person();

princess.setId(“123456");

princess.setName(“彭晨阳");

session.save(princess);

tx.commit();

session.close(); //关闭一个Sessio

 

 

 

JDBC比较

Sessiosessio= sf.openSession();?

相当于Connectiocon, 开启数据库连接

Transactiotx = session.beginTransactioin(); ...
相当于 conn.setAutoCommit(false);

session.flush();

tx.commit();
相当于conn.setAutoCommit(true);

session.close();
相当于conn.close(); 连接关闭

Session是一个操作过程,类似connectio

SessionFactory是全局的,类似容器,工厂模式。

为了使上述代码运行,需要一些全局应用配置。如如何让转换代码寻找到映射配置文件hibernate.cfg.xml ?

 

 

 

Hibernate配置文件

全局性配置:数据库服务器的IP地址;访问用户和密码等通用配置。 hibernate.cfg.xml

映射Mapping配置:对象和相应数据表字段之间的映射。配置文件自己定义。

 

hibernate.cfg.xml配置

<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=“Person.hbm.xml"/>

</session-factory> </hibernate-configuration>

 

HIBernate启动

SessioFactory 和配置Configuration等类是启动 Hibernate 的主要功能类。

SessionFactory sessionFactory = new Configuration().configure()

 

SessionFactory实例比较重或大,第一次创建后保存在容器的Application或Singleton, 如struts的HibernatePlugIn。

 

配置对象映射方法:

将对象映射放入主配置Hibernate-cfg.xml 优点是集中化,但是大型项目无伸缩性。

配置对象映射在分离的XML文件中,每个对象一个配置文,然后在Hibernate-cfg.xml增加这些配置指向;或在Configuratio通过编程注册。

在SessionFactory 创建时,通过程序注册。

 

插入数据库

Cat cat = new Cat();

cat.setColor(Color.GINGER);

cat.setSex('M');

cat.setName("Fritz");

Long generatedID = (Long) sess.save(cat);

 

sess.save( pk, new Long(1234) );

 

Hibernate查询

Load三种不同用法:

Cat fritz = (Cat) sess.load(Cat.class, generatedId);

 

long pkId = 1234;

DomesticCat pk = (DomesticCat) sess.load( Cat.class, new Long(pkId) );

 

Cat cat = new DomesticCat();

// load pk's state into cat

sess.load( cat, new Long(pkId) );

Set kittens = cat.getKittens();//真正访问数据库

如果没有匹配的数据库记录,load()方法抛出exceptio

Load返回一个对象,这是一个未初始化的代理,并且直到你调用该对象的某方法时才会去访问数据库

String name = Fritz.getName();

 

Hibernate查询

get()方法,它会立刻访问数据库,如果没有对应的行,返回null。

Cat cat = (Cat) sess.get(Cat.class, id);

if (cat==null) {

cat = new Cat();

sess.save(cat, id);

}

returcat;

 

任何时候都可以使用refresh()方法重新装载对象和它的集合。如果你使用数据库触发器更改了对象的某些属性,这就很有用。

sess.save(cat);

sess.flush(); //force the SQL INSERT

sess.refresh(cat); //re-read the state (after the trigger executes)

 

懒加载Lazy

防止加载对象时取出暂时无用的大量数据。

Load完全使用lazy

Get主对象不是使用lazy,但是主对象中子对象是lazy。

为获得主对象下子对象有三种方式:

1. OpeSessioiView (J2EE)

2. Hibernate.initialize(user.get子对象());

3. 设置子对象映射关系lazy= false,失效lazy

 

Lazy和缓存

Lazy是一种代理,以JDK动态代理。

类似树形结构,如果没有lazy,获得一个Tree根节点,会将其下所有节点都加载,影响性能,浪费内存。

Lazy对Tree中的枝有效用,可防止将枝下面节点全部加载。

Lazy和缓存是hibernate基本要点。

Lazy基于模型对象优化建模。

 

更新对象

在同一Session中更新 ,直接的更改一个对象的方法就是load()它,保持Session打开,然后直接修改即可:

Cat cat = (Cat) sess.load( Cat.class, new Long(69) );
//update db

cat.setName("PK");
sess.flush();

 


 

  下页

更多Hibernate专题