## 【與ORM】
**Object Relational Mapping**,對象關系映射,將對象和關系聯系了起來。面向對象是從耦合、聚合、封裝等的基礎上發展起來的,而關系數據庫則是從數學理論發展而來的,兩套理論存在顯著的區別。為了解決這個不匹配的現象,對象關系映射技術應運而生,這樣開發人員就可以以面向對象的思想來操作數據庫。
實現ORM技術的框架有很多,.net的有NHibernate、EF、iBATIS.NET等,java的有mybatis、ibatis,當然還有Hibernate。
言歸正傳,我們這里介紹Hibernate,他是一個實現了ORM技術的框架。Hibernate對jdbc進行了封裝,這使得我們操作數據庫變得更加簡單。本篇博客主要介紹Hibernate自動建表的功能。
## 【Demo】
我們以一個簡單的例子來看,Hibernate是如何自動建表的。其中涉及到User類,以及他對應的映射文件User.hbm.xml,Hibernate的數據庫配置文件hibernate.cfg.xml,后面我們會詳細介紹各自的作用。
首先從實體開始,我們先來構造User類。
描述數據庫表的結構,表中的字段對應類中的屬性,數據庫中的表對應一個類。
這里的User是一個java類,也可以叫作**POJO對象**。即Plain Ordinary Java Object,簡單的Java對象,只有一些屬性及其getter setter方法的類,沒有業務邏輯。POJO對象可以方便程序員操作數據庫中的表,進行get和set操作。
~~~
package com.hibernate;
import java.util.Date;
/**
* 用戶類
* @author YANG
*
*/
public class User {
//用戶id
private String id;
//用戶名稱
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
~~~
Uer類對應的映射文件User.hbm.xml,該配置文件中依據User實體類來建立的。具體建立時,可以一個實體一個映射文件,也可以多個實體配在一個映射文件中。
它指定數據庫表(比如t_User)和映射類(User.java)之間的關系,包括映射類和數據庫表的對應關系、表字段和類屬性類型的對應關系以及表字段和類屬性名稱的對應關系等。
~~~
<?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 >
<!-- 數據庫默認表的名稱和類名相同,
如果需要改變或類名為關鍵字時,
可以添加table="t_user"給表重命名 -->
<class name="com.hibernate.User" ><!-- table="t_user" -->
<!-- 映射主鍵 -->
<id name="id">
<!-- 主鍵生成策略,利用生成器 -->
<generator class="uuid"></generator>
</id>
<!-- 利用property映射其他字段 -->
<property name="name" ></property><!-- 若加上column="user_name",數據庫字段名為user_name -->
</class>
</hibernate-mapping>
~~~
現在實體類和對應的映射文件已經都準備好了,還差數據庫的連接了。配置內容包括數據庫的驅動類,連接數據庫的url,用戶名和密碼等等。這里用的是mysql數據庫,需要注意的是,我們一定要把實體類的映射文件加入,不然無法獲取。
~~~
<!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="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 連接的url,數據庫名稱為hibernate_first -->
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_first</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"></property>
<!-- 適配器,方言,用于翻譯成mysql的語句 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 設置打印到控制臺 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化sql -->
<property name="hibernate.format_sql">true</property>
<!-- 映射文件加入 -->
<mapping resource="com/hibernate/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
~~~
之后我們建立一個測試類,來測試是否能夠生成表。不過在執行該類之前,需要手動在數據庫中建立相應的數據庫,數據庫的名稱需要和配置文件保持一致。因為Hibernate只會自動建表,不會自動建庫。
~~~
public static void main(String[] args){
//讀取的是properties文件
//Configuration cfg=new Configuration();
Configuration cfg=new Configuration().configure();
//工具類
SchemaExport export=new SchemaExport(cfg);
//打到控制臺,輸出到數據庫
export.create(true, true);
}
~~~
這個方法主要功能是將hbm生成ddl語句,進行建表。DDL是用來操作數據庫、表、視圖等,所以最終需要轉換成ddl語句來完成建表。這樣也比較麻煩,每次建表都要單獨執行該類。還有一種方法,修改配置文件。每次加載hibernate時都會刪除上一次的生成的表,然后根據你的model類再重新來生成新表。但這個參數并不建議使用,正是因為每次加載都會重新生成表,會使得表中的數據丟失。
~~~
<properties>
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
~~~
執行之后,控制臺輸入內容如下,去數據庫里看一下,表就建好了。
~~~
drop table if exists User
create table User (
id varchar(255) not null,
name varchar(255),
primary key (id)
)
~~~
## 【小結】
之前就接觸過自動建表這部分,但當時就只是照著做,沒有去看是如何實現的,覺得好神奇啊。不過邊用邊總結一下,就會有恍然大悟的感覺,其實也就是這個樣子啦。其實也是人家Hibernate-tool里面的工具類封裝的好,像SchemaExport,如果沒有這個東西,自動建表也是很麻煩的啊。不管是哪個巨人吧,還是先站在巨人的肩膀上了,然后再努力成為一個巨人!