一些在Hibernate學習中應該注意的問題
一. 包的引入
注意Hibernate包的引入(包的引入是學習每個開發框架都必須注意的問題),在不能確定用到哪個包時(特別是對於新手),建議把Hibernate/lib裏面的包和hibernate2.jar全部引入.還有用於連接數據庫的包(這個隨情況而定。我用mysql的mysql-connector-java-3.0.14-production-bin.jar)。
二. 配置文件hibernate.cfg.xml的書寫
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">
<!-- DO NOT EDIT: This is a generated file that is synchronized -->
<!-- by MyEclipse Hibernate tool integration. -->
<hibernate-configuration>
<session-factory>
<!-- properties -->
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.url">
jdbc:mysql://192.168.151.72:3306/quickstart
</property>
<property name="dialect">
net.sf.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.password"></property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- mapping files -->
<!-- The following mapping element was auto-generated in -->
<!-- order for this file to conform to the Hibernate DTD -->
<mapping resource="Customer.hbm.xml" />
</session-factory>
</hibernate-configuration>
配置文件中的前半部分是用來配置數據庫連接池的(建議新手是用Hibernate自帶的連接池配置—比較簡單。高手可以是用別的連接池-如tomcat,struts,或jboss的)
最後一句“<mapping resource="Customer.hbm.xml" />”則是用來指明表的配置文件的,形式如下:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="com.ln.hb.Customer" table="CUSTOMER">
<id name="id" column="CID">
<generator class="identity" />
</id>
<property name="username" column="USERNAME" />
<property name="password" column="PASSWORD" />
</class>
</hibernate-mapping>
在這個配置文件中,class標籤是用來建立一個表到類的映射,如上例則是說明在com.ln.hb包下的Customer類與數據庫裏的CUSTOMER表建立了映射關係。Class標籤的子標籤:
1.Id是用來指明主鍵的,<generator class=" " />這是用來指明主鍵的生成機制,有如下可選項:
可選項說明:
1) Assigned
主鍵由外部程序負責生成,無需Hibernate參與。
2)
通過hi/lo 算法實現的主鍵生成機制,需要額外的數據庫表保存主
鍵生成歷史狀態。
3) seqhilo
與hilo 類似,通過hi/lo 算法實現的主鍵生成機制,只是主鍵歷史
狀態保存在Sequence中,適用於支持Sequence的數據庫,如Oracle。
4) increment
主鍵按數值順序遞增。此方式的實現機制爲在當前應用實例中維持
一個變量,以保存着當前的最大值,之後每次需要生成主鍵的時候
將此值加1作爲主鍵。
這種方式可能產生的問題是:如果當前有多個實例訪問同一個數據
庫,那麼由於各個實例各自維護主鍵狀態,不同實例可能生成同樣
的主鍵,從而造成主鍵重復異常。因此,如果同一數據庫有多個實
例訪問,此方式必須避免使用。
5) identity
採用數據庫提供的主鍵生成機制。如DB2、SQL Server、MySQL
中的主鍵生成機制。
6) sequence
採用數據庫提供的sequence 機制生成主鍵。如Oralce 中的
Sequence。
7) native
由Hibernate根據底層數據庫自行判斷採用identity、hilo、sequence
其中一種作爲主鍵生成方式。
8) uuid.hex
由Hibernate基於128 位唯一值產生算法生成16 進制數值(編碼後
以長度32 的字符串表示)作爲主鍵。
9) uuid.string
與uuid.hex類似,只是生成的主鍵未進行編碼(長度16)。在某些
數據庫中可能出現問題(如PostgreSQL)。
10) foreign
使用外部表的字段作爲主鍵。
一般而言,利用uuid.hex 方式生成主鍵將提供最好的性能和數據庫平臺適
應性。
另外由於常用的數據庫,如Oracle、DB2、SQLServer、MySql 等,都提
供了易用的主鍵生成機制(Auto-Increase 字段或者Sequence)。我們可以在數
據庫提供的主鍵生成機制上,採用generator-class=native的主鍵生成方式。
不過值得注意的是,一些數據庫提供的主鍵生成機制在效率上未必最佳,
大量並發insert數據時可能會引起表之間的互鎖。
數據庫提供的主鍵生成機制,往往是通過在一個內部表中保存當前主鍵狀
態(如對於自增型主鍵而言,此內部表中就維護着當前的最大值和遞增量),
之後每次插入數據會讀取這個最大值,然後加上遞增量作爲新記錄的主鍵,之
後再把這個新的最大值更新回內部表中,這樣,一次Insert操作可能導致數據
庫內部多次表讀寫操作,同時伴隨的還有數據的加鎖解鎖操作,這對性能產生
了較大影響。
因此,對於並發Insert要求較高的系統,推薦採用uuid.hex 作爲主鍵生成
機制。
2.“<property name="username" column="USERNAME" />”這是對其他的屬性建立映射。
三. 持久化類的書寫
與一般的formbean類書寫形式一樣,定義屬性,及其getter和setter方法。(注意屬性名字與配置文件的屬性項name定義的名字要一致)如下例:
package com.ln.hb;
import java.io.Serializable;
public class Customer implements Serializable {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public String getPassword() {
return password;
}
public String getUsername() {
return username;
}
public void setId(int id) {
this.id = id;
}
public void setPassword(String password) {
this.password = password;
}
public void setUsername(String username) {
this.username = username;
}
}
四. 測試類的書寫(Hibernate的調用)
package com.ln.test;
import java.util.Iterator;
import com.ln.hb.Customer;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.Transaction;
import net.sf.hibernate.cfg.Configuration;
public class Test {
public static void main(String[] args) {
try {
SessionFactory sf = new Configuration().configure()
.buildSessionFactory();
//上面的寫法是讀默認的hibernate.cfg.xml
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
Customer customer = new Customer();
System.out.println("Let's go!");
// customer.setUsername("liang");
// customer.setPassword("hello");
// session.save(customer);
// session.flush();
Query query = session.createQuery("select customer from Customer as customer");
for (Iterator it = query.iterate(); it.hasNext();) {
Customer cust = (Customer) it.next();
System.out.print("********"+"UserName: " + cust.getUsername()+"********");
System.out.println("PassWord: " + cust.getPassword()+"********");
}
tx.commit();
session.close();
} catch (HibernateException e) {
e.printStackTrace();
}
}
}
五.數據庫表的設計中要注意的事項。
1.由於在Hibernate初級階段要儘量避免對主鍵值進行手動設置、修改。所以建議把主鍵設置成auto_increment(就是能自動加一的形式)且不能爲空的格式。
2.在下面附上使用tomcat連接池的例子:
上面配置的東西只用對hibernate.cfg.xml進行一些修改。修改後的hibernate.cfg.xml如下:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">
<!-- DO NOT EDIT: This is a generated file that is synchronized -->
<!-- by MyEclipse Hibernate tool integration. -->
<hibernate-configuration>
<session-factory>
<!-- properties -->
<!-- <property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.url">
jdbc:mysql://localhost:3306/quickstart
</property>-->
<property name="connection.datasource">java:comp/env/jdbc/mysql</property>
這裏就是用來連接tomcat(或其他)連接池的地方,property的內容是你所配置的連接池的jndi名稱。
<property name="dialect">
net.sf.hibernate.dialect.MySQLDialect
</property>
<!--<property name="hibernate.connection.password"></property>-->
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- mapping files -->
<!-- The following mapping element was auto-generated in -->
<!-- order for this file to conform to the Hibernate DTD -->
<mapping resource="com/ln/hb/Customer.hbm.xml" />
</session-factory>
</hibernate-configuration>
而tomcat的連接池配置如下(在指向你的工程的yourProject.xml裏面進行配置):
<?xml version='1.0' encoding='utf-8'?>
<Context
path="/hb2" docBase="eclipse /workspace/Hbstruts" reloadable="true">
<Resource type="javax.sql.DataSource" name="jdbc/mysql"/>
<ResourceParams name="jdbc/mysql">
<parameter>
<name>maxWait</name>
<value>5000</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>4</value>
</parameter>
<parameter>
<name>password</name>
<value></value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:mysql://localhost:3306/quickstart</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>com.mysql.jdbc.Driver</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>2</value>
</parameter>
<parameter>
<name>username</name>
<value>root</value>
</parameter>
</ResourceParams>
</Context>