Skip to content

适用虚谷数据库版本

v12.10.13



适用虚谷数据库版本

v12.10.13


hibernate 连接 XuguDB 示例程序 ​

📄字数 6.9K
👁️阅读量 加载中...

虚谷数据库通过实现 Hibernate 的方言接口 Dialect 类,提供了对 Hibernate 框架的功能支持。这些方言类封装了虚谷数据库的特性,使得 Hibernate 能够在虚谷数据库上正确地执行各种数据库操作,包括数据查询、更新、插入、删除以及分页等功能。
本文将介绍对 hibernate-6.6.1 版本的适配情况以及如何连接 XuguDB ,如何使用 xugu-dialect 方言包接入到项目中使用等。

框架名称适配起始版本官网地址源框架下载地址XuguDB框架下载demo程序地址
hibernate3.6.0hibernate 官网hibernate 源码xugu-dialect 版本发布xugu-dialect-demo

提示

其他支持版本可详见版本发布列表

一、使用说明 ​

虚谷对 xugu-dialect 提供了两种获取方式,从而支持 hibernate 框架。源码 install 进行本地 maven 仓库部署和通过 pom 本地引用 jar 包两种方式。

1.1 本地 maven 仓库部署 ​

1.1.1 下载源码 ​

从 xugu-dialect下载源码,获取虚谷适配的 hibernate 框架的方言包 xugu-dialect 源码。

hibernate-github获取源码图 1.1 hibernate-github获取源码

1.1.2 使用 IDEA 编译工具打开源码 ​

idea打开源码图 1.2 idea打开源码

提示

该项目实际是通过继承 hibernate 框架的 Dialect.java 类的方式适配。

1.1.3 项目 install ​

项目依赖加载完毕即可使用 maven 插件进行 install。

maven 执行install图 1.3 maven 执行install

成功完成 install

maven 执行install成功图 1.4 maven 执行install成功

1.1.4 添加依赖 ​

修改 pom.xml 文件,添加一下内容:

xml
<dependency>
  <groupId>com.xugudb</groupId>
  <artifactId>xugu-dialect</artifactId>
  <version>6.6.1</version>
</dependency>

1.2 pom 本地引用 jar 包 ​

1.2.1 解压文件 ​

通过上方链接 XuguDB 框架下载 下载压缩包,并解压。

hibernate 获取到的jar包图 1.5 hibernate 获取到的jar包

1.2.2 lib 文件夹 ​

到项目根路径下创建 lib 包并且把获取的 jar 包放入 lib 包中,然后在项目的 pom.xml 文件中添加依赖

xml
<dependency>
  <groupId>com.xugudb</groupId>
  <artifactId>xugu-dialect</artifactId>
  <version>6.6.1</version>
  <systemPath>${project.basedir}/src/main/resources/lib/xugu-dialect-6.6.1.jar</systemPath>
  <scope>system</scope>
</dependency>
添加到lib图 1.6 添加到lib

1.3 功能支持 ​

1.3.1 数据类型映射 ​

SqlTypestypeNamePattern
BITBinary
DECIMALNumeric(p,s)
CHARchar($l)
VARCHARVarchar($l)
LONGVARCHARVarchar
VARBINARYBinary
LONGVARBINARYBlob
CLOBClob
REALFloat
DATEDate
TIMETime
TIMESTAMPTimestamp

1.3.2 功能支持 ​

支持类别详细支持内容
分页与排序支持支持通过 LIMIT 和 OFFSET 关键字实现分页查询,兼容 FOR UPDATE 子句以确保数据一致性;支持对查询结果的排序,包括对空值的排序规则。
序列与标识列支持支持通过 CREATE SEQUENCE 语句创建序列,并提供获取序列值的 SQL 片段;支持自增列,通过 identity(1,1)定义自增列,并提供获取最后插入的自增列值的 SQL 语句。
事务与锁支持支持事务操作,并提供锁功能以确保数据一致性;通过 getForUpdateString 方法生成 FOR UPDATE 子句,实现行级锁定。
模式与表操作支持支持模式与表的操作,包括通过 CREATE DATABASE 和 DROP DATABASE 创建和删除数据库;通过 CREATE TABLE 和 DROP TABLE 创建和删除表。
外键与约束支持支持外键约束的创建和删除,确保数据的参照完整性;通过 ADD CONSTRAINT 和 DROP CONSTRAINT 创建和删除外键约束;同时支持唯一键约束的删除。
注释支持支持表注释和列注释的添加,便于数据字典的维护和理解;通过 COMMENT ON 语句添加表注释和列注释。
临时表支持支持通过 CREATE TEMPORARY TABLE 语句创建临时表,并提供本地临时表支持。
特殊功能支持支持通过 SELECT uuid() 获取 GUID ;支持处理日期时间字面量,并支持查询序列信息。

二、连接示例 ​

2.1 前提条件 ​

  • 系统环境
  • 计算机已安装 JDK 11 和 Maven。
  • 计算机已安装 IntelliJ IDEA。
  • 计算机已部署 XuguDB 12.0.0 或有能连接访问的虚谷数据库实例。
  • 提前备好 xugu-dialect-6.6.1 的 jar 包。

