分享
 
 
 

初学者想学Hibernate,初级基础教程

王朝other·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

Hibernate理论基础

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:oracle: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)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有