Hibernate 框架

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

开发环境搭建

软件 版本
DM 数据库 DM 8.0 及以上版本
JDK JDK 8
Eclipse 2018-12 (4.10.0)
hibernate 3.0

安装 DM 数据库

请参考 DM 数据库快速上手指南

数据库安装过程中,请勾选创建 BOOKSHOPDMHR 示例库,作为数据库模拟环境,如下图所示:

DMHR 示例库

安装 Java 开发工具包--JDK

双击安装包进行安装,安装步骤简单,点击【下一步】安装即可。以安装目录 D:\java\jdk1.8.0_111 为例,安装完成如下图所示:

安装成功

安装成功后需要配置 JDK 环境变量,即将 JDK 安装路径的 bin 路径复制到环境变量 path 里,如下图所示:

环境变量配置

环境变量配置成功后,可使用 win+R 打开命令提示符,输入 java -version 命令,可以正常出现 JDK 版本号,即环境变量配置成功,如下图所示:

JDK 版本号

注意

JDK 安装完成后还需配置环境变量,环境变量配置不正确会导致项目启动报错。

因环境变量配置错误导致的常见错误代码如下:

Unable to find a javac compiler;
Perhaps JAVA_HOME does not point to the JDK;

安装集成开发环境 eclipse

正确配置 Java 环境变量后,eclipse 可正常打开。

开发示例

Hibernate 框架的引入

  1. 准备项目所需 jar 包
  2. 新建项目 JAVA_Hibernate,并导入项目所需 jar 包,如下图所示:
注意

复制 jar 包到 lib 文件夹后,要选择所有 jar 包,鼠标右键,Build path-->Add to Build path。

导入 jar 包到项目里

  1. 在 src 源码目录下创建如下包名,完整项目目录结构如下图所示:

项目完整目录包结构

  1. 书写 Hibernate 的主配置文件:hibernate.cfg.xml.xml,存放在 src 目录下。hibernate.cfg.xml 文件如下所示:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
   <session-factory>

   <!-- 这个属性使 Hibernate 应用为被选择的数据库生成适当的 SQL -->
   <property name="hibernate.dialect">org.hibernate.dialect.DmDialect</property>

   <!-- JDBC 驱动程序类 -->
   <property name="hibernate.connection.driver_class">dm.jdbc.driver.DmDriver</property>

   <!-- Assume test is the database name -->
   <!-- 数据库实例的 JDBC URL -->
   <property name="hibernate.connection.url">jdbc:dm://localhost:5236</property>

   <!-- 数据库用户名 -->
   <property name="hibernate.connection.username">SYSDBA</property>

   <!-- 数据库密码 -->
   <property name="hibernate.connection.password">SYSDBA</property>

   <!-- 是否显示 SQL -->
   <property name="hibernate.show_sql">true</property>

   <!-- 是否将 SQL 格式化 -->
   <property name="hibernate.format_sql">true</property>

   <!-- 是否自动在数据库中生成表 -->
   <property name="hibernate.hbm2ddl.auto">update</property>

   <!-- 事物自动提交 -->
   <property name="hibernate.connection.autocommit">true</property>

   <!-- 针对大字段处理 -->
   <property name="hibernate.connection.SetBigStringTryClob">true</property>

   <!-- List of XML mapping files -->
   <!-- 下面是映射的类 -->
   <mapping resource="com/pojo/BigData.hbm.xml"/>
   <mapping resource="com/pojo/ProductCategory.hbm.xml"/>

</session-factory>
</hibernate-configuration>

基础操作示例代码

基本操作使用的数据表为示例库中 Product 的 PRODUCT_CATEGORY 表,对应于数据库表添加实体类 ProductCategory,其位置放于 com.pojo 下。

操作数据库对应的实体类

ProductCategory.java 文件如下所示:

package com.pojo;
public class ProductCategory {
    private Long productCategoryId;
    private String name;
    public Long getProductCategoryId() {
        return productCategoryId;
    }
    public void setProductCategoryId(Long productCategoryId) {
        this.productCategoryId = productCategoryId;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "ProductCategory [productCategoryId=" + productCategoryId + ", name=" + name + "]";
    }
    public ProductCategory(Long productCategoryId, String name) {
        super();
        this.productCategoryId = productCategoryId;
        this.name = name;
    }
    public ProductCategory() {
        super();
    }
 }

