1. 程式人生 > >Hibernate使用之快速開始

Hibernate使用之快速開始

在gradle中引入hibernate

相關gradle內容如下:

apply plugin: "java"

repositories {
    jcenter()
}

dependencies {
    compile "org.hibernate:hibernate-core:5.0.0.Final"
}

截止到本文時最新的hibernate是5.0.0版。

建立並編寫配置檔案”hibernate.cfg.xml”

hibernate的主配置檔案有兩種方式:”hibernate.properties”和”hibernate.cfg.xml”, 本文中我們採用第二種方式。如果對第一種方式感興趣,可以自行搜尋。

這裡我們按照gradle java外掛的預設原始碼結構規則,將”hibernate.cfg.xml”檔案放到”src/main/resources”目錄下。

配置檔案的內容如下:

<?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">
<hibernate-configuration> <session-factory> <property name="hibernate.dialect"> org.hibernate.dialect.PostgreSQLDialect </property> <property name="hibernate.connection.driver_class"> org.postgresql.Driver </property> <property
name="hibernate.hbm2ddl.auto">
update</property> <property name="hibernate.connection.url"> jdbc:postgresql://localhost:5432/zhanglong_test </property> <property name="hibernate.connection.username"> postgres </property> <property name="hibernate.connection.password"> 123456 </property> <!-- List of XML mapping files --> <mapping resource="UserAccount.hbm.xml"/> </session-factory> </hibernate-configuration>

“”標籤前面的部分基本上是固定的,不用更改,直接拷貝即可。

“hibernate.dialect”屬性代表具體的資料庫偏好,因為不同的資料庫在具體的實現上,sql語句上會有一些差別,通過這個屬性來制定具體的資料庫”方言”可以讓hibernate產生效率更高的SQL語句。

常用的一些支援的資料庫”方言”如下:

Database Dialect Property
DB2 org.hibernate.dialect.DB2Dialect
HSQLDB org.hibernate.dialect.HSQLDialect
HypersonicSQL org.hibernate.dialect.HSQLDialect
Informix org.hibernate.dialect.InformixDialect
Ingres org.hibernate.dialect.IngresDialect
Interbase org.hibernate.dialect.InterbaseDialect
Microsoft SQL Server 2000 org.hibernate.dialect.SQLServerDialect
Microsoft SQL Server 2005 org.hibernate.dialect.SQLServer2005Dialect
Microsoft SQL Server 2008 org.hibernate.dialect.SQLServer2008Dialect
MySQL org.hibernate.dialect.MySQLDialect
Oracle (any version) org.hibernate.dialect.OracleDialect
Oracle 11g org.hibernate.dialect.Oracle10gDialect
Oracle 10g org.hibernate.dialect.Oracle10gDialect
Oracle 9i org.hibernate.dialect.Oracle9iDialect
PostgreSQL org.hibernate.dialect.PostgreSQLDialect
Progress org.hibernate.dialect.ProgressDialect
SAP DB org.hibernate.dialect.SAPDBDialect
Sybase org.hibernate.dialect.SybaseDialect
Sybase Anywhere org.hibernate.dialect.SybaseAnywhereDialect

“hibernate.connection.driver_class”屬性指定資料庫驅動類名,hibernate可以通過配置的驅動型別用java的反射機制載入驅動類。

本人只使用過mysql和postgresql,所以只列出這兩個資料庫的驅動,啟動可自行搜尋,網上資料很多:

Database driver class name
MySQL com.mysql.jdbc.Driver
PostgresSQL org.postgresql.Driver

“hibernate.hbm2ddl.auto”屬性是告訴hibernate操作資料表的模式,可用的模式有:”validate”, “update”, “create”, “create-drop” 和”none”。

create:
每次載入hibernate時都會刪除上一次的生成的表,然後根據你的model類再重新來生成新表,哪怕兩次沒有任何改變也要這樣執行,這就是導致資料庫表資料丟失的一個重要原因。
create-drop :
每次載入hibernate時根據model類生成表,但是sessionFactory一關閉,表就自動刪除。
update:
最常用的屬性,第一次載入hibernate時根據model類會自動建立起表的結構(前提是先建立好資料庫),以後載入hibernate時根據 model類自動更新表結構,即使表結構改變了但表中的行仍然存在不會刪除以前的行。要注意的是當部署到伺服器後,表結構是不會被馬上建立起來的,是要等 應用第一次執行起來後才會。
validate :
每次載入hibernate時,驗證建立資料庫表結構,只會和資料庫中的表進行比較,不會建立新表,但是會插入新值。

none:自己來維護表的建立,更改與銷燬。

“hibernate.connection.url”屬性指定資料庫的連線字串,這裡列出MySql和PostgresSQL的, 注意連線字串中的域名,埠和資料庫名要替換成實際的:

DataBase connection url
MySQL jdbc:mysql://localhost:3600/zhanglong_test
PostgreSQL jdbc:postgresql://localhost:5432/zhanglong_test

“hibernate.connection.username”屬性指定資料庫的使用者名稱,用於連線資料庫時的認證。
“hibernate.connection.password”屬性指定資料庫的使用者密碼,用於連線資料庫時的認證。
“mapping”標籤指定所有對映檔案(定義domain類到關係資料庫的對映方式)的位置,每個domain類對應一個。

