1. 什么是hibernate? 
2. hibernate的知识内容 
3. 什么是对象持久化?对象持久化有什么用?(解决的问题) 
4. 如何对象持久化? 
5. 如何用数据库的方法做对象持久化? 
6. ORM(对象关系映射)是什么?有什么作用? 
7. ORM从对象到表所要考虑的问题 
8. 什么是ORM框架?有什么用? 
9. 使用hibernate的方法做对象持久化的工作,程序员应该怎么做? 
10. hibernate有什么用? 
11. 程序员和hibernate的整体工作流程
什么是hibernate: 
持久化的框架,属于设计方面的内容,类库,用来做对象持久化的,什么是对象持久化呢? 
Hibernate的知识内容: 
语法部分(类库) 
程序设计思想,也就是持久层的设计 
什么是对象持久化?对象持久化有什么用?(解决的问题): 
发现问题: 
程序设计的架构: 表现层—业务层—持久层—数据库层,其中表现层和业务层是JVM来执行,应用程序会产生许多的对象,如果断电了,对象就消失了,也就是说在内存中的对象是不稳定的,状态不能持久 
发现问题: 
将一个对象从A电脑复制到B电脑,如何做到呢? 
那么有三种方法解决上面的问题: 
1. 序列化: 通过网络传递,或者硬盘共享 
2. 存储到数据库中,谁想用,从数据库中拿 
3. EJB Entity Bean(实体Bean) 
序列化的方法比较死板:如果当一个对象的结构比较复杂的时候,我们这时只需要一部分内容,没有办法,只能整个写入到文件,整个读取 
序列化的缺点: 不能检索,不能分离一个对象,不方便共享 
所以说第一种方法只能用于做临时的持久化,简单的传输,但不适合复杂的持久化工作 
第二种方法(数据库持久化):检索方便,分布式共享,永久数据 
总结: 
什么是对象持久化: 对象持久化就是把内存中的对象永久的保存起来,保护对象的状态,方便使用 
对象持久化有什么用: 1.解决掉电的问题 2.共享方便 3.保证对象安全检索方便 
如何对象持久化: 
1. 对象序列化 
2. 数据库(JDBC,EJB,Hibernate) 
如何用数据库的方法做对象持久化: 
1. JDBC 
发现问题: 需要做大量的工作,难度大 
2. EJB 
使用的是其中的一个功能来做持久化,解决了使用JDBC方法的的大量工作的问题 
发现问题: EJB是重量级的组件,要使用它,有两个问题 1.成本 2.性能 
发现问题: 以上两种方式还有个共同的问题,对象不是简单存储在数据库中的,比如多态的特点就不能处理 A b=new B(); B为A的子类 
3. Hibernate 
解决了以上的所有问题,作用:1.不用做大量的工作 2.移植性能好 3.提高了代码的质量,简单 4.检索共享重用成本调试 
ORM(对象关系映射)是什么?有什么作用? 
发现问题: 
java中的对象的属性类型和数据库中的字段类型是不一样的,那么如何来存储java中的对象呢?这就需要做对象关系的映射,也就是ORM 
什么是ORM: 将内存中的对象和数据库做转化,这样就实现了java与数据库之间的访问等功能 
ORM从对象到表所要考虑的问题: 
Orm的复杂问题: 
1. 数据库如何保证对象的唯一性:在内存中,两个对象属性值都一样,但是内存地址不一样,可以做区分,但是在数据库中如何分辨呢? 
2. 继承关系如何转化 
3. 集合如何映射呢? 
什么是ORM框架?有什么用? 
就是一个类库,通过这个类库完成持久化层的设计 
使用hibernate的方法做对象持久化的工作,程序员应该怎么做? 
1. 将ORM方案定下来,就是类到数据库的转化 2.利用hibernate生成代码 
hibernate有什么用? 
1. 完成jdbc的代码 
2. 管理持久化对象的状态 
3. 提供一个查询的API 
程序员和hibernate的整体工作流程 
程序员: 
1. 设计ORM方案 
2. 写配置文件 
3. 调用Hibernate的API,向Hibernate发出命令 
hibernate: 
4. 读配置文件 
5. 生成jdbc代码 
6. 执行 
Hibernate简单实例 
Hibernate语法: 
作用: 数据库的增删改查 HQL面向对象的查询语句 
大致步骤: 
1. 设置环境 类库 
2. 定义映射 
A 定义映射的实体po 
B 建立数据库表 
C 写XML配置文件(表,数据库) 
3. 调用Hibernate API 
A 管理po的状态(增删改,恢复po状态) 
B 检索(查询) 
Hibernate第一个简单的实例: 引例(frisHbn包) 
1. 设置环境 
hibernate配置环境需要的资源 
Hibernate的jar包: lib.zip dtd.zip: dtd.zip可以不设置 
2. 定义映射 
建立项目: 
bussiness包: entity包 Biz包业务 
client包: 测试 
util包: 工具 
先写持久化类: 以花为实体,建立花类,并且建立数据库表 
/** 
* 建表语句: 
* CREATE TABLE T_FRUIT( 
FID NUMBER(10) PRIMARY KEY, 
NAME VARCHAR(20) NOT NULL, 
COMMENTS VARCHAR(50), 
PRICE NUMBER(5) NOT NULL 
); 
*/ 
package Yuchen.fristHbn.business.entity; 
//持久化类(花类),注意因为采用的是hilo的方式获得id,所以需要有setid的方法 
public class Fruit { 
private Integer fid;//hibernate中的id不能识别int 
private String name; 
private String comments; 
private int price; 
public Fruit() { 
super(); 
} 
public Fruit(String name, String comments, int price) { 
super(); 
this.name = name; 
this.comments = comments; 
this.price = price; 
} 
public String getComments() { 
return comments; 
} 
public void setComments(String comments) { 
this.comments = comments; 
} 
public Integer getFid() { 
return fid; 
} 
public String getName() { 
return name; 
} 
public void setName(String name) { 
this.name = name; 
} 
public int getPrice() { 
return price; 
} 
public void setPrice(int price) { 
this.price = price; 
} 
public void setFid(Integer fid) { 
this.fid = fid; 
} 
} 
使用hilo的方式获得id: 
建表语句: 
CREATE TABLE T_HILO(HILO_ID NUMBER(10)); 
INSERT INTO T_HILO VALUES(1); 
写hibernate的连接数据库的配置文件: 
<?xml version="1.0"?> 
<!DOCTYPE hibernate-configuration PUBLIC 
"-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 
<hibernate-configuration> 
<session-factory> 
<property name="show_sql">true</property> 
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property> 
<property name="connection.url">jdbc

