更新时间:2024-09-13 GMT+08:00

使用Hibernate连接数据库

Hibernate是一种Java语言下的对象关系映射(ORM)解决方案。它提供了一个使用方便的持久化框架,可以自动将数据库表和Java对象之间建立映射关系,使得开发者可以使用面向对象的方式来操作数据库。使用Hibernate,开发者就不需要手动编写大量的SQL和JDBC代码,从而大大简化了数据访问层的开发工作。

本章节指导用户使用Hibernate连接GaussDB进行建表,修改表以及增删改查操作示例。

配置pom依赖

<dependency>
    <groupId>com.huaweicloud.gaussdb</groupId>
    <artifactId>opengaussjdbc</artifactId>
    <version>503.2.T35</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.3.7.Final</version>
</dependency>

配置pom依赖时,需要提前配置好maven环境。

配置hibernate.cfg.xml资源文件

<?xml version="1.0" encoding="utf-8"?>
        <!DOCTYPE hibernate-configuration PUBLIC
                "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!--GaussDB 连接信息-->
        <property name="connection.driver_class">com.huawei.opengauss.jdbc.Driver</property>
        <property name="connection.url">jdbc:opengauss://***.***.***.***(需要替换为数据库ip):20000(需要替换为数据库端口)/test?currentSchema=test(test需要替换为对应的database和schema)</property>
        <property name="connection.username">***(需要替换为正确的用户名)</property>
        <property name="connection.password">******(需要替换为正确的密码)</property>

        <!-- 以下为可选配置 -->

        <!--是否支持方言 -->
        <!--在 postgresql 兼容模式下,必须有如下配置-->
        <property name="dialect">org.hibernate.dialect.PostgreSQL82Dialect</property>
        <!--执行CURD时是否打印SQL语句  -->
        <property name="show_sql">true</property>

        <!--自动建表(修改表)-->
        <!-- <property name="hbm2ddl.auto">update</property>-->
        <!-- <property name="hbm2ddl.auto">create</property>-->

        <!-- 资源注册 (实体类映射文件)-->
        <mapping resource="./student.xml"/>
    </session-factory>
</hibernate-configuration>

准备实体类和实体类映射表xml文件

以Student类以及student.xml文件为例,文件路径为com.howtodoinjava.hibernate.test.dto。

  1. 实体类。
    public class Student implements Serializable {
        int id;
        String name;
    //  String age;
        // 此处省略构造器,get,set方法
    }
    
  2. student.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>
        <!-- 类与表的映射制作在class元素上 -->
        <!-- name:全路径类名 -->
        <!-- table:表名 -->
        <class name="com.howtodoinjava.hibernate.test.dto.Student" table="student">
            <!-- 主键的映射制作在 id 元素上 -->
            <!-- name:对象中用于作为主键的属性名 -->
            <!-- column:表中主键字段名 -->
            <!-- 如果 name 与 column 值相同,可以省略 column -->
            <id name="id" column="id">
                <!-- 将 generator 元素 class 属性设置为 "assigned" 手动生成,必须给 id -->
                <generator class="assigned"  />
    
                <!--**要注意 Hibernate 主键生成策略**-->
    
            </id>
            <!-- 属性与字段的映射制作在 property 元素上 -->
            <!-- name:类中的属性名 -->
            <!-- column:表中的字段名 -->
            <!-- 如果 name 与 column 值相同,可以省略 column -->
            <property name="name" />
            <!--此处同实体类-->
            <!--<property name="age"/>-->
        </class>
    </hibernate-mapping>

