自動創建數據庫表
如果需要Hibernate根據映射關係自動創建數據庫,則需要配置hibernate.cfg.xml文件
<property name="hbm2ddl.auto">create</property>
這裏有四個配置,分別是:create、update、create-drop和validate
create
:當我們的應用程序加載hibernate.cfg.xml(比如new Configuration().configure()
)時,就會根據映射文件,創建出數據庫,每次都會刪掉已經存在的數據庫重新創建;update
:如果數據庫中沒有該表,則創建表,如果有表,則看錶有沒有變化,如果有變化,則更新(比如增加一列);create-drop
:在顯示關閉sessionFactory時,將drop掉數據庫的schemavalidate
:相當於每次插入數據之前都會驗證數據庫中的表結構和hbm文件的結果是否一致
下面我們對update
屬性做簡單的測試,首先我們創建一個數據庫test
。
可以看到,當前數據庫中沒有任何數據表。
接着,我們創建項目HibernateHbmToDDL
,手動創建一個domain對象Student
,如下:
package com.gavin.domain;
public class Student {
private Integer id;
private String name;
private String sex;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
並且手動配置其對象關係映射文件Student.hbm.xml
,如下:
<?xml version='1.0' encoding='utf-8'?>
<!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="com.gavin.domain.Student" table="student" schema="test">
<id name="id" column="id" type="java.lang.Integer"/>
<property name="name" column="name" type="java.lang.String" length="64"/>
<property name="sex" column="sex" type="java.lang.String" length="8"/>
</class>
</hibernate-mapping>
接着,我們對Hibernate進行配置。hibernate.cfg.xml文件如下:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password">gavin</property>
<!-- DB schema will be updated if needed -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="com/gavin/domain/Student.hbm.xml"/>
</session-factory>
</hibernate-configuration>
可以看到,在這裏我們配置了<property name="hbm2ddl.auto">update</property>
,所以如果數據庫沒有表的時候,Hibernate會自動幫我們建表。
下面寫一個主方法保存一個Student對象:
import com.gavin.domain.Student;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;
public class Main {
public static void main(final String[] args) throws Exception {
Session session = new Configuration().configure().buildSessionFactory().openSession();
Transaction transaction = session.beginTransaction();
Student student = new Student();
student.setId(1);
student.setName("Gavin");
student.setSex("M");
session.save(student);
transaction.commit();
session.close();
}
}
運行之後,我們可以再看數據庫:
發現已經數據庫已經創建好了student
表,而且存入了剛剛程序中的數據。此時我們可以查看student
表的表結構:
可以看到name
字段是varchar(64)
類型,也就是長度爲64,sex
長度爲8,這就是之前我們在對象映射文件Student.hbm.xml
文件中配置的length
屬性起的作用。
對象的狀態
瞬時(transient)
數據庫中沒有數據與之對應,超過作用域會被JVM垃圾回收期回收,一般是new出來且與session沒有關聯的對象。
持久(persistent)
數據庫中有數據與之對應,當前與session有關聯,並且相關聯的session沒有關閉,事務沒有提交;持久對象狀態發生改變,在事務提交時會影響到數據庫(Hibernate能檢測到)
脫管/遊離(detached)
數據庫中有數據與之對應,但當前沒有session與之關聯;託管對象狀態發生改變,Hibernate不能檢測到。
三種狀態的轉換圖如下:
示例代碼如下:
// 對象的三種狀態
// 剛剛創建的時候,course就是瞬時態
Course course = new Course();
course.setCcredit(3);
course.setCname("PHP");
SessionFactory sessionFactory = HibernateSessionFactory.getSessionFactory();
Session session = null;
Transaction transaction = null;
try {
session = sessionFactory.openSession();
transaction = session.beginTransaction();
session.save(course);
// 此時course既處於Session的管理之下(因爲Session還沒有關閉)
// 同時course被保存在了數據庫中,故其處於持久態
System.out.println("course.getCname() = " + course.getCname());
transaction.commit();
session.close();
// 這是course被保存到數據庫中,同時沒有處於session的管理之下
// 故此時course處於遊離態
System.out.println("course.getCname() = " + course.getCname());
} catch (Exception e) {
}