跳转至

Hibernate框架支持

Hibernate框架支持

本文档描述了 SeaboxSQL 数据库对于Hibernate框架的支持情况和配置说明,面向所有使用SeaboxSQL数据库的用户,主要是数据库管理员和应用程序开发人员。

有关 Hibernate 的更多信息,请参阅以下资源:

Documentation - 5.6 - Hibernate ORM

  • 注意:

$SD_HOME:SeaboxSQL数据库的安装路径。

Hibernate 简介

Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,它将 POJO 与 数据库表建立映射关系,是一个全自动的 ORM 框架,Hibernate 可以自动生成 SQL 语句,自动执行,使得 Java 程序员可以熟练地使用对象编程思维来操纵数据库。

Hibernate 驱动包和方言包

SeaboxSQL 提供了 Hibernate 的方言包dialect-1.0.0.jar来支持Hibernate,使用时将 dialect-1.0.0.jar 导 入到项目的 Libraries 中并定义相关配置项即可。

Hibernate开发流程

hibernate 首先通过配置文件cfg.xml初始化数据库,创建SessionFactory,进而得到session也就是一个数据库 连接。cfg 文件中包括数据库驱动、URL、数据库名称以及密码等等参数,最重要的是将表或者视图的 hbm 文件写入cfg 文件,否则是无法使用 Hibernate 服务的。当用户操作数据库表或视图的时候,hibernate 加载此表的 hibernate mapping 文件,也就是hbm.xml 文件。hbm 文件主要是映射数据库表与持久化类 POJO。通过 hbm 文件可以将实体对象与数据库表或者视图对应,从而间接的操作数据库表或者视图。

使用原理图

Hibernate 环境配置

本部分描述如何配置 Hibernate 的开发环境,包括工程搭建、配置文件、配置方法和参数。

• Hibernate 工程搭建

• Hibernate 的配置文件说明

• 服务的配置方法和参数说明

Hibernate 工程搭建

要使用 Hibernate 进行开发,需要先搭建环境。以下两种方法均可完成搭建环境:

• 创建好项目之后,在/lib 目录下导入 hibernate 的核心 jar 包以及 dialect-1.0.0.jar 方言包。

• 使用 Maven 工具来管理 jar 包,修改 pom.xml 配置来导入 hibernate 核心 jar 包以及 dialect-1.0.0.jar方言包

Hibernate 的配置文件说明

在 hibernate.properties 中增加方言声明:

hibernate.dialect com.seabox.hibernate.SeaboxSQLDialect

定义 hibernate 配置文件,根据用户选择更改以下配置文件。

vim hibernate.cfg.xml,根据环境修改文件内容:

 <property name="dialect">
     com.seabox.hibernate.SeaboxSQLDialect
 </property>
服务的配置方法和参数说明

Hibernate 配置文件示例

配置时按照实际使用情况修改”dialect” 、”connection.driver_class” 等参数。

说明:jdbc:seaboxsql://ip1:7300,ip2:7301/库名?targetServerType=any&loadBalanceHosts=true为SeaboxSQL连接高可用写法,该用户为sql任务轮询访问数据库不同的管理接口达到任务数量上的负载均衡。支持其中一个ip失效后只访问另一个ip,达到高可用的目的。

<?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>
        <!-- Database connection settings -->
        <property name="connection.driver_class">
            com.seaboxsql.Driver
        </property>
        <property name="connection.url">
            jdbc:seaboxsql://192.168.2.168:7300/seaboxsql
        </property>
        <property name="connection.username">mppadmin</property>
        <property name="connection.password">mppadmin</property>
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">
            com.seabox.hibernate.SeaboxSQLDialect
        </property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>
        <!-- Disable the second-level cache  
        <property name="cache.provider_class">
            org.hibernate.cache.internal.NoCacheProvider
        </property>-->
        
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
        
        <!-- 配置文件方式 -->
        <mapping resource="User.hbm.xml" />        
        <!-- 注解方式 -->
        <!-- <mapping class="com.seabox.User"></mapping> -->
    </session-factory>

</hibernate-configuration>

hibernate 程序示例

Hibernate 映射文件示例

