Hibernate 框架

Hibernate是一個開放源代碼]的對象關系映射框架,它對JDBC進行了非常輕量級的對象封裝,它將POJO與數(shù)據庫表建立映射關系,是一個全自動的orm框架,hibernate可以自動生成SQL語句,自動執(zhí)行,使得Java程序員可以隨心所欲的使用對象編程思維來操縱數(shù)據庫。

Hibernate可以應用在任何使用JDBC的場合,既可以在Java的客戶端程序使用,也可以在Servlet/JSP的Web應用中使用,最具革命意義的是,Hibernate可以在應用EJB的JavaEE架構中取代CMP,完成數(shù)據持久化的重任。

Hibernate 中只需要通過“方言”的形式指定當前使用的數(shù)據庫,就可以根據底層數(shù)據庫的實際情況生成適合的 SQL 語句。因此在使用 Hibernate 連接數(shù)據庫時,我們主要關注的配置就是數(shù)據庫方言這個參數(shù)。

Hibernate 使用 HGDB,只需要將“方言”這個配置參數(shù),改為 HGDB 方言即可。

開發(fā)環(huán)境搭建

軟件 版本
HGDB 安全版V4、企業(yè)版v5及以上版本
JDK 1.6、1.7、1.8
Java IDE Eclipse、IntelliJ IDEA

HGDB 針對 Hibernate 框架,封裝了 HGDB 方言包,現(xiàn)有的 Hibernate HGDB方言包支持的 Hibernate 版本,如下圖所示:

image-20220418151105678

Hibernate HGDB 方言包的說明,如下:

使用說明
HGDB 方言包是用于使用 Hibernate 開發(fā)提供支持的,該方言包使用依賴hibernate-core,因此需要應用程序中已經添加了相關的依賴包后才能使用。HGDB 方言包使用配置:org.hibernate.dialect.HgdbDialect

版本說明
HGDB 方言包使用依賴 hibernate-core,所以方言包的版本需要與hibernate-core 的版本對應,對應規(guī)則為:HGDB 方言包 jar 包名字末尾的編號即是對應的 hibernate-core 的版本號。

例:hgdb-hibernate-dialect-5.4.0.jar,需要對應使用 hibernate-core 的 5.4.0 版本。

編譯環(huán)境說明

HGDB 的所有方言包均使用 jdk1.6 進行編譯,所以需要在 jdk1.6 或以上的環(huán)境中使用。如果使用的 hibernate 版本在 HGDB 方言包的版本中不存在,請修改一下項目的 hibernate 版本,只要 hibernate 的大版本號一致,基本就沒有問題。

Hibernate引入 HGDB 方言包

以maven 倉庫方式為例:

mvn install:install-file -Dfile=C:\***\hgdb-hibernate-dialect-4.3.11.jar -DgroupId=highgo -DartifactId=hgdb-hibernate-dialect -Dversion=4.3.11 -Dpackaging=jar

## C:\***\hgdb-hibernate-dialect-4.3.11.jar 為本地絕對路徑

執(zhí)行結果,如下:

image-20220418152525445

示例項目

結構圖如下:

image-20220516191541275

主要文件介紹

pom.xml:添加依賴(僅為片段部分)

<!-- hibernate配置-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.11.Final</version>
</dependency>
<!-- HGDB的方言包-->
<dependency>
<groupId>highgo</groupId>
<artifactId>hgdb-hibernate-dialect</artifactId>
<version>4.3.11</version>
</dependency>
<!-- HGDB jdbc-->
<dependency>
<groupId>highgo</groupId>
<artifactId>highgo</artifactId>
<version>5.0-42</version>
</dependency>

hibernate.cfg.xml:Hibernate的核心配置文件,主要用來描述Hibernate的相關配置

<hibernate-configuration>
<!--構造數(shù)據庫的連接工廠-->
<session-factory>
<!-- 配置關于數(shù)據庫連接信息 driverClass url username password僅為參考 -->
<property name="hibernate.connection.driver_class"><>com.highgo.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:highgo://localhost:5866/hibernateTest</property>
<property name="hibernate.connection.username">test</property>
<property name="hibernate.connection.password">test</property>
<!-- 可以將向數(shù)據庫發(fā)送的sql顯示出來 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化sql -->
<property name="hibernate.format_sql">true</property>
<!-- hibernate的方言,修改為 HGDB的方言包 -->
<property name="hibernate.dialect">org.hibernate.dialect.HgdbDialect</property>
<!-- 配置hibernate的映射文件所在位置 -->
<mapping resource="com/highgo/entitty/User.hbm.xml" />
</session-factory>
</hibernate-configuration>

User.hbm.xml:映射文件

<?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
package="com.highgo.entity">

<class name="User" >
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="birthday"/>

</class>

</hibernate-mapping>

User.java:實體bean

public class User {
private int id;
private String name;
private Date birthday;

public int getId() {
return id;
}

public String getName() {
return name;
}

public Date getBirthday() {
return birthday;
}

public void setId(int id) {
this.id = id;
}

public void setName(String name) {
this.name = name;
}

public void setBirthday(Date birthday) {
this.birthday = birthday;
}

@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", birthday=" + birthday
+ "]";
}
}

