保存成功
订阅成功
保存失败,请重试
提交成功

Hibernate5 之 Hello World 级入门教程

向作者提问
寰讯天翔创始人兼 CTO,曾任华为高级工程师,中软国际技术咨询顾问,知名大学特聘高级讲师。15 年软件开发及教学经验。曾参与华为 Nastar 系统平台的设计与研发,教育厅资源平台研发,Android 游戏《突突兔》,《岛屿守卫者》等游戏作者。
查看本场Chat

Hibernate 简介

Hibernate 是一款优秀的持久化框架及优秀的 ORM 框架之一。它通过使用 Java 反射、xml 解析、代理模式等等技术对 JDBC 原有的繁琐的操作步骤进行了简化封装,使得之前 JDBC 代码可能需要几十行代码才能完成的功能,只需几行代码就能搞定。而且开发人员即使不需要熟悉 SQL 也能完成对数据库完成 CRUD 操作。它可以自动生成 SQL 语句,自动执行。完全可以使用面向对象的思想完成对数据库的操作。所以使用 Hibernate 框架可以大大简化了代码和提高了开发的效率。

ORM 是什么?

ORM 即 Object Relation Mapping 对象关系映射。是一种程序技术,解决一类问题的思路方法,不局限于应用在 Java 语言。用于面向对象语言中完成类和表,属性和表字段转换的映射机制。

​ 举例来说:

​ 在 Java 有一个实体类 School,在 MySQL 数据库中有一张表 schoolTbl。现在需要完成 Java 中对象数据通过自动化框架持久化到 MySQL 数据库表中。这时对象的属性和表中的列如何对应?ORM 就是解决这样问题的。如图:

enter image description here

从上图中,可以看到中间映射的作用,就是完成了类属性和表字段的对应映射关系。从而可以实现 School 对象根据映射表生成对应表的 SQL 语句。这就是 ORM 的概念和作用。

搭建环境详细步骤

​ Hibernate 的其他概念,我们就先不啰嗦了,有需要进一步解释的,可以关注文末我的个人公众号 zp11481062,接下来,我们来介绍 Hibernate 环境搭建步骤。

1. 下载 Hibernate 类库 jar 包

​ 目前 Hibernate 官网版本已经到 Hibernate6 了,但是还是属于测试阶段,所以我们可以下载最近更新的稳定版 Hibernate5.4.3 版:

下载地址:http://hibernate.org/orm/releases/5.4/

enter image description here

2. 解压并找到 lib 目录

​ 在 lib 目录下有一个文件夹 required 下就是 Hibernate 必须的依赖 jar 包

enter image description here

3. 使用 IDE (本案例使用 Eclipse ) 创建项目工程

​ 本案例使用 Eclipse 新建 web 工程(工程创建步骤省略),然后拷贝上一步的 jar 包到工程下的 lib 目录,另外注意:连接 MySQL 还需要连接 Mysql 的驱动 jar 包,所以也需要提前下载,拷贝进来,如下图:

enter image description here

4. 在 MySQL 数据库中创建表

-- 创建数据库
CREATE DATABASE hib;
-- 打开数据库
USE hib;
-- 创建表
CREATE TABLE school(
    scid INT PRIMARY KEY AUTO_INCREMENT,
    scname VARCHAR(100),
    address VARCHAR(200)
);
-- 创建学生表
CREATE TABLE student(
    sid INT AUTO_INCREMENT PRIMARY KEY,
    sname VARCHAR(20),
    birthday DATE,
    gendar VARCHAR(2),
    phone VARCHAR(12)
);
-- 插入测试数据
INSERT INTO school(scname,address)VALUES('西安三中','西安市新城区长乐西路');

5. 在 Java 项目中新建实体类 School

package com.wdzl.entity;

public class School {
    private Integer scid;
    private String scname;
    private String address;

    public Integer getScid() {
        return scid;
    }
    public void setScid(Integer scid) {
        this.scid = scid;
    }
    public String getScname() {
        return scname;
    }
    public void setScname(String scname) {
        this.scname = scname;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
}

6. 新建实体类的映射文件 School.hbm.xml

 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="com.wdzl.entity.School" table="school">
        <!-- id表示主键 -->
        <id name="scid" column="scid">
             <!-- 主键生成策略,native表示数据库端本地生成策略,比如标识列 -->
            <generator class="native"></generator>
          </id>
        <!-- 属性和列名对应关系,不过这里属性和列表定义相同了,可以不同的 -->
        <property name="scname" column="scname"></property>
        <property name="address" column="address"></property>
    </class>
</hibernate-mapping>

7. 新建 Hibernate 的配置文件

​ Hibernate 框架是对 JDBC 的封装,所以一样是需要 JDBC 连接所需的 url、driver、username、password 这四个参数的,Hibernate 一般是通过配置文件来指定的。所以在 src 目录下新建 xml 文件 hibernate.cfg.xml文件,内容如下:

<!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="dialect">
            org.hibernate.dialect.MySQLDialect
        </property>
        <!-- 驱动 -->
        <property name="connection.driver_class">
            com.mysql.jdbc.Driver
        </property>
        <!-- URL -->
        <property name="connection.url">
            jdbc:mysql://127.0.0.1:3306/hib
        </property>
        <!-- 用户名 -->
        <property name="connection.username">root</property>
        <!-- 密码 -->
        <property name="connection.password">root</property>
        <!-- 在控制台显示SQL语句 -->
        <property name="show_sql">true</property>

