Hibernate3-七个步骤

如果您已经看完了三个准备,所以看此文章是没有问题的,如果没有看完请点击此处回到上一篇。

下面我们正式开始我们的七个步骤

步骤1: 装配hibernate.cfg.xml

这里我们还是使用上一个笔记的代码继续往下写,这里我们创建一个测试类HibernateTest,在此类中有一个hibernateTest1()方法,我这里使用单元测试,所以不需要main()大家也可以使用main方法来调用都是也可以。

//第一步 装载hibernate.cfg.xml
//Configuration() 可是使用有参数构造,可以填写你指定的hibernate的文件名,例如hiber.cfg.xml
//如果不填写则默认装载src根目录下的hibernate.cfg.xml
Configuration configuration = new Configuration();
步骤2: 创建SessionFactory

Hibernate 3.x版本创建SessionFactory方法

//Hibernate 3.x版本创建SessionFactory方法
SessionFactory sessionFactory = configuration.buildSessionFactory();

Hibernate 4.x版本以上创建SessionFactory方法

//Hibernate 4.x版本创建SessionFactory方法
//ServiceRegistry接口:任何配置和服务都需要在该对象注册后才能有效
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);

用4.x版本创建SessionFactory的时候要注意如果没有找到new ServiceRegistryBuilder()对象要使用一下方式创建SessionFactory

ServiceRegistry sr = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();  
SessionFactory sf = configuration.buildSessionFactory(sr);  

Hibernate 5.x版本以上创建SessionFactory方法,我只想说呵呵,这个更变态

//Hibernate 5.x版本创建SessionFactory方法
//StandardServiceRegistry接口是一个标准服务注册接口,扩展ServiceRegistry
//使用StandardServiceRegistryBuilder()生成标准ServiceRegistry实例。
//configure() 此方法是来加载hibernate.cfg.xml文件,也就是说使用Hibernate5.x,我们可以省略第一步
//build() 此方法是用来构建StandardServiceRegistry
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build();
//我们在上面只是创建了一个标准的服务,但是Hibernate并不知道我们的映射有那些所以需要创建Metadata对象
//Metadata对象表示从映射来源确定orm模型,然后在通过buildSessionFactory()方法来创建SessionFactory对象
SessionFactory sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();

步骤3: 创建Session

Session session = sessionFactory.openSession();

步骤4: 开启事务

Transaction transaction = session.getTransaction();
//事务就不需要多说了吧,oracle的增删改都离不开事务。

步骤5: 执行添加

//我们先创建一个User对象
User user = new User();
user.setId(1);
user.setName("张三");
user.setPwd("123");
//然后执行Hibernate的保存操作
session.save(user);

步骤6: 提交事务

transaction.commit();
//提交事务,做数据持久化操作

步骤7: 关闭Seession

session.close();

这里要注意 为什么不一起关闭SessionFactory呢?
因为SessionFactory是Session的工厂,整个程序创建一次就可以,我们要到Session的时候直接从工厂获取,也就是sessionFactory.openSession()
这个方法;而程序结束会自动释放SessionFactory对象所以不需要我们关闭,当然在此例程序中你也可以手动关闭。

运行程序,做测试

到此为止,我们的三个准备和七个步骤已经做完了;现在我们可以运行一下我们的程序


hibernate3-1.png

好的非常漂亮,一个小小的程序都给我报错了,好的上面说类为找到异常,而且提示出那个类没有找到,可以看到并不是我们自己写的类,还有继续往下看提示我们发现是因为我们的单元测试引起的,所以我们需要找到对应的架包,添加上去即可。
好吧再一次出错了

org.hibernate.MappingException: Repeated column in mapping for entity: cc.ibadboy.hibernate.hibernate2.entity.User column: name (should be mapped with insert="false" update="false")

他说我的映射异常,而且已经告诉我们是那个实体类了cc.ibadboy.hibernate.hibernate2.entity.User,并且提示我们 column: name, 那么我们就找这个实体类的映射文件,发现

<property name="name" type="java.lang.String" column="name" length="50" not-null="true"/>
<property name="pwd" type="java.lang.String"  column="name" length="50" not-null="true"/>

发现column数据值相同,我们应该将name="pwd"的column属性值改为pwd

<property name="name" type="java.lang.String" column="name" length="50" not-null="true"/>
<property name="pwd" type="java.lang.String"  column="pwd" length="50" not-null="true"/>

我们继续调试程序,又出错了 但是这个错误非常好

hibernate3-2.png