racle:thin

127.0.0.1:1521:name</property> 
<property name="connection.username">scott</property> 
<property name="connection.password">tiger</property> 
<property name="connection.isolation">2</property> 
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property> 
<mapping resource="Yuchen/fristHbn/business/entity/Fruit.hbm.xml"/> 
</session-factory> 
</hibernate-configuration> 
写映射配置文件: 
<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping package="Yuchen.fristHbn.business.entity"> 
<class name="Fruit" table="T_FRUIT"> 
<id name="fid" column="fid"> 
<generator class="hilo"> 
<param name="table">t_hilo</param> 
<param name="column">hilo_id</param> 
</generator> 
</id> 
<property name="name" column="name" /> 
<property name="comments" column="comments"></property> 
<property name="price" column="price"></property> 
</class> 
</hibernate-mapping> 
A. 类名—表名 
B. id—id 获得id的方式 详细信息(如: hilo的表名和字段) 
C. 属性—字段 
使用hibernate API(FruitManager.java): 
package Yuchen.fristHbn.business.Biz; 
//业务逻辑类:负责增删改查通过使用hibernate API进行 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.hibernate.Transaction; 
import org.hibernate.cfg.Configuration; 
import Yuchen.fristHbn.business.entity.Fruit; 
public class FruitManager { 
public void insert(Fruit fruit){ 
Configuration config=new Configuration(); 
config.configure();//读配置文件 
SessionFactory sf=config.buildSessionFactory();//得到工厂 
Session session=sf.openSession();//得到session 
Transaction tt=session.beginTransaction();//检查事务开启 
session.save(fruit);//存储insert 
tt.commit();//提交 
session.close();//关闭资源 
} 
} 
写测试类: 插入一个对象到数据库中 
/** 
* 知识点: 
* hibernate基础:练习语法部分API和简单的映射关系 
* 程序目标: 
* 使用hibernate方法将对象进行持久化 
* 实现数据库的增删改查 
* API: 
* 1.Configuration:这个类负责读取XML文档(映射配置文件) 
* configure():读xml 
* buildSessionFactory():创建一个生产session对象的工厂,其实是再次检查 
* 因为hibernate和jdbc不一样,jdbc是如果不手动设置开启事务,那它 
* 就是马上执行sql的,hibernate的不会马上执行,是事务提交后执行 
* 默认情况下就是打开事务的状态,这里只是再检查以下 
* 2.SessionFactory:负责生产session对象 
* openSession():创建一个session 
* 3.Session类:这个是主要的类,负责增删改查,开启事务等 
* beginTransaction():产生一个事务对象(Transaction) 
* save():增加相当于操作sql中的insert语句 
* 4.Transaction类:负责管理事务的 
* commit():提交一个事务 
* 
*/ 
package Yuchen.fristHbn.client; 
import Yuchen.fristHbn.business.Biz.FruitManager; 
import Yuchen.fristHbn.business.entity.Fruit; 
public class Test { 
public static void test1(){ 
Fruit fruit=new Fruit("lisi","hello",100); 
// fruit.setName("zhangsan"); 
// fruit.setComments("hello"); 
// fruit.setPrice(100); 
FruitManager fm=new FruitManager(); 
fm.insert(fruit); 
} 
public static void main(String[] args) { 
// TODO 自动生成方法存根 
Test t=new Test(); 
t.test1(); 
} 
} 
hibernate API(一): 
Configuration: 读取配置文件信息用来初始化的 
SessionFactory: 重量级对象,特点:消耗资源大,线程是安全,所以可以被共享 
上面两个对象只实例化一个就行了,都是用于初始化的 
Session: 线程是不安全的,所以要避免多个线程共享它,是轻量级的对象,使用后关闭 
Session对象的状态: 
顺态: 还没有被持久化,也就是说数据库中没有该对象的记录,并且Session中的缓冲区里没有这个对象的引用 
持久态: 在数据库中有该对象的记录,并且在session中的缓冲区里有这个对象的引用,和顺态正好相反 
游离态: 在数据库中有记录,但是不在session的缓冲区里 
对象状态的转换: 
做一个工具类,将hibernate中重复的代码包装起来: 
package Yuchen.fristHbn.util; 
//生产session对象的工具类 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.hibernate.cfg.Configuration; 
public class HbnUtil { 
private static SessionFactory sf; 
static{ 
sf=new Configuration().configure().buildSessionFactory(); 
} 
public static Session getSession(){ 
return sf.openSession(); 
} 
} 
完善FruitManager类: 
package Yuchen.fristHbn.business.Biz; 
//业务逻辑类:负责增删改查通过使用hibernate API进行 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.hibernate.Transaction; 
import org.hibernate.cfg.Configuration; 
import Yuchen.fristHbn.business.entity.Fruit; 
import Yuchen.fristHbn.util.HbnUtil; 
public class FruitManager { 
public Integer insert(Fruit fruit){ 
Session session=HbnUtil.getSession();//通过工具更方便了 
Integer id=null; 
// Configuration config=new Configuration(); 
// config.configure();//读配置文件 
// SessionFactory sf=config.buildSessionFactory();//得到工厂 
// Session session=sf.openSession();//得到session 
Transaction tt=session.beginTransaction();//检查事务开启 
id=(Integer)session.save(fruit);//存储insert 
tt.commit();//提交 
session.close();//关闭资源 
return id; 
} 
public Fruit selectId(Integer id){ 
Session session=HbnUtil.getSession(); 
Transaction t=session.beginTransaction(); 
Fruit fruit=(Fruit)session.get(Fruit.class, id); 
t.commit(); 
session.close(); 
return fruit; 
} 
public void remove(Fruit fruit){ 
Session session=HbnUtil.getSession(); 
Transaction t=session.beginTransaction(); 
session.delete(fruit); 
t.commit(); 
session.close(); 
} 
} 
测试对象状态的转换: 
/** 
* 知识点: 
* hibernate基础:练习语法部分API和简单的映射关系 
* 程序目标: 
* 使用hibernate方法将对象进行持久化 
* 实现数据库的增删改查 
* API: 
* 1.Configuration:这个类负责读取XML文档(映射配置文件) 
* configure():读xml 
* buildSessionFactory():创建一个生产session对象的工厂,其实是再次检查 
* 因为hibernate和jdbc不一样,jdbc是如果不手动设置开启事务,那它 
* 就是马上执行sql的,hibernate的不会马上执行,是事务提交后执行 
* 默认情况下就是打开事务的状态,这里只是再检查以下 
* 2.SessionFactory:负责生产session对象 
* openSession():创建一个session 
* 3.Session类:这个是主要的类,负责增删改查,开启事务等 
* beginTransaction():产生一个事务对象(Transaction) 
* save():增加相当于操作sql中的insert语句 
* 4.Transaction类:负责管理事务的 
* commit():提交一个事务 
* test1():测试插入的功能 
* test2():测试数据同步更新的功能 
* test3():测试saveOrUpdate() 
* test4():测试clear()和flush() 
*/ 
package Yuchen.fristHbn.client; 
import org.hibernate.Session; 
import org.hibernate.Transaction; 
import Yuchen.fristHbn.business.Biz.FruitManager; 
import Yuchen.fristHbn.business.entity.Fruit; 
import Yuchen.fristHbn.util.HbnUtil; 
public class Test { 
public void test1(){ 
Fruit fruit=new Fruit("lisi","hello",100); 
// fruit.setName("zhangsan"); 
// fruit.setComments("hello"); 
// fruit.setPrice(100); 
FruitManager fm=new FruitManager(); 
fm.insert(fruit); 
} 
public void test2(){ 
//测试同步更新的功能 
Fruit fruit=new Fruit("meigui","hongse",70);//顺态 
FruitManager fm=new FruitManager(); 
Fruit fruit2=new Fruit(); 
Integer id=fm.insert(fruit); 
fruit2=fm.selectId(id); 
System.out.println(fruit2.getFid()); 
System.out.println(fruit2.getName()); 
fruit.setName("ziluolan");//这里修改了对象 
fruit2=fm.selectId(id); 
System.out.println(fruit2.getFid());//但是结果没有更新 
System.out.println(fruit2.getName()); 
//因为fruit在Integer id=fm.insert(fruit);后变成游离态了 
//也就是说只有持久态才能实现同步更新 
System.out.println(fruit.getFid()); 
System.out.println(fruit.getName()); 
} 
public void test3(){ 
Session session=HbnUtil.getSession(); 
Transaction t=session.beginTransaction(); 
Fruit fruit=new Fruit("ziluolan","lanse",100);//顺态 
Fruit fruit2=new Fruit(); 
FruitManager fm=new FruitManager(); 
session.save(fruit);//fruit在运行完此句后变为游离态 
fruit2=(Fruit) session.get(Fruit.class, fruit.getFid()); 
//从数据库读并打印出来 
System.out.println(fruit2.getFid()+":"+fruit2.getName()); 
session.saveOrUpdate(fruit);//如果该对象为游历态就更新数据库update 
//否则就是顺态,增加insert 
fruit2=(Fruit) session.get(Fruit.class, fruit.getFid()); 
//saveOrUpdate后再从数据库读并打印出来 
System.out.println(fruit2.getFid()+":"+fruit2.getName()); 
//两个打印结果一样,saveOrUpdate方法判断如果id为null,就 
//顺态,否则就是游离态 
t.commit(); 
session.close(); 
} 
public void test4(){ 
Session session=HbnUtil.getSession(); 
Transaction t=session.beginTransaction(); 
Fruit fruit=new Fruit("guihua","fense",300);//顺态 
Fruit fruit2=new Fruit(); 
session.saveOrUpdate(fruit);//执行insert因为对象为顺态 
// session.flush(); 
session.clear();//fruit变成游离态了,并且不会执行insert语句 
//因为hibernate不是马上执行sql,而是等t.commit()提交事务 
//后才执行,clear后,对象为游离态 
session.saveOrUpdate(fruit);//这里验证上面的话,执行update 
//做个select查看一下,可以证明,因为clear后,没有马上执行 
//sql语句,所以表里没有数据,这里update也没有用,所以表中 
//一个对象也没插入,但是如果加入flush()刷新就是马上执行sql了 
t.commit(); 
session.close(); 
} 
public static void main(String[] args) { 
// TODO 自动生成方法存根 
Test t=new Test(); 
// t.test1(); 
// t.test2(); 
// t.test3(); 
t.test4(); 
} 
} 
hibernate API(二): 
flush(): 从上面的例子可以看出,flush是刷新session的缓冲区,并执行里面的命令 
flush()的事务管理模式: flushMode()里面有三个常量,可以用数字来表示 
Load(): 另一种读取数据的方法,和get的区别是: 1.异常处理: load有异常处理,get没有,它返回null,2.get从数据库读数据,load可能去读缓冲区 
事务的隔离级别: 
在hibernate的数据库配置文件中设置 
数字1为可以脏读,数字2为不能,这个是最常用的 
锁机制: 
避免并发冲突,在数据库中写数据是自动加锁的,读一般不加,有悲观锁和乐观锁 
乐观锁是可以是hibernate程序自己加 
实现乐观锁: 引例(hbn2包) 
步骤: 
1. 在表中加个version字段 
2. 在持久类里加个version属性 
3. 配置文件<version name=”versopm”> 每存一次值加1 
引例:hbn2包 
复杂的映射: 
1. 基数关系映射 
2. 继承关系映射 
3. 组件关系映射 
4. 集合映射 
基数关系的映射—one to one: 
基数关系的映射需要考虑的问题: 
1. 数量问题 
2. 方向问题 
在one to one的关系中,我们有两种方法可以体现类与类之间的关系 
1. 共享主键 
2. 外键唯一 
引例: Joto包-此包引用了fristHbn包 
建立与Fruit类有一对一关系的类: 
我们认为一个花有一个产地,一个产地生产一种花,所以要建立产地类 
package Yuchen.Joto.business.entity; 
//花的地址类 
//问题:为什么不能在构造函数中写Fruit?因为生成对象后要持久化 
//这个对象,但是数据库的表中不能插入另一个类的值,写上null又不 
//大合适,所以就去掉它 
public class Address { 
private Integer aid; 
private String nation; 
private String postcode; 
private Fruit fruit; 
public Address() { 
} 
public Address(String nation, String postcode) { 
super(); 
this.nation = nation; 
this.postcode = postcode; 
} 
public Integer getAid() { 
return aid; 
} 
public void setAid(Integer aid) { 
this.aid = aid; 
} 
public Fruit getFruit() { 
return fruit; 
} 
public void setFruit(Fruit fruit) { 
this.fruit = fruit; 
// fruit.setAddress(this); 
} 
public String getNation() { 
return nation; 
} 
public void setNation(String nation) { 
this.nation = nation; 
} 
public String getPostcode() { 
return postcode; 
} 
public void setPostcode(String postcode) { 
this.postcode = postcode; 
} 
} 
修改Fruit类: 
package Yuchen.Joto.business.entity; 
//持久化类(花类),注意因为采用的是hilo的方式获得id,所以需要有setid的方法 
public class Fruit { 
private Integer fid;//hibernate中的id不能识别int 
private String name; 
private String comments; 
private int price; 
private Address address;//一朵花对应一个地址 
public Fruit() { 
super(); 
} 
public Fruit(String name, String comments, int price) { 
super(); 
this.name = name; 
this.comments = comments; 
this.price = price; 
} 
public Address getAddress() { 
return address; 
} 
public void setAddress(Address address) { 
this.address = address; 
address.setFruit(this);//因为当你给一个花设置产地的时候 
//该产地也有了花 
} 
public String getComments() { 
return comments; 
} 
public void setComments(String comments) { 
this.comments = comments; 
} 
public Integer getFid() { 
return fid; 
} 
public String getName() { 
return name; 
} 
public void setName(String name) { 
this.name = name; 
} 
public int getPrice() { 
return price; 
} 
public void setPrice(int price)