初次學習Hibernate,瞭解到他是全自動裝配SQL的後端持久層框架,他讓開發人員成功從大量的jdbc編程中解放出來,但它的底層依然使用jdbc,使用xml配置文件完成jdbc連接的配置,並通過xml實現表結構與對象屬性的映射。它爲面向對象的領域模型到傳統的關係型數據庫的映射,提供了一個使用方便的框架。
我使用的是hibernate4.2.4的版本。作爲持久層的框架,數據庫就先建起來。現在還沒有存放數據。然後在myEclipse中導入jar包開始使用hibernate。
對jdbc的配置主要通過hibernate.cfg.xml來實現。各個標籤的意思很明瞭,各個property中配置數據庫驅動,連接以及賬號密碼等信息。
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<!-- hibernate框架的配置文件 -->
<hibernate-configuration>
<session-factory>
<property name="connection.username">root</property>
<property name="connection.password">1234</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="connection.url">
jdbc:sqlserver://localhost:3306;DatabaseName=Student
</property>
<!-- 指定SQL“方言” -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- 建表策略 -->
<property name="hbm2ddl.auto">create</property>
<property name="myeclipse.connection.profile"></property>
<!-- 關係映射文件的存放地址 -->
<mapping resource="Student.hbm.xml" />
</session-factory>
</hibernate-configuration>
需要說明的:
1、hbm2ddl.auto這項property是建表策略,當爲create的時候對錶的每一項操作都會drop舊錶create新表後再操作。而update則是操作都基於現有的表而不會去刪掉重建。前者需要注意數據會被清空,後者需要注意找不到表的異常。dialect指定SQL方言方便生成語句,show_sql爲true則在生成SQL語句後會打印在console裏,format爲true則打印出來的SQL會按照格式排版。
2、mapping標籤指定了表結構和對象的映射文件的名字(放在同一目錄下)。
實體類不貼圖,屬性和數據庫表一致即可。而如上述關係映射文件以.hbm.xml文件命名。
Student.hbm.xml內容:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="hibernate.Student" table="Student_info">
<!-- 主鍵生成策略 -->
<id name="Sno" type="java.lang.Integer">
<column name="Sno"></column>
<generator class="assigned"></generator>
<!-- native是自動賦值主鍵 assigned是手動賦值主鍵 -->
</id>
<!-- 實體類的屬性 -->
<property name="Sname" type="java.lang.String">
<column name="Sname"></column>
</property>
<property name="Sex" type="java.lang.String">
<column name="Sex"></column>
</property>
<property name="Birth" type="java.lang.String">
<column name="Birth"></column>
</property>
<property name="classno" type="java.lang.String">
<column name="classno"></column>
</property>
<property name="Entrance_date" type="java.lang.String">
<column name="Entrance_date"></column>
</property>
<property name="Home_addr" type="java.lang.String">
<column name="Home_addr"></column>
</property>
<property name="sdept" type="java.lang.String">
<column name="sdept"></column>
</property>
<property name="postcode" type="java.lang.String">
<column name="postcode"></column>
</property>
</class>
</hibernate-mapping>
需要說明的:
1、主鍵(唯一標識符)在關係映射彙總以id標籤標示,其他屬性以property標示,而id標籤中generator標籤指定了在庫表中存儲的主鍵是自動生成還是手動賦值。其中native是自動賦值(跨數據庫),assigned是手動賦值,此外還有identity、hilo、sequence等,一共7種主鍵生成策略。
2、class name標籤和table指定實體類和表名。每個column標籤都標示了當前property映射爲庫表中的具體某一條屬性,而property的type屬性指定數據類型,一般使用包名+包裝類的表達形式。
3、如果是實體之間有一對多或多對一或的映射關係(比如學生對班級,老師對學生)則使用<one-to-many>或<many-to-one>標籤指定,而多對多關係一般拆分成一對多多對一關係。
配置寫好之後在程序中調用hibernate的方式也並不麻煩,需要導入org.hibernate.Session包。jdbc配置都寫在文件裏,所以先用Configuration對象傳入配置參數,創建session對象(需要註冊服務),開啓一個事務。
Configuration config = new Configuration().configure();
//創建服務註冊對象
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(config.getProperties())
.buildServiceRegistry();
//創建會話工廠對象
sessionFactory = config.buildSessionFactory(serviceRegistry);
//會話對象
session = sessionFactory.openSession();
//session = sessionFactory.getCurrentSession();
//getCurrentSession不創建新的連接對象,而openSession會創建一個新的連接對象。
//openSession每次提交事務後需要手動關閉session.close(),否則連接次數多了會造成連接池溢出
//getCurrentSession每次提交事務後自動關閉連接。
transaction = session.beginTransaction();//開啓事務
session對象就是與數據庫的會話通道,增刪改查操作以事務形式提交到session。session有save方法、delete方法、clear以及create等方法,均以事務形式提交(transaction.commit())。方法執行完畢爲了節省內存需要關係session以及sessionFactory。
另:當執行session的查詢時,get和load方式也是不同的需要注意的。
//get方法和load方法不同
//get方法立刻發送SQL語句,返回一個實體對象
//load方法先返回一個代理對象(保留實體對象的ID),等到需要用到非主屬性的時候才發送SQL。
//!!當對象不存在時,get返回一個null,load返回ObjectNotFoundException。!!
Student s1 = (Student) session.get(Student.class, 20110010);
Student s2 = (Student) session.load(Student.class, 20110009);
當hibernate自動裝配的SQL語句不符合生產要求的時候就還是需要使用HQL了。