2.2 maven 依赖 ​

xml
<dependencies>
    <!-- hibernate Core -->
    <dependency>
        <groupId>org.hibernate.orm</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>6.6.1.Final</version>
    </dependency>
   <!-- 虚谷数据库方言 -->
    <dependency>
        <groupId>com.xugudb</groupId>
        <artifactId>xugu-dialect</artifactId>
        <version>6.6.1</version>
    </dependency>
    <!-- 虚谷数据库 JDBC 驱动 -->
    <dependency>
        <groupId>com.xugudb</groupId>
        <artifactId>xugu-jdbc</artifactId>
        <version>12.3.2</version>
    </dependency>
</dependencies>

2.3 hibernate 配置 ​

2.3.1 必要配置 ​

属性值示例说明
hibernate.connection.urljdbc:xugu://localhost:5138/SYSTEM必须连接url
hibernate.connection.usernameSYSDBA用户名
hibernate.connection.passwordSYSDBA密码
hibernate.connection.driver_classcom.xugu.cloudjdbc.DriverJDBC驱动类
hibernate.dialectcom.xugu.dialect.XuguDialect方言类

2.3.2 XML 示例配置: hibernate.cfg.xml ​

xml
<?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>
    <!-- JDBC 连接 -->
    <property name="hibernate.connection.driver_class">com.xugu.cloudjdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:xugu://localhost:5138/SYSTEM</property>
    <property name="hibernate.connection.username">SYSDBA</property>
    <property name="hibernate.connection.password">SYSDBA</property>
    <!-- 方言配置 -->
    <property name="hibernate.dialect">com.xugu.dialect.XuguDialect</property>
    <!-- 最佳实践 -->
    <property name="hibernate.hbm2ddl.auto">validate</property>
    <property name="hibernate.jdbc.batch_size">25</property>
  </session-factory>
</hibernate-configuration>

提示

该文件应该位于:src\main\resources 目录下。

2.4 代码示例 ​

  1. 在项目根目录的 src\main\java\com\xugu\entity 下创建一个 User 实体类。User.java 文件如下所示:
java
@Entity
@Table(name = "USERT")
public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    private String id;
    private String name;
    private String password;
    private String policy;
    private Float organflag;

    public float getOrganflag() {
        return organflag;
    }

    public void setOrganflag(float organflag) {
        this.organflag = organflag;
    }

    public User(String id, String name, String password, String policy, float organflag) {
        this.id = id;
        this.name = name;
        this.password = password;
        this.policy = policy;
        this.organflag = organflag;
    }

    public User(String name, String password, String policy, Float organflag) {
        this.name = name;
        this.password = password;
        this.policy = policy;
        this.organflag = organflag;
    }

    public String getPolicy() {
        return policy;
    }

    public void setPolicy(String policy) {
        this.policy = policy;
    }

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public User() {
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", policy='" + policy + '\'' +
                ", organflag=" + organflag +
                '}';
    }
}
  1. 在项目根目录的 src\main\resources\mapper 下创建实体类对应配置类。User.hbm.xml 文件如下所示:
xml
<?xml version="1.0"?>
<!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.xugu.entity.User" table="USERT">
        <id name="id" type="java.lang.String">
            <column name="ID" />
            <generator class="uuid"/>
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <property name="password" type="java.lang.String">
            <column name="PASSWORD" />
        </property>
        <property name="policy" type="java.lang.String">
            <column name="[POLICY]"/>
        </property>
        <property name="organflag" type="java.lang.Float">
            <column name="ORGANFLAG"/>
        </property>
    </class>
</hibernate-mapping>
  1. 在项目根目录的 src\main\java\com\xugu\utils 下创建 Utils 工具类,用于获取 SessionFactory 对象和创建 Session 对象。Utils.java 文件如下所示:
java

public class Utils {

    static Configuration configuration =null;
    static SessionFactory sessionFactory = null;
    static
    {
        // 加载一次配置文件
        configuration = new Configuration();
        configuration.configure();

        // 获取一个sessionFactory
        sessionFactory=configuration.buildSessionFactory();

    }
    

    // 从连接池获取的
    public  Session openSession()
    {
        return sessionFactory.openSession();
    }

    //获取SessionFactory
    public  SessionFactory getSessionFactory(){
        return sessionFactory;
    }

    /**
     * 关闭session
     * @param session
     */
    public void closeSession(Session session){
        if(session != null) {
            session.close();
        }
    }

    /**
     * 关闭SeesionFactory
     * @param sessionFactory
     */
    public void closeSessionFactory(SessionFactory sessionFactory){
        if(sessionFactory != null){
            sessionFactory.close();
        }
    }


}
  1. 在项目根目录的 src\test\java\com\xugu\mapper 下创建单元测试类,分别测试插入、查询、更新和删除操作。HibernateTest.java 文件如下所示:
java
public class HibernateTest {
    
    private static Utils utils;
    
