通过Hibernate使用SQL查询

更新时间:
复制为 MD 格式

通过表格存储 JDBC 驱动集成 Hibernate ORM 框架,可在 Java 应用中以 ORM 方式查询表格存储数据。

前提条件

  • 已获取 AccessKey。RAM 用户需具备 "Action": "ots:SQL*" 权限。

  • 已创建数据表和映射表,详见DDL 操作

使用流程

步骤一:安装JDBC驱动

可通过以下两种方式安装 JDBC 驱动。

添加Maven依赖

在 Maven 工程的 pom.xml 中添加表格存储 JDBC 驱动依赖。以 5.17.0 版本为例,在 <dependencies> 内加入如下内容:

<dependency>
  <groupId>com.aliyun.openservices</groupId>
  <artifactId>tablestore-jdbc</artifactId>
  <version>5.17.0</version>
</dependency>

手动安装

下载 表格存储 JDBC 驱动并导入到项目中。

步骤二:安装Hibernate

可通过以下两种方式安装 Hibernate。

添加Maven依赖

在 Maven 工程的 pom.xml 中添加 Hibernate 依赖。以 3.6.3.Final 版本为例,在 <dependencies> 内加入如下内容:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>3.6.3.Final</version>
</dependency>

手动安装

下载 Hibernate 安装包并导入到项目中。

步骤三:映射SQL字段

创建数据表字段对应的 Java Bean,并通过映射配置文件将 Bean 成员变量与数据表字段一一映射。

  1. 创建数据表字段对应的 Java Bean。

    package hibernate;
    
    public class Trip {
    
        private long tripId;
        private long duration;
        private String startDate;
        private String endDate;
        private long startStationNumber;
        private long endStationNumber;
        private String startStation;
        private String endStation;
        private String bikeNumber;
        private String memberType;
        
        // 以 tripId 为例,其他字段类似。
        public void setTripId(Long tripId){
            this.tripId = tripId;
        }
        public Long getTripId() {
            return tripId;
        }
    }
  2. 创建映射配置文件。以在 hibernate 目录下创建 Trip.hbm.xml 为例,将 Java Bean 的成员变量与数据表字段映射。

    重要

    如果仅查询数据而不写入,建议将属性列的 insert 和 update 属性设为 false,避免 Hibernate 自动生成写入语句。SQL 数据类型映射规则参见 SQL数据类型映射

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <!--此处的类名必须与实际类名称一致。-->
        <class name="hibernate.Trip" table="trips">
            <!-- id元素中配置的字段为数据表中的主键列。-->
            <id name="tripId" column="trip_id" type="long"/>
            <!-- 如果仅查询数据,建议将属性列的 insert 和 update 设置为 false。-->
            <property name="duration" column="duration" type="long" insert="false" update="false"/>
            <property name="startDate" column="start_date" type="string" insert="false" update="false"/>
            <property name="endDate" column="end_date" type="string" insert="false" update="false"/>
            <property name="startStationNumber" column="start_station_number" type="long" insert="false" update="false"/>
            <property name="endStationNumber" column="end_station_number" type="long" insert="false" update="false"/>
            <property name="startStation" column="start_station" type="string" insert="false" update="false"/>
            <property name="endStation" column="end_station" type="string" insert="false" update="false"/>
            <property name="bikeNumber" column="bike_number" type="string" insert="false" update="false"/>
            <property name="memberType" column="member_type" type="string" insert="false" update="false"/>
        </class>
    </hibernate-mapping>

步骤四:构建SessionFactory

完成配置文件设置后,加载 Hibernate 配置文件创建 SessionFactory。

  1. 创建 Hibernate 配置文件 hibernate.cfg.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>
            <property name="hibernate.connection.driver_class">com.alicloud.openservices.tablestore.jdbc.OTSDriver</property>
            <property name="hibernate.connection.url">jdbc:ots:https://myinstance.cn-hangzhou.ots.aliyuncs.com/myinstance</property>
            <property name="hibernate.connection.username">************************</property>
            <property name="hibernate.connection.password">********************************</property>
            <property name="hibernate.connection.autocommit">true</property>
            <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
            <!-- 设置为映射配置文件的路径。-->
            <mapping resource="hibernate/Trip.hbm.xml"/>
        </session-factory>
    </hibernate-configuration>

    配置项说明如下。

    配置项

    类型

    是否必选

    描述

    hibernate.connection.driver_class

    class

    表格存储 JDBC 驱动的类名,固定为 com.alicloud.openservices.tablestore.jdbc.OTSDriver

    hibernate.connection.url

    string

    实例访问地址,格式为 jdbc:ots:endpoint/instanceName。其中 endpoint 为实例的服务地址,instanceName 为实例名称,根据实际情况修改。

    hibernate.connection.username

    string

    阿里云账号或 RAM 用户的 AccessKey ID。

    hibernate.connection.password

    string

    阿里云账号或 RAM 用户的 AccessKey Secret。

    hibernate.connection.autocommit

    boolean

    是否自动提交。

    重要

    表格存储不支持事务,autocommit 必须设为 true。

    hibernate.dialect

    string

    表格存储 SQL 兼容 MySQL 语法,固定为 org.hibernate.dialect.MySQLDialect

  2. 加载 Hibernate 配置文件构建 SessionFactory。

    SessionFactory factory = new Configuration().
      configure("hibernate/hibernate.cfg.xml").
      buildSessionFactory();

步骤五:创建Session查询数据

通过 SessionFactory 创建 Session,调用 get 方法按主键查询数据。

Session session = factory.openSession();
Trip trip = (Trip) session.get(Trip.class, 99L); 
System.out.println("trip id: " + trip.getTripId());
System.out.println("start date: " + trip.getStartDate());
System.out.println("end date: " + trip.getEndDate());
System.out.println("duration: " + trip.getDuration());
session.close();
factory.close();

完整示例

查询表中指定主键行并获取列值。以主键列值 99 为例:

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import hibernate.Trip;

public class HibernateDemo {
    public static void main(String[] args) {
        SessionFactory factory = new Configuration().
                configure("hibernate/hibernate.cfg.xml").
                buildSessionFactory();
        Session session = factory.openSession();
        Trip trip = (Trip) session.get(Trip.class, 99L);
        System.out.println("trip id: " + trip.getTripId());
        System.out.println("start date: " + trip.getStartDate());
        System.out.println("end date: " + trip.getEndDate());
        System.out.println("duration: " + trip.getDuration());
        session.close();
        factory.close();
    }
}           

常见问题

Unable to instantiate default tuplizer

报错信息:

org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer]

原因:缺少 javassist 依赖。

解决方案:

在 pom.xml 中添加:

<dependency>
    <groupId>org.javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.15.0-GA</version>
</dependency>

Unknown column '{columnName}' in 'field list'

原因:SQL 映射表中不存在指定列。

解决方案:

  • 在预定义列中添加指定列,该列会自动同步到 SQL 映射表中。

  • 通过 CREATE TABLE 或 ALTER TABLE 语句在映射表中添加指定列,详见DDL 操作