如果您已經(jīng)看完了三個準備攻旦,所以看此文章是沒有問題的,如果沒有看完請點擊此處回到上一篇。
下面我們正式開始我們的七個步驟
步驟1: 裝配hibernate.cfg.xml
這里我們還是使用上一個筆記的代碼繼續(xù)往下寫,這里我們創(chuàng)建一個測試類HibernateTest
膛壹,在此類中有一個hibernateTest1()
方法,我這里使用單元測試唉堪,所以不需要main()
大家也可以使用main方法來調(diào)用都是也可以模聋。
//第一步 裝載hibernate.cfg.xml
//Configuration() 可是使用有參數(shù)構(gòu)造,可以填寫你指定的hibernate的文件名唠亚,例如hiber.cfg.xml
//如果不填寫則默認裝載src根目錄下的hibernate.cfg.xml
Configuration configuration = new Configuration();
步驟2: 創(chuàng)建SessionFactory
Hibernate 3.x版本創(chuàng)建SessionFactory方法
//Hibernate 3.x版本創(chuàng)建SessionFactory方法
SessionFactory sessionFactory = configuration.buildSessionFactory();
Hibernate 4.x版本以上創(chuàng)建SessionFactory方法
//Hibernate 4.x版本創(chuàng)建SessionFactory方法
//ServiceRegistry接口:任何配置和服務都需要在該對象注冊后才能有效
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
用4.x版本創(chuàng)建SessionFactory的時候要注意如果沒有找到new ServiceRegistryBuilder()
對象要使用一下方式創(chuàng)建SessionFactory
ServiceRegistry sr = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
SessionFactory sf = configuration.buildSessionFactory(sr);
Hibernate 5.x版本以上創(chuàng)建SessionFactory方法链方,我只想說呵呵,這個更變態(tài)
//Hibernate 5.x版本創(chuàng)建SessionFactory方法
//StandardServiceRegistry接口是一個標準服務注冊接口灶搜,擴展ServiceRegistry
//使用StandardServiceRegistryBuilder()生成標準ServiceRegistry實例祟蚀。
//configure() 此方法是來加載hibernate.cfg.xml文件,也就是說使用Hibernate5.x割卖,我們可以省略第一步
//build() 此方法是用來構(gòu)建StandardServiceRegistry
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build();
//我們在上面只是創(chuàng)建了一個標準的服務前酿,但是Hibernate并不知道我們的映射有那些所以需要創(chuàng)建Metadata對象
//Metadata對象表示從映射來源確定orm模型,然后在通過buildSessionFactory()方法來創(chuàng)建SessionFactory對象
SessionFactory sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
步驟3: 創(chuàng)建Session
Session session = sessionFactory.openSession();
步驟4: 開啟事務
Transaction transaction = session.getTransaction();
//事務就不需要多說了吧鹏溯,oracle的增刪改都離不開事務罢维。
步驟5: 執(zhí)行添加
//我們先創(chuàng)建一個User對象
User user = new User();
user.setId(1);
user.setName("張三");
user.setPwd("123");
//然后執(zhí)行Hibernate的保存操作
session.save(user);
步驟6: 提交事務
transaction.commit();
//提交事務,做數(shù)據(jù)持久化操作
步驟7: 關閉Seession
session.close();
這里要注意 為什么不一起關閉SessionFactory呢丙挽?
因為SessionFactory是Session的工廠言津,整個程序創(chuàng)建一次就可以攻人,我們要到Session的時候直接從工廠獲取,也就是sessionFactory.openSession()
這個方法悬槽;而程序結(jié)束會自動釋放SessionFactory對象所以不需要我們關閉,當然在此例程序中你也可以手動關閉瞬浓。
運行程序初婆,做測試
到此為止,我們的三個準備和七個步驟已經(jīng)做完了猿棉;現(xiàn)在我們可以運行一下我們的程序
好的非常漂亮磅叛,一個小小的程序都給我報錯了,好的上面說類為找到異常萨赁,而且提示出那個類沒有找到弊琴,可以看到并不是我們自己寫的類,還有繼續(xù)往下看提示我們發(fā)現(xiàn)是因為我們的單元測試引起的杖爽,所以我們需要找到對應的架包敲董,添加上去即可。
好吧再一次出錯了
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")
他說我的映射異常慰安,而且已經(jīng)告訴我們是那個實體類了cc.ibadboy.hibernate.hibernate2.entity.User
腋寨,并且提示我們 column: name
, 那么我們就找這個實體類的映射文件,發(fā)現(xiàn)
<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"/>
發(fā)現(xiàn)column數(shù)據(jù)值相同化焕,我們應該將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"/>
我們繼續(xù)調(diào)試程序萄窜,又出錯了 但是這個錯誤非常好
可以看到 我們的程序沒有用到JNDI為什么會出現(xiàn)這個錯誤呢?而且為什么提示我說
Error parsing JNDI name [foo]
這是因為我們的hibernate.cfg.xml
配置文件中的<session-factory/>
標簽有一個name屬性撒桨,這個name屬性值為foo查刻,當我們設置此屬性Hibernate試圖將這個sessionFacoty注冊到JNDI中,我們項目沒有用到JNDI所以會出錯的凤类。記下來看第二個問題org.hibernate.TransactionException: Transaction not successfully started
事務沒有成功開啟穗泵,但是我前面已經(jīng)使用session.getTransaction();獲取到了事務了啊,為什么失敗呢踱蠢?是的
session.getTransaction();
的確會獲取事務火欧,獲取的是session對象所開啟的事務,你的session對象都沒有開啟事務所以當然獲取不到啊茎截。
而這里我們要使用
session.beginTransaction();
來開啟事務苇侵,這里希望大家注意一下,你雖然使用sessionFactory.openSession();
來獲取了一個Session對象企锌,但獲取的僅僅只是一個Session對象而已榆浓,并沒有自動的為我們開啟事務。
好的兩個錯誤解決完了撕攒,我們繼續(xù)調(diào)試吧
好了調(diào)試成功可以看到輸出的sql語句陡鹃,1.先刪除了表烘浦。2.為我們創(chuàng)建了新表。3.插入了我們的數(shù)據(jù)萍鲸。
這里未必非要使用oracle數(shù)據(jù)庫你用mysql也是可以的闷叉,前面我們也說了hibernate會為我們自動生成sql語句,生成的sql語句肯定也是對應你使用的數(shù)據(jù)庫的啊脊阴。
注意
細心的讀者可能會意識到握侧,為什么我們通過main()
方法或者單元測試,也可以通過hibernate來做數(shù)據(jù)持久化嘿期,而不需要通過web容器(如:tomcat)呢?
答:因為dao品擎、serivce層根web容器沒有關系。
詳細說說用到的接口和類的作用
在上面的代碼中我們要到了一些接口和類备徐,雖然在代碼注釋中有寫到萄传,但是我在這里在做一下總結(jié).
????1.Configuration:通過加載配置文件管理獲取并管理配置信息,默認讀取hibernate.cfg.xml文件;如果你需要自定義配置文件(*.cfg.xml)那么就需要使用new Configuration().configuration(*.cfg.xml)
蜜猾,星號表示你自己的文件名秀菱,當然也可以傳入一個File對象。
????2.SessionFactory:是Session工廠類瓣铣,專門幫我們來new Session的;SessionFactory也有一個緩存機制答朋,稱為二級緩存可以作用在進程或集群上。也可以說hibernate的二級緩存是SessionFactory維護的棠笑。在大多數(shù)情況下SessionFactory在整個應用程序中只創(chuàng)建一次梦碗。
????3.Session:是我們以后用的主要對象。此對象是比較輕量級的蓖救,我們以后可以隨便創(chuàng)建洪规;而我們的增刪改查操作,都是通過此對象來完成循捺。注意:一個Session對象只可以由一個線程使用斩例。我們可以想想一下,當一個瀏覽器發(fā)送請求到tomcat服務器的時候从橘,tomcat會開啟一個線程操作念赶,這個線程里面調(diào)用我們的action->serivce->dao,而在dao中有我們的hibernate的一些操作恰力,所以會啟動(通過SessionFactory獲取)一個Session對象叉谜。每一次瀏覽器發(fā)送請求到tomcat服務器的時候都會執(zhí)行以上操作,所以說Session對象是屬于我們一個線程中的踩萎,也可以說成Session對象由一個線程使用停局。
????4.Transaction:用來管理事務的。我們需要在增刪改的時候需要開啟事務。注意:hibernate中的事務是不會自動提交的董栽。
????5.StandardServiceRegistry:一個標準服務注冊接口码倦,擴展ServiceRegistry使用StandardServiceRegistryBuilder()生成標準ServiceRegistry實例。
????6.Metadata:從映射來源確定orm模型锭碳,然后在通過buildSessionFactory()方法來創(chuàng)建SessionFactory對象袁稽。
我個人感覺這些代碼不許要特意記住,用到的時候拷貝就可以了工禾,而且最后會通過Spring整合运提,整合后更用不上了。
大大的總結(jié)
????1.Configuration:加載hibernate.cfg.xml文件闻葵。讀取用戶名、密碼癣丧、方言槽畔、映射信息等。而讀取的數(shù)據(jù)信息胁编,全部放在SessionFactory對象中的厢钧。
????2.SessionFactory:根據(jù)單個數(shù)據(jù)(單個hibernate.cfg.xml文件)編譯后的內(nèi)存鏡像,編譯無法改變嬉橙,都是從這里來獲取Session對象早直。我個人認為SessionFactory有點像你使用jdbc來操作數(shù)據(jù)庫時的Connection對象。
????3.Session:封裝了JDBC的操作市框,通過Session中的方法霞扬,可以簡化復雜的JDBC操作。我個人因為Session有點像你使用jdbc來操作數(shù)據(jù)庫時的PreparedStatement對象枫振。
資源下載
本節(jié)筆記代碼我已經(jīng)上傳到了github上大家可以點擊下載
下載鏈接:Hibernate3.zip