    @Test
    public void insertTest(){
        //使用sessionFactory对象创建session对象
        Session session =  utils.openSession();
        //手动开启事务
        Transaction transaction = session.beginTransaction();
        //构建实体对象
        User user = new User();
        //user.setId(UUID.randomUUID().toString());
        user.setName("测试名1");
        user.setPassword("123456");
        user.setPolicy("hibernate测试333");
        user.setOrganflag(2);
        log.info("插入的数据为:"+user);
        //调用save() 保存数据到表
        session.save(user);
        //提交事务
        transaction.commit();
        //期望值
        String expected = user.toString();
        //实际值
        String actual =session.load(User.class,user.getId()).toString();
        //使用断言机制判断
        Assert.assertEquals(expected,actual);
        //关闭资源
        session.close();

    }

        @Test
        public void SelectTest(){
        Session session =  utils.openSession();
        //手动开启事务
        Transaction transaction = session.beginTransaction();
        //指定条件查询
        String hql = "from User where name = :name_val";
        Query query = session.createQuery(hql);
        query.setParameter("name_val", "测试名1");
        //执行语句,获取结果集
        List<User> list = query.list();
        for (User val:list) {
        log.info("查询得到的数据为:"+val);
        }
        //期望值
        int expected = 1;
        //实际值
        int actual = list.size();
        //使用断言机制判断
        Assert.assertEquals(expected,actual);
        //关闭资源
        session.close();
        }

        @Test
        public void  insertOrUpdateTest() throws SQLException {
        //使用sessionFactory对象创建session对象
        Session session =  utils.openSession();
        //手动开启事务
        Transaction transaction = session.beginTransaction();
        SessionFactory sessionFactory = utils.getSessionFactory();
        //从sessionFactory中获取connection
        Connection connection = sessionFactory.getSessionFactoryOptions().getServiceRegistry().getService(ConnectionProvider.class).getConnection();
        Statement statement = connection.createStatement();
        //清空表
        String sql1 = "truncate usert";
        statement.execute(sql1);
        User user = new User(UUID.randomUUID().toString(),"新的测试名","rqerer","reqegfrqtgrr",3.0f);
        //插入对象
        session.save(user);
        //指定条件查询
        String sql = "select * from usert where name = '新的测试名'";
        NativeQuery<User> query = session.createNativeQuery(sql,User.class);
        //获取结果集
        List<User> list = query.getResultList();
        for (User val:list) {
        user = val;
        log.info("更新前的数据为:"+user);
        }
        //更新数据
        user.setName("saveOrUpdate测试");
        session.saveOrUpdate(user);
        //提交事务
        transaction.commit();
        log.info("更新后的数据"+user);
        //期望值
        String expected = user.toString();
        //实际值
        String actual = session.load(User.class,user.getId()).toString();
        //使用断言机制判断
        Assert.assertEquals(expected,actual);
        //关闭资源
        session.close();
        }

        @Test
        public void DeleteTest(){
        Session session =  utils.openSession();
        //手动开启事务
        Transaction transaction = session.beginTransaction();
        String name = "新的测试名";
        //hql语句删除数据
        String  hql = "delete User where NAME = :oldName";
        int deleteEntities = session.createQuery(hql)
        .setString("oldName",name)
        .executeUpdate();
        //提交事务
        transaction.commit();
        //期望值
        int expected = 0;
        //实际值
        int actual = deleteEntities;
        //使用断言机制判断
        Assert.assertEquals(expected,actual);
        //关闭资源
        session.close();
        }

}
  1. 在项目根目录的 src\main\resources 下创建 hibernate 框架配置文件。hibernate.cfg.xml 文件如下所示:
xml
<?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>
    <!-- JDBC 连接 -->
    <property name="hibernate.connection.driver_class">com.xugu.cloudjdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:xugu://localhost:5138/SYSTEM</property>
    <property name="hibernate.connection.username">SYSDBA</property>
    <property name="hibernate.connection.password">SYSDBA</property>
    <!-- 方言配置 -->
    <property name="hibernate.dialect">com.xugu.dialect.XuguDialect</property>
    <!-- 最佳实践 -->
    <property name="hibernate.hbm2ddl.auto">validate</property>
    <property name="hibernate.jdbc.batch_size">25</property>
     <mapping resource="mapper/User.hbm.xml" />
  </session-factory>
</hibernate-configuration>

提示

hibernate.cfg.xml 文件中需要配置实体类或者实体类对应的xml配置文件。

三、常见问题&解决办法 ​

  1. 出现报错ong.hibernate.StaleObjectStateException Create breakpoint: Request processing failed: org.springframework.orm.ObjectOptimisticLockingFailureException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)...
    • 保存数据时,当 id 映射为空串时,hibernate 会抛出异常。
    • 解决方法:将 id 映射为 null
  2. 导包需要 hibernate-core 和 xugu-jdbc 同时导入,缺少任何一个都会导致程序抛出异常,启动失败。
  3. 导入虚谷方言包版本应该匹配应用程序中的 hinbernate-core 版本。不同版本之间,存在差异。