赞
踩
Hibernate 是一款优秀的持久化框架及优秀的 ORM 框架之一。
它通过使用 Java 反射、xml解析、代理模式等等技术对 JDBC 原有的繁琐的操作步骤进行了简化封装,使得之前 JDBC 代码可能需要几十行代码才能完成的功能,只需几行代码就能搞定。
而且开发人员即使不需要熟悉 SQL 也能完成对数据库完成 CRUD 操作。它可以自动生成SQL语句,自动执行。完全可以使用面向对象的思想完成对数据库的操作。
所以使用 Hibernate 框架可以大大简化了代码和提高了开发的效率。
ORM 即
Object Relation Mapping
对象关系映射。是一种程序技术,解决一类问题的思路方法,不局限于应用在 Java 语言。用于面向对象语言中完成类和表,属性和表字段转换的映射机制。
举例来说:
在 Java 有一个实体类 School ,在 MySQL 数据库中有一张表 schoolTbl 。现在需要完成 Java 中对象数据通过自动化框架持久化到 MySQL 数据库表中。这时对象的属性和表中的列如何对应?ORM 就是解决这样问题的。如图:
从上图中,可以看到中间映射的作用,就是完成了类属性和表字段的对应映射关系。从而可以实现 School 对象根据映射表生成对应表的 SQL 语句。这就是 ORM 的概念和作用。
Hibernate 的其他概念,我们就先不啰嗦了,有需要进一步解释的,
可以添加个人微信zp11481062,
接下来,我们来介绍 Hibernate 环境搭建步骤。
目前 Hibernate 官网版本已经到 Hibernate6 了,但是还是属于测试阶段,所以我们可以下载最近更新的稳定版 Hibernate5.4.3 版:
下载地址:5.4 series - Hibernate ORM
在 lib 目录下有一个文件夹 required 下就是 Hibernate 必须的依赖 jar 包
本案例使用 Eclipse 新建 web 工程(工程创建步骤省略),然后拷贝上一步的 jar 包到工程下的 lib 目录,另外注意:连接 MySQL 还需要连接 Mysql 的驱动 jar 包,所以也需要提前下载,拷贝进来,如下图:
- -- 创建数据库
- 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('西安三中','西安市新城区长乐西路');

- 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;
- }
- }

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>

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 步创建的映射文件关联的,所以这里的路径一定要一致,而且注意是路径,不是包结构。
写一个类来根据主键查询对象, 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();
- }
- }
-
- }

运行结果如下,表示查询到对象数据,成功:
通过上面第 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() 方法完成数据保存入库操作。步骤最后我们总结。
下面来看修改代码:
- 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();
- }
- }
- }

上面代码需要注意的就是,对于修改,需要先根据主键查询出对象,然后在查出后的对象上做修改,最后持久化到数据库中。为什么要先查询,看下图:
从图中我们可以看到框架在执行修改操作时,执行的 SQL 语句。比较代码,我们只是修改了 scname 属性,并没有要修改 address 属性,但是框架这里做的是全列修改!所以如果我们不先查询出旧的对象数据,而是新实例化对象执行修改,则会导致,其他没有要修改的属性值,会置空 null 或修改成其他数据。所以一般修改,需要先查询再修改。
- 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 完全面向对象思想来操作的。修改的是对象,删除的也是对象。当然,如果你这里新实例化一个对象,只要指定主键,也是可以删除成功的,不过就不能和缓存同步了而已,具体差别这里不在详述。
上面代码中,为了方便理解,并没有去封装 session 对象的获取步骤,开发中肯定需要封装成工具类的。
从上面四个的查询、插入、修改、删除操作中,可以归纳 Hibernate 持久化的七个步骤:
加载配置文件;
创建会话工厂 SessionFactory;
创建会话 Session;
开启事务;
持久化操作;
提交事务;
关闭会话;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。