        <!-- 注册所有ORM映射文件 -->
        <mapping resource="com/wdzl/entity/School.hbm.xml" />
    </session-factory>
</hibernate-configuration>

注意:在上面配置文件中,

<mapping resource="com/wdzl/entity/School.hbm.xml" />

这个映射文件的引入就是和上一步第 6 步创建的映射文件关联的,所以这里的路径一定要一致,而且注意是路径,不是包结构。

8. 新建类来测试调用,检查环境

​ 写一个类来根据主键查询对象, Test01.java:

package com.wdzl.test;

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

import com.wdzl.entity.School;

public class Test01 {

    public static void main(String[] args) {
        try {
            //加载配置文件
            Configuration cfg = new Configuration().configure("hibernate.cfg.xml");
            //创建会话工厂
            SessionFactory factory = cfg.buildSessionFactory();
            //创建会话session
            Session session = factory.openSession();

            //根据主键查询对象
            School school = session.get(School.class, 1);
            System.out.println("==="+school);

            //关闭会话
            session.close();
            //关闭工厂 释放资源
            factory.close();
        } catch (HibernateException e) { 
            e.printStackTrace();
        }
    }

}

运行结果如下,表示查询到对象数据,成功:

enter image description here

9.保存对象数据(插入操作)

通过上面第 8 步,我们就算是完成了 Hibernate5 的环境搭建了,上面是根据主键查询,接下来,写一个保存数据的代码例子:

package com.wdzl.test;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.wdzl.entity.School;

/**
 *     保存数据到数据库
 *
 */
public class Test02 {

    public static void main(String[] args) {
        try {
            //加载配置文件
            Configuration cfg = new Configuration().configure("hibernate.cfg.xml");
            //创建会话工厂
            SessionFactory factory = cfg.buildSessionFactory();
            //创建会话session
            Session session = factory.openSession();
            //开启事务
            Transaction tran = session.beginTransaction();

            //实例化对象
            School school = new School();
            school.setScname("Java一中");
            school.setAddress("Java三路");

            //持久化
            session.save(school);

            //提交事务
            tran.commit();

            //关闭会话
            session.close();
            //关闭工厂 释放资源
            factory.close();
        } catch (HibernateException e) { 
            e.printStackTrace();
        }
    }
}

这里就是新实例化一个对象,并赋值,然后通过 session.save() 方法完成数据保存入库操作。步骤最后我们总结。

10. 数据修改

下面来看修改代码:

package com.wdzl.test;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.wdzl.entity.School;
/**
 *     修改
 */
public class Test03 {

    public static void main(String[] args) {
        try {
            //加载配置文件
            Configuration cfg = new Configuration().configure("hibernate.cfg.xml");
            //创建会话工厂
            SessionFactory factory = cfg.buildSessionFactory();
            //创建会话session
            Session session = factory.openSession();
            //开启事务
            Transaction tran = session.beginTransaction();

            //根据主键查询对象
            School school = session.get(School.class, 1);

            school.setScname("西安4中");
            //持久化 修改
            session.update(school);

            //提交事务
            tran.commit();
            //关闭会话
            session.close();
            //关闭工厂 释放资源
            factory.close();
        } catch (HibernateException e) { 
            e.printStackTrace();
        }
    }
}

上面代码需要注意的就是,对于修改,需要先根据主键查询出对象,然后在查出后的对象上做修改,最后持久化到数据库中。为什么要先查询,看下图:

enter image description here

从图中我们可以看到框架在执行修改操作时,执行的 SQL 语句。比较代码,我们只是修改了 scname 属性,并没有要修改 address 属性,但是框架这里做的是全列修改!所以如果我们不先查询出旧的对象数据,而是新实例化对象执行修改,则会导致,其他没有要修改的属性值,会置空 null 或修改成其他数据。所以一般修改,需要先查询再修改。

11. 数据删除

package com.wdzl.test;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.wdzl.entity.School;

public class Test04 {

    public static void main(String[] args) {
        try {
            //加载配置文件
            Configuration cfg = new Configuration().configure("hibernate.cfg.xml");
            //创建会话工厂
            SessionFactory factory = cfg.buildSessionFactory();
            //创建会话session
            Session session = factory.openSession();
            //开启事务
            Transaction tran = session.beginTransaction();

            //根据主键查询对象
            School school = session.get(School.class, 1);

            //持久化 删除
            session.delete(school);

            //提交事务
            tran.commit();
            //关闭会话
            session.close();
            //关闭工厂 释放资源
            factory.close();
        } catch (HibernateException e) { 
            e.printStackTrace();
        }
    }

}

删除操作,这里也是先查询再删除的,因为 Hibernate 完全面向对象思想来操作的。修改的是对象,删除的也是对象。当然,如果你这里新实例化一个对象,只要指定主键,也是可以删除成功的,不过就不能和缓存同步了而已,具体差别这里不在详述。

12. 总结

​ 上面代码中,为了方便理解,并没有去封装 session 对象的获取步骤,开发中肯定需要封装成工具类的。

从上面四个的查询、插入、修改、删除操作中,可以归纳 Hibernate 持久化的七个步骤:

​ 加载配置文件;

​ 创建会话工厂 SessionFactory;

​ 创建会话 Session;

​ 开启事务;

​ 持久化操作;

​ 提交事务;

​ 关闭会话;

13. 最后

​ 如果有问题可以随时留言,可以关注个人公众号:java_1995。

​ 后续会经常推送技术相关面试题,敬请关注,谢谢

​ 源码下载:https://github.com/zp8126/hibernate01

enter image description here


本文首发于 GitChat,未经授权不得转载,转载需与 GitChat 联系。

互动评论
评论
五一快乐4 个月前
哈哈哈
评论
24KBear8 个月前
入门?!
评论
愚凡(作者)8 个月前
环境搭建和基本增删改查,确实入门级的
评论
查看更多
微信扫描登录