編寫domain類與對映檔案

本文的程式碼按照gradle java外掛的預設目錄結構將java檔案放到”src/main/java”目錄下。

在”src/main/java”目錄下建立”com.zhanglong.test.domains”包,並在新建立的包下建立”UserAccount.java”檔案。檔案的內容如下:

package com.zhanglong.test.domains;

public class UserAccount {
    private Long id;
    private String name;
    private Integer age;

    public UserAccount() {

    }

    public UserAccount(String name, int age) {
        this.name = name;
        this.age = age;
    }

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

    public Long getId() {
        return this.id;
    }

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

    public String getName() {
        return this.name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Integer getAge() {
        return this.age;
    }
}

然後在”src/main/resources”目錄下為該類建立hibernate對映檔案”UserAccount.hbm.xml”,內容如下:

<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.zhanglong.test.domains">

    <class name="UserAccount" table="user_account">
        <id name="id" column="id">
            <generator class="increment"/>
        </id>
        <property name="name" type="string" column="name"/>
        <property name="age" type="int" column="int"/>
    </class>

</hibernate-mapping>

編寫業務程式碼並操作資料庫

為了保證能順利操作資料,我們還需要引入驅動包,在build.gradle檔案中的”dependencies”模組中新增如下一行:

compile "org.postgresql:postgresql:9.4-1201-jdbc41"

此時整個build.gradle內容如下:

apply plugin: "java"

repositories {
    jcenter()
}

dependencies {
    compile "org.hibernate:hibernate-core:5.0.0.Final"
    compile "org.postgresql:postgresql:9.4-1201-jdbc41"
}

在”com.zhanglong.test”包下建立”TestNativeApiHbmMapping.java”檔案,檔案內容如下:

package com.zhanglong.test;

import com.zhanglong.test.domains.UserAccount;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class TestNativeApiHbmMapping {
    private static SessionFactory factory;

    public static void main(String[] args) {
        try{
           factory = new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
           System.err.println("Failed to create sessionFactory object." + ex);
           throw new ExceptionInInitializerError(ex); 
        }
        System.out.println("factory: " + factory);
        Session session = factory.openSession();
        session.beginTransaction();
        UserAccount me = new UserAccount("zhanglong", 26);
        long meId = (Long) session.save(me); 
        System.out.println("meId: " + meId);
        session.getTransaction().commit();
        session.close();
    }
}

build和執行

為了更方便的管理執行的包得依賴,我們使用gradle的fatJar外掛將所有被依賴的包大包到一塊。“build.gradle”問價中新增如下幾行:

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'eu.appsatori:gradle-fatjar-plugin:0.3'
    }
}

apply plugin: 'eu.appsatori.fatjar'

此時完整的build.gradle檔案內容如下:

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'eu.appsatori:gradle-fatjar-plugin:0.3'
    }
}

apply plugin: 'eu.appsatori.fatjar'

apply plugin: "java"

repositories {
    jcenter()
}

dependencies {
    compile "org.hibernate:hibernate-core:5.0.0.Final"
    compile "org.postgresql:postgresql:9.4-1201-jdbc41"
}

在終端執行如下命令進行打包:

~$ gradle fatJar

命令執行成功後,將會生成一個build目錄,最終的jar包就在“build/libs”目錄下。

在終端執行如下命令執行jar包:

~$ java -cp build/libs/TestNativeApiHbmMapping.jar com.zhanglong.test.TestNativeApiHbmMapping

輸出的結果如下:

九月 09, 2015 9:50:56 上午 org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.0.0.Final}
九月 09, 2015 9:50:56 上午 org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
九月 09, 2015 9:50:56 上午 org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
九月 09, 2015 9:50:56 上午 org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.0.0.Final}
九月 09, 2015 9:50:57 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)
九月 09, 2015 9:50:57 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [org.postgresql.Driver] at URL [jdbc:postgresql://localhost:5432/zhanglong_test]
九月 09, 2015 9:50:57 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=postgres, password=****}
九月 09, 2015 9:50:57 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
九月 09, 2015 9:50:57 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
九月 09, 2015 9:50:57 上午 org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
九月 09, 2015 9:50:57 上午 org.hibernate.engine.jdbc.env.internal.LobCreatorBuilderImpl useContextualLobCreation
INFO: HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
九月 09, 2015 9:50:57 上午 org.hibernate.type.BasicTypeRegistry register
INFO: HHH000270: Type registration [java.util.UUID] overrides previous : org.hibernate.type.UUIDBinaryType@55cf0d14
九月 09, 2015 9:50:57 上午 org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000228: Running hbm2ddl schema update
九月 09, 2015 9:50:57 上午 org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl processGetTableResults
INFO: HHH000262: Table not found: user_account
九月 09, 2015 9:50:57 上午 org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl processGetTableResults
INFO: HHH000262: Table not found: user_account
factory: org.hibernate.internal.SessionFactoryImpl@5b58ed3c
meId: 3

結果中最後兩行是我們列印的執行成功的結果,前面是hibernate的log。