MainTest.java:測試類

public class MainTest {
public static void main(String[] args) {
try {
Configuration conf=new Configuration();
SessionFactory sessionFactory= conf.configure().buildSessionFactory();
Session session=sessionFactory.openSession();
Transaction tx=session.beginTransaction();
User user=new User() ;
user.setName("張三");
user.setBirthday(new Date());
session.save(user);
tx.commit();
session.close();
//獲取數(shù)據集合
Transaction tx1=session.beginTransaction();
Criteria criteria =session.createCriteria(User.class);
List<User> list = criteria.list();
//使用forEach遍歷集合
for (User userEntity : list) {
System.out.println(userEntity);
}
tx1.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
}

執(zhí)行結果:

image-20220418172933992

image-20220418173905608

注意事項

Hibernate主鍵生成策略

Hibernate要求實體類里面有一個屬性作為唯一值,對應表主鍵,提供了多種主鍵的生成方式,具體有哪些以下做簡單介紹。

一、在映射配置文件中指定主鍵生成策略

<class name="User"  table="test_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="birthday"/>
</class>

二、常見的主鍵生成策略

策略名稱 說明
Assigned Assigned方式由用戶生成主鍵值,并且要在save()之前指定否則會拋出異常。
特點:主鍵的生成值完全由用戶決定,與底層數(shù)據庫無關。用戶需要維護主鍵值,在調用session.save()之前要指定主鍵值。
Hilo Hilo使用高低位算法生成主鍵,高低位算法使用一個高位值和一個低位值,然后把算法得到的兩個值拼接起來作為數(shù)據庫中的唯一主鍵。Hilo方式需要額外的數(shù)據庫表和字段提供高位值來源。默認情況下使用的表是hibernate_unique_key,默認字段叫作next_hi。next_hi必須有一條記錄否則會出現(xiàn)錯誤。
特點:需要額外的數(shù)據庫表的支持,能保證同一個數(shù)據庫中主鍵的唯一性,但不能保證多個數(shù)據庫之間主鍵的唯一性。Hilo主鍵生成方式由Hibernate 維護,所以Hilo方式與底層數(shù)據庫無關,但不應該手動修改hi/lo算法使用的表的值,否則會引起主鍵重復的異常。
Increment Increment方式對主鍵值采取自動增長的方式生成新的主鍵值,但要求底層數(shù)據庫的主鍵類型為long,int等數(shù)值型。主鍵按數(shù)值順序遞增,增量為1。
特點:由Hibernate本身維護,適用于所有的數(shù)據庫,不適合多進程并發(fā)更新數(shù)據庫,適合單一進程訪問數(shù)據庫。不能用于群集環(huán)境。
Identity Identity方式根據底層數(shù)據庫,來支持自動增長,不同的數(shù)據庫用不同的主鍵增長方式。
特點:與底層數(shù)據庫有關,要求數(shù)據庫支持Identity,如MySQl中是auto_increment, SQL Server 中是Identity,支持的數(shù)據庫有MySql、SQL Server、DB2、Sybase和HypersonicSQL。 Identity無需Hibernate和用戶的干涉,使用較為方便,但不便于在不同的數(shù)據庫之間移植程序。
Sequence Sequence需要底層數(shù)據庫支持Sequence方式,例如Oracle數(shù)據庫等
特點:需要底層數(shù)據庫的支持序列,支持序列的數(shù)據庫有DB2、PostgreSql、Oracle、SAPDb等在不同數(shù)據庫之間移植程序,特別從支持序列的數(shù)據庫移植到不支持序列的數(shù)據庫需要修改配置文件。
Native Native主鍵生成方式會根據不同的底層數(shù)據庫自動選擇Identity、Sequence、Hilo主鍵生成方式
特點:根據不同的底層數(shù)據庫采用不同的主鍵生成方式。由于Hibernate會根據底層數(shù)據庫采用不同的映射方式,因此便于程序移植,項目中如果用到多個數(shù)據庫時,可以使用這種方式。
UUID UUID使用128位UUID算法生成主鍵,能夠保證網絡環(huán)境下的主鍵唯一性,也就能夠保證在不同數(shù)據庫及不同服務器下主鍵的唯一性。
特點:能夠保證數(shù)據庫中的主鍵唯一性,生成的主鍵占用比較多的存貯空間

三、常見問題

遇到的問題:項目有mysql遷移到HGD環(huán)境時,提示ERROR: relation "HIBERNATE_SEQUENCE" does not exist

經查證,Hibernate中的實體類使用native方式生成主鍵時,native是由Hibernate根據使用的數(shù)據庫自行判斷采用identity、hilo、sequence其中一種作為主鍵生成方式。而HGDB數(shù)據庫沒有類似的自增類型,因此需要手動創(chuàng)建一個名稱為hibernate_sequence的序列做支持。

create sequence HIBERNATE_SEQUENCE
minvalue 1
maxvalue 9999999999999999
start with 1
increment by 1
cache 20;