可以看到 我们的程序没有用到JNDI为什么会出现这个错误呢?而且为什么提示我说Error parsing JNDI name [foo]这是因为我们的hibernate.cfg.xml配置文件中的<session-factory/>标签有一个name属性,这个name属性值为foo,当我们设置此属性Hibernate试图将这个sessionFacoty注册到JNDI中,我们项目没有用到JNDI所以会出错的。记下来看第二个问题org.hibernate.TransactionException: Transaction not successfully started事务没有成功开启,但是我前面已经使用session.getTransaction();获取到了事务了啊,为什么失败呢?
是的session.getTransaction();
的确会获取事务,获取的是session对象所开启的事务,你的session对象都没有开启事务所以当然获取不到啊。
而这里我们要使用session.beginTransaction();来开启事务,这里希望大家注意一下,你虽然使用sessionFactory.openSession();
来获取了一个Session对象,但获取的仅仅只是一个Session对象而已,并没有自动的为我们开启事务。
好的两个错误解决完了,我们继续调试吧
hibernate3-3-1.png

好了调试成功可以看到输出的sql语句,1.先删除了表。2.为我们创建了新表。3.插入了我们的数据。

这里未必非要使用oracle数据库你用mysql也是可以的,前面我们也说了hibernate会为我们自动生成sql语句,生成的sql语句肯定也是对应你使用的数据库的啊。

注意

细心的读者可能会意识到,为什么我们通过main()
方法或者单元测试,也可以通过hibernate来做数据持久化,而不需要通过web容器(如:tomcat)呢?
答:因为dao、serivce层根web容器没有关系。

详细说说用到的接口和类的作用

在上面的代码中我们要到了一些接口和类,虽然在代码注释中有写到,但是我在这里在做一下总结.
    1.Configuration:通过加载配置文件管理获取并管理配置信息,默认读取hibernate.cfg.xml文件;如果你需要自定义配置文件(*.cfg.xml)那么就需要使用new Configuration().configuration(*.cfg.xml),星号表示你自己的文件名,当然也可以传入一个File对象。
    2.SessionFactory:是Session工厂类,专门帮我们来new Session的;SessionFactory也有一个缓存机制,称为二级缓存可以作用在进程或集群上。也可以说hibernate的二级缓存是SessionFactory维护的。在大多数情况下SessionFactory在整个应用程序中只创建一次。
    3.Session:是我们以后用的主要对象。此对象是比较轻量级的,我们以后可以随便创建;而我们的增删改查操作,都是通过此对象来完成。注意:一个Session对象只可以由一个线程使用。我们可以想想一下,当一个浏览器发送请求到tomcat服务器的时候,tomcat会开启一个线程操作,这个线程里面调用我们的action->serivce->dao,而在dao中有我们的hibernate的一些操作,所以会启动(通过SessionFactory获取)一个Session对象。每一次浏览器发送请求到tomcat服务器的时候都会执行以上操作,所以说Session对象是属于我们一个线程中的,也可以说成Session对象由一个线程使用。
    4.Transaction:用来管理事务的。我们需要在增删改的时候需要开启事务。注意:hibernate中的事务是不会自动提交的。
    5.StandardServiceRegistry:一个标准服务注册接口,扩展ServiceRegistry使用StandardServiceRegistryBuilder()生成标准ServiceRegistry实例。
    6.Metadata:从映射来源确定orm模型,然后在通过buildSessionFactory()方法来创建SessionFactory对象。

我个人感觉这些代码不许要特意记住,用到的时候拷贝就可以了,而且最后会通过Spring整合,整合后更用不上了。

大大的总结

    1.Configuration:加载hibernate.cfg.xml文件。读取用户名、密码、方言、映射信息等。而读取的数据信息,全部放在SessionFactory对象中的。
    2.SessionFactory:根据单个数据(单个hibernate.cfg.xml文件)编译后的内存镜像,编译无法改变,都是从这里来获取Session对象。我个人认为SessionFactory有点像你使用jdbc来操作数据库时的Connection对象。
    3.Session:封装了JDBC的操作,通过Session中的方法,可以简化复杂的JDBC操作。我个人因为Session有点像你使用jdbc来操作数据库时的PreparedStatement对象。

资源下载
本节笔记代码我已经上传到了github上大家可以点击下载
下载链接:Hibernate3.zip

配图
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,598评论 18 399
  • Hibernate: 一个持久化框架 一个ORM框架 加载:根据特定的OID,把一个对象从数据库加载到内存中OID...
    JHMichael阅读 1,963评论 0 27
  • 这部分主要是开源Java EE框架方面的内容,包括Hibernate、MyBatis、Spring、Spring ...
    杂货铺老板阅读 1,357评论 0 2
  • 本文包括:1、Hibernate的持久化类2、Hibernate 持久化对象的三个状态(难点)3、Hibernat...
    廖少少阅读 1,444评论 0 13
  • 阿呆站在路口,静静的看着马路对面的车祸现场。一阵风吹过,他打了个哆嗦,救护车还没到,似乎伤员已经坚持不住了。 他看...
    郑小五阅读 379评论 0 0