通过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 操作。