配置实体类与数据库映射的配置文件

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.pojo.ProductCategory" table="PRODUCTION.PRODUCT_CATEGORY">
        <id name="productCategoryId" type="java.lang.Long">
            <column name="PRODUCT_CATEGORYID" />
            <generator class="identity" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" length="50" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

测试类

TestProduct.java 文件如下所示:

package com.test;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.pojo.ProductCategory;

public class TestProductCategory {
    SessionFactory sf = null;
    Session session = null;
    @Before
    public void before() {
        //(1)读取并解析hibernate.cfg.xml配置文件
        Configuration config = new Configuration().configure();
        //(2)由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml"/>读取并解析映射信息*/
        //(3)创建会话SessionFactory对象
        sf = config.buildSessionFactory();
        //(4)加载Session对象
        session = sf.openSession();
    }
    //测试插入
    @Test
    public void testInsert() {
        ProductCategory pCategory = new ProductCategory(null, "美术");
        session.save(pCategory);
    }
    //测试修改
    @Test
    public void testUpdate() {
        ProductCategory pCategory = null; 
        pCategory = (ProductCategory)session.get(ProductCategory.class,new Long(4));
        System.out.println(pCategory);
        pCategory.setName("英语");
        System.out.println(pCategory);
        session.update(pCategory);
    }
    //测试全查
    @Test
    public void testSelectAll() {
        String hql = "from ProductCategory";
        Query query = session.createQuery(hql);
        List<ProductCategory> list = query.list();
        for(ProductCategory pCategory:list) {
            System.out.println(pCategory);
        }
    }
    //测试删除
    @Test
    public  void testDelete(){
        ProductCategory pCategory = null; 
        pCategory = (ProductCategory)session.get(ProductCategory.class,new Long(5));
        if(pCategory!=null) {
            session.delete(pCategory);
        }
    }
    @After
    public void after() {
        if (session != null) { 
            session.flush();
            session.clear();
            //(9) 关闭session对象
            session.close();
            /*
                *关闭session工厂,清空资源.由于sessionFactory对象持有整个持久化操作的资源,
                *关闭之后,下次在使用又需要创建,太耗内存,通过监听器application servletContext对象,
                *当服务器关闭或Web应用被移除时,ServletContext对象跟着销毁,
                *当停止进程时,再清理sessionFactory资源
                */
            //(10) 关闭sessionFactory对象
            sf.close();
        }
    }
    public static void main(String[] args) {
        TestProductCategory test = new TestProductCategory();
        test.before();
        test.testInsert();
        test.testUpdate();
        test.testSelectAll();
        test.testDelete();
        test.after();
    }
}

运行后控制台截图:

运行后控制台截图

运行后数据库表截图:

运行后数据库表截

大字段操作示例

  1. 创建需要操作的含大字段类型的数据表。
CREATE TABLE "PRODUCTION"."TEST_BIG_DATA"
(
"ID" INT IDENTITY(1, 1) NOT NULL,
"PHOTO" IMAGE,
"DESCRIBE" BLOB,
"TXT" CLOB,
NOT CLUSTER PRIMARY KEY("ID")) STORAGE(ON "BOOKSHOP", CLUSTERBTR) ;
  1. 在 D 盘根目录下,创建 DM8 特点.jpg达梦产品简介.txt 两个文件,作为大字段存储,如下图所示:

准备大字段存储文件

操作数据库对应的实体类

BigData.java 文件如下所示:

package com.pojo;

public class BigData {
    private Long id;
    private byte[] photo; 
    private byte[] describe;
    private String txt; 
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public byte[] getPhoto() {
        return photo;
    }
    public void setPhoto(byte[] photo) {
        this.photo = photo;
    }
    public byte[] getDescribe() {
        return describe;
    }
    public void setDescribe(byte[] describe) {
        this.describe = describe;
    }
    public String getTxt() {
        return txt;
    }
    public void setTxt(String txt) {
        this.txt = txt;
    }
    @Override
    public String toString() {
        return "TestBigData [id=" + id + ", txt=" + txt + "]";
    }
    public BigData(Long id, byte[] photo, byte[] describe, String txt) {
        super();
        this.id = id;
        this.photo = photo;
        this.describe = describe;
        this.txt = txt;
    }
    public BigData() {
        super();
    }
}