下例内容为 Hibernate 的映射文件配置(xxx.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 package="com.seabox">
    <class name="com.seabox.User" table="users" schema="public">
        <!--主键-->
         <id name="userId" column="userid" type="java.lang.Integer">
            <generator class="increment"/> 
         </id> 
         
        <!--非主键-->
        <!-- <property name="userId" column="userId" type="java.lang.Integer"/> -->
        <property name="userName" column="userName" type="java.lang.String"/>
        <property name="passWord" column="passWord" type="java.lang.String"/>
    </class>
</hibernate-mapping>
Hibernate 的 java 对象示例
package com.seabox;

import javax.persistence.*;
import org.hibernate.annotations.GenericGenerator;

@Entity
@Table(name="public.users")
public class User {
    public Integer userId;
    public String userName;
    public String passWord;

    public User() {
        this.userId = -1;
        this.userName = "";
        this.passWord = "";
    }

    public User(Integer id, String name, String passwd) {
        this.userId = id;
        this.userName = name;
        this.passWord = passwd;
    }

    @Id
    @GeneratedValue(generator="increment")
    @GenericGenerator(name="increment", strategy = "increment")
    @Column(name = "userid")
    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    @Column(name = "username")
    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    @Column(name = "password")
    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    public String toString() {
        return this.userId + ", " + this.userName + ", " + this.passWord;
    }

}
Hibernate 的 java 使用示例

下例为 Hibernate 的 Java 使用示例:

public class App 
{
    public static void main( String[] args )
    {
	    // A SessionFactory is set up once for an application!
	    final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
		    	.configure() // configures settings from hibernate.cfg.xml
		    	.build();
        SessionFactory sessionFactory = null; 
	    try {
		    sessionFactory = new MetadataSources( registry ).buildMetadata().buildSessionFactory();
	    }
	    catch (Exception e) {
            e.printStackTrace();
            return;
        }

        Session session = sessionFactory.openSession();
        session.beginTransaction();


        
        //查询
        System.out.println("select users:");
        List result = session.createQuery( "from com.seabox.User" ).list();
        for ( User tmpuser : (List<User>) result ) {
            System.out.println(tmpuser);
        }

        //insert
        System.out.println("insert users 3条数据");
        session.save(new User(1, "zhangshan", "111"));
        session.save(new User(2, "lishi", "222"));
        session.save(new User(3, "wangwu", "333"));
        
        //打印结果
        System.out.println("select users:");
        List result1 = session.createQuery( "from com.seabox.User" ).list();
        for ( User tmpuser : (List<User>) result1 ) {
            System.out.println(tmpuser);
        }

        //update
        System.out.println("update users set setUserName = 'lisi' where userid = 2:");
        User user=session.get(User.class, 2);
        user.setUserName("lisi");
        
        //打印结果
        System.out.println("select users:");
        List result2 = session.createQuery( "from com.seabox.User" ).list();
        for ( User tmpuser : (List<User>) result2 ) {
            System.out.println(tmpuser);
        }

        //delete
        System.out.println("delete users where userid = 3");
        User user1 = session.get(User.class, 3);
        session.delete(user1);
        
        //打印结果
        System.out.println("select users:");
        List result3 = session.createQuery( "from com.seabox.User" ).list();
        for ( User tmpuser : (List<User>) result3 ) {
            System.out.println(tmpuser);
        }

        //分页    
        System.out.println("分页查询offset 1 limit 1:");
        Query query = session.createQuery("from com.seabox.User");
        query.setFirstResult(1);
        query.setMaxResults(1);
        for ( User tmpuser : (List<User>) query.list() ) {
            System.out.println(tmpuser);
        }
        session.getTransaction().commit();
        session.close();
    }
}

hibernate 注意点

  1. HQL(JPA QL)不支持 SeaboxSQL特有的函数,包括:TO_HEX、SETSEED、STRPOS、GET_BIT、GET_BYTE、SET_BIT、SET_BYTE、EMPTY_BLOB、EMPTY_CLOB、CAST、AR-RAY_NDIMS、ARRAY_FILL、UNNEST 和 ARRAY_LENGTH 等。

  2. HQL(JPA QL)不支持某些操作符,包括:+、^、%、&、|、||、#~等,以及 UNION、UNION ALL、INTERSECT、EXCEPT。

  3. 不支持 INTERVAL 数据类型以及返回值为 INTERVAL 的系统函数,包括:AGE、DATE_FORMAT、ISFI-NITE、STR_VALID 和 TIMEOFDAY。

  4. 对于近义的系统函数,只支持常用的名称,例如:sqrt(dsqrt)、cbrt(dcbrt)等。

  5. 对于重载的系统函数,只支持常用的参数及返回值类型,例如:LEFT(expr1 TEXT, expr2 INTEGER)REPLICATE(expr1 TEXT, expr2 INTEGER)RIGHT(expr1 TEXT, expr2 INTEGER)SUB-STRING(expr1 TEXT, [FROM] expr2 INTEGER[,[FOR] expr3 INTEGER]) 等。

  6. 使用原生查询时,某些函数的返回值与 SeaboxSQL有差异,例如:SIGN() 应返回整型值但实际返回浮点型。

  7. 只有在查询时才可使用 Query.getSingleResult() 方法,例如因为该方法会添加 Limit 子句,call function() 执行函数取返回值时使用该方法会构造一个不合法的 SQL 语句。