功能测试示例

  1. 测试连接功能。
    1. 测试方法:
      @Test
          public void testConnection() {
              // 加载配置信息
              Configuration conf = new Configuration().configure();
              // 基于配置信息,创建 SessionFactory 对象
              SessionFactory sessionFactory = conf.buildSessionFactory();
              // 打开一个与数据库相关的 session 对象
              Session session = sessionFactory.openSession();
              System.out.println(session);
          }
    2. 打断点可见成功建立连接:
      图1 断点调试
  2. 自动建表。
    1. 将配置文件本行注释打开:
      <property name="hbm2ddl.auto">create</property>
    2. 将数据库中 student 表删除后,执行如下测试方法:
      @Test
          public void testCreateTableAndInsertData() {
              // 创建要测试的对象
              Student student = new Student();
              student.setId(16);
              student.setName("xiaoming");
              // 开启事务,基于 session 得到
              Configuration conf = new Configuration().configure();
              SessionFactory sessionFactory = conf.buildSessionFactory();
              Session session = sessionFactory.openSession();
              Transaction transaction = session.beginTransaction();
              // 通过 session 保存数据
              session.save(student);
              // 提交事务
              transaction.commit();
              // 操作完毕,关闭 session 连接对象
              session.close();
          }
      
    3. 查看控制台打印出来的所执行SQL语句以及 GaussDB 数据库中的结果:
      图2 执行SQL语句
      图3 查询结果

      成功创建student表并插入字段(id = 16, name = "xiaoming")。

  3. 修改表(增加字段)。
    1. 首先修改配置文件,需要配置需要修改表所在的schema路径在url中。

      如本用例中,student 表在名为 test 的 databse 下的名为 test 的 schema 下,即该表路径为test.test.student:

      <property name="connection.url">jdbc:opengauss://xxx.xxx.xxx.xxx(需要替换为数据库ip):20000(需要替换为数据库端口)/test?currentSchema=test(test需要替换为对应的database和schema)</property>
      <!-- 打开update注释 -->
      <property name="hbm2ddl.auto">update</property>
      
    2. 将实体类和xml文件中关于age属性的注释打开,执行如下方法:
       @Test
          public void testAlterTable() {
              // 创建要测试的对象
              Student student = new Student();
              student.setId(15);
              student.setName("xiaohong");
              student.setAge("20");
              // 开启事务,基于 session 得到
              Configuration conf = new Configuration().configure();
              SessionFactory sessionFactory = conf.buildSessionFactory();
              Session session = sessionFactory.openSession();
              Transaction transaction = session.beginTransaction();
              // 通过 session 保存数据
              session.save(student);
              // 提交事务
              transaction.commit();
              // 操作完毕,关闭 session 连接对象
              session.close();
          }
    3. 查看控制台打印出来的所执行SQL语句以及 GaussDB 数据库中的结果:
      图4 执行SQL语句
      图5 查询结果

      在原有表的基础上,框架根据实体类及xml文件,自动对表进行了新增字段处理。

  4. 持久化数据。
    1. 测试方法:
      @Test
          public void testInsert() {
              Student s1 = new Student(1,"q");
              Student s2 = new Student(2,"w");
              Student s3 = new Student(3,"e");
              ArrayList<Student> students = new ArrayList<>();
              students.add(s1);
              students.add(s2);
              students.add(s3);
              // 开启事务,基于 session 得到
              Configuration conf = new Configuration().configure();
              SessionFactory sessionFactory = conf.buildSessionFactory();
              Session session = sessionFactory.openSession();
              Transaction transaction = session.beginTransaction();
              // 通过 session 保存数据
              for (Student student : students) {
                  session.save(student);
              }
              // 提交事务
              transaction.commit();
              // 操作完毕,关闭 session 连接对象
              session.close();
          }
    2. 执行结果如下:
      图6 执行SQL语句
      图7 查询结果

      成功插入三行数据。

  5. HQL模式查询。
    1. 测试方法:
      @Test
          public void testHQL() {
              //HQL模式
              Configuration conf = new Configuration().configure();
              SessionFactory sessionFactory = conf.buildSessionFactory();
              // 创建会话
              Session session = sessionFactory.openSession();
              // 开始事务
              Transaction tx = session.beginTransaction();
      
              // 创建HQL查询
              String hql = "FROM Student S WHERE S.id = 15";
              Query query = session.createQuery(hql);
      
              // 执行查询并获取结果
              List results = query.list();
      
              // 提交事务
              tx.commit();
      
              // 关闭会话
              session.close();
          }
    2. 执行结果如下:
      图8 SQL执行结果
  6. SQL模式查询。
    1. 测试方法:
       @Test
          public void testQuery() {
              // 开启事务,基于 session 得到
              Configuration conf = new Configuration().configure();
              SessionFactory sessionFactory = conf.buildSessionFactory();
              Session session = sessionFactory.openSession();
              Transaction transaction = session.beginTransaction();
              // SQL模式
              List<Student> students = session.createSQLQuery("select * from test.student where id = 1").addEntity(Student.class).list();
              for (int i = 0; i < students.size(); i++) {
                  System.out.println(students.get(i));
              }
              students.get(0).setAge("20");
              // 提交事务
              transaction.commit();
              // 操作完毕,关闭 session 连接对象
              session.close();
          }
    2. 执行结果如下:
      图9 SQL执行结果
      图10 查询结果

      成功查询到id=1的学生数据并修改其age字段为20。

  7. 修改操作。
    • 测试方法:
      @Test
          public void testUpdate() {
              // 开启事务,基于 session 得到
              Configuration conf = new Configuration().configure();
              SessionFactory sessionFactory = conf.buildSessionFactory();
              Session session = sessionFactory.openSession();
              Transaction transaction = session.beginTransaction();
              // SQL模式
              session.createSQLQuery("update test.student set age = 19 where id = 16").executeUpdate();
              // 提交事务
              transaction.commit();
              // 操作完毕,关闭 session 连接对象
              session.close();
          }
      
    • 执行结果如下:
      图11 SQL执行结果
      图12 查询结果

      成功将id=16的学生的age字段修改为19。

  8. 删除操作。
    1. 测试方法:
       @Test
          public void testDelete() {
              // 开启事务,基于 session 得到
              Configuration conf = new Configuration().configure();
              SessionFactory sessionFactory = conf.buildSessionFactory();
              Session session = sessionFactory.openSession();
              Transaction transaction = session.beginTransaction();
              // SQL模式
              List<Student> students = session.createSQLQuery("select * from test.student").addEntity(Student.class).list();
              System.out.println(students);
              session.createSQLQuery("delete from test.student where id = " + students.get(0).getId()).executeUpdate();
              // 提交事务
              transaction.commit();
              // 操作完毕,关闭 session 连接对象
              session.close();
          }
      
    2. 执行结果如下:
      图13 SQL执行结果
      图14 查询结果

      student表中id=15的字段已被删除。