配置实体类与数据库映射的配置文件

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.pojo.BigData" table="PRODUCTION.TEST_BIG_DATA">
        <id name="id" type="java.lang.Long">
            <column name="ID" />
            <generator class="identity" />
        </id>
        <property name="photo" type="byte[]">
            <column name="PHOTO" />
        </property>
        <property name="describe" type="byte[]">
            <column name="DESCRIBE" />
        </property>
        <property name="txt" type="java.lang.String">
            <column name="TXT" />
        </property>
    </class>
</hibernate-mapping>

测试类

Test_TestBigData.java 文件如下所示:

package com.test;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.pojo.BigData;

public class TestBigData {
    SessionFactory sf = null;
    Session session = null;
    @Before
    public void before() {
        //(1)读取并解析 hibernate.cfg.xml 配置文件
        Configuration config = new Configuration().configure();
        //(2)由 hibernate.cfg.xml 中的<mapping resource="com/xx/User.hbm.xml"/>读取并解析映射信息*/
        //(3)创建会话 SessionFactory 对象
        sf = config.buildSessionFactory();
        //(4)加载 Session 对象
        session = sf.openSession();
    }
    //测试插入大字段表
    @Test
    public void testInsert() {
        try {
        String filePath = "D:\\DM8特点.jpg";
        File file = new File(filePath);
        String filePath2 = "D:\\达梦产品简介.txt";
        File file2 = new File(filePath2);
        InputStream in;
        in = new BufferedInputStream(new FileInputStream(file));
        byte[] bytes1 = new byte[102400];
        byte[] bytes2 = new byte[102400];
        in.read(bytes1);
        InputStream in2 = new BufferedInputStream(new FileInputStream(file));
        in2.read(bytes2);
        BufferedReader reader = new BufferedReader(new InputStreamReader
                (new FileInputStream(file2),"UTF-8"));
        StringBuffer stringBuffer = new StringBuffer("");
        String str = null;
        while((str = reader.readLine())!=null) {
            stringBuffer.append(str);
            stringBuffer.append("\n");
        }
        BigData bigData = new BigData(null,bytes1,bytes2,stringBuffer.toString());
        session.save(bigData);
        in.close();
        in2.close();
        reader.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e){
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //测试查询大字段表
    @Test
    public void testSelect() {
        String hql = "from BigData";
        Query query = session.createQuery(hql);
        List<BigData> list = query.list();
        try {
            for(BigData big:list) {
                //打印出 id
                System.out.println("id = "+big.getId());
                //将 photo 列信息 输出到指定路径
                FileOutputStream fos = new FileOutputStream("D:/"+big.getId()+"_DM8特点.jpg");
                fos.write(big.getPhoto());
                //将 describe 列信息 输出到指定路径
                FileOutputStream fos2 = new FileOutputStream("D:/"+big.getId()+"_Blob_DM8特点.jpg");
                fos2.write(big.getDescribe());
                //将 photo 列信息 输出到控制台
                System.out.println("txt="+big.getTxt());
                fos.close();
                fos2.close();
        }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @After
    public void after() {
        if (session != null) { 
            session.flush();
            session.clear();
            //关闭 session 对象
            session.close();
            // 关闭 sessionFactory 对象
            sf.close();
        }
    }
    public static void main(String[] args) {
        TestBigData test = new TestBigData();
        test.before();
        test.testInsert();
        test.testSelect();
        test.after();
    }
}

运行结果截图

运行前如下图所示:

运行前

运行后控制台输出 Clob 里保存的大字段文本信息,如下图所示:

输出 Clob 里保存的大字段文本信息

运行后读取处理 Image 大字段和 Blob 大字段后的信息,如下图所示:

读取处理 Image 大字段和 Blob 大字段后的信息

运行后数据库数据信息如下图所示:

Image 类型字段数据库保存的是图片信息 Blob 类型字段数据库保存的是文本信息

示例代码下载

请下载示例代码

微信扫码
分享文档
扫一扫
联系客服