【ORM思想】源码分析篇:Hibernate的ORM思想分析

ORM思想之源码分析篇:Hibernate的ORM思想分析


1. ORM的经典应用:Hibernate案例

Hibernate 就是应用 ORM 思想建立的一个框架,一般我们把它称之为全自动的 ORM 框架,程序员在使用 Hibernate 时几乎不用编写 sql 语句,而是通过操作对象即可完成对数据库的增删改查。

通过案例让大家对 ORM 思想有一个更深入的了解
在这里插入图片描述

1.1 创建 Maven 工程

1.2 编写 pom.xml

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.16</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.4.4.Final</version>
    </dependency>
</dependencies>

1.3 核心配置文件 hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.url">jdbc:mysql://localhost:3306/test?serverTimezone=UTC</property>
        <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="connection.username">root</property>
        <property name="connection.password">123456</property>
        
        <property name="hbm2ddl.auto">update</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="show_sql">true</property>

        <mapping class="top.lzchao.orm.entity.Book"/> <!--带有映射注解的实体类-->
        <mapping resource="top/lzchao/orm/entity/Book.hbm.xml"/> <!--映射配置文件-->
    </session-factory>
</hibernate-configuration>

1.4 实体类 Book.java

/**
 * @author: LzCc
 * @blog: https://blog.csdn.net/qq_41744145
 * @description: Book 实体类
 */
public class Book {
    private int id; //主键
    private String name; //图书名字
    private String author; //图书作者
    private double price; //图书价格
    // getter、setter...
}

1.5 编写映射信息

配置映射文件:Book.hbm.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="top.lzchao.orm.entity.Book" table="t_book">
        <id name="id">
            <column name="bid"/>
            <generator class="identity"/> <!--主键的值采用自增方式-->
        </id>
        <property name="name">
            <column name="bname"/>
        </property>
        <property name="author">
            <column name="author"/>
        </property>
        <property name="price">
            <column name="price"/>
        </property>
    </class>
</hibernate-mapping>

也可以通过注解方式:

@Entity
@Table(name = "t_book")
public class Book {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY) //数据库自增
	@Column(name = "bid")
	private Integer id; //主键
	@Column(name = "bname")
	private String name; //图书名字
	@Column(name = "author")
	private String author; //图书作者
	@Column(name = "price")
	private double price; //图书价格
	// getter、setter...
}

1.6 测试类

/**
 * @author: LzCc
 * @blog: https://blog.csdn.net/qq_41744145
 * @description: BookTest
 */
public class BookTest {
    private SessionFactory factory;
    @Before
    public void init() {
        //1. 创建一个 Configuration 对象,解析 hibernate 的核心配置文件
        Configuration cfg = new Configuration().configure();
        //2. 创建 SessinFactory 对象,解析映射信息并生成基本的 sql
        factory = cfg.buildSessionFactory();
    }
    @Test
    public void testSave() {
        //3. 得到 Session 对象,该对象具有增删改查的方法
        Session session = factory.openSession();
        //4. 开启事务
        Transaction tx = session.beginTransaction();
        //5. 保存数据
        Book book = new Book();
        book.setName("Spring5核心原理");
        book.setAuthor("TOM");
        book.setPrice(89.9);
        session.save(book);
        //6. 提交事务
        tx.commit();
    }
    @Test
    public void testGet() {
        //3. 得到 Session 对象,该对象具有增删改查的方法
        Session session = factory.openSession();
        //4. 通过 Session 对象进行查询
        Book book = session.get(Book.class, 1);
        System.out.println(book);
        //5. 释放资源
        session.close();
    }
    @Test
    public void testDelete(){
        //3. 得到 Session 对象,该对象具有增删改查的方法
        Session session=factory.openSession();
        //4. 开启事务管理
        Transaction tx=session.beginTransaction();
        //5. 删除数据
        Book book=new Book();
        book.setId(2);
        session.delete(book);
        //6. 提交事务
        tx.commit();;
        //7. 释放资源
        session.close();
    }
}

该测试类使用 Hibernate 的 API 实现了图书的添加,查询和删除功能,程序员无需编写sql 语句,只需要像平时一样操作对象即可,然后由 Hibernate 框架自动生成 sql 语句,如下图所示:

添加:在这里插入图片描述
查询在这里插入图片描述
删除
在这里插入图片描述

2. Hibernate 的 ORM 实现原理

接下来我们通过上述案例来讲解一下 Hibernate 框架是如何应用 ORM 思想的,一起剖析一下 Hibernate 的内部实现原理。

其实不管使用什么框架,最终都需要生成 sql 语句,因为数据库需要的就是 sql 语句,而我们在使用 Hibernate 编码时没有编写 sql 语句,只是提供了对象,那么 Hibernate 是如何根据对象生成 sql 语句的呢?接下来我们一起跟踪并分析一下 Hibernate 5.x 的源码。

1. 跟踪第一行代码

//1. 创建一个 Configuration 对象,解析 hibernate 的核心配置文件
Configuration cfg = new Configuration().configure();

1.1 在 new Configuration()时,进行了 hibernate 的环境初始化工作,相关对象和容器被创建了出来,如下图所示:
在这里插入图片描述

红框中的两个对象大家要尤为注意,一个是第 158 行的 StandardServiceRegistryBuilder,一个是第 161 行的 Properties 对象,后面的源码中会重点用到这两个对象。

1.2 接下来跟踪调用 configure()方法,如下图所示:
在这里插入图片描述

第 244 行的 configure(…)方法会默认加载名字为 hibernate.cfg.xml 的配置文件,然后去解析该配置文件并把解析到的数据存放到一个 Properties 中(第 258 和 261 行代码)。

解析出来的数据如下图所示:
在这里插入图片描述
通过上图大家能很清晰得看到,hibernate.cfg.xml 中的信息被解析出来并存到了一个 Properties 中。

1.3 我们再跟踪一下第 258 行的代码,这行代码调用了 StandardServiceRegistryBuilder 对象的 config 方法,如下图所示:

在这里插入图片描述
第 165 行从 hibernate.cfg.xml 中解析出来映射配置文件和实体类的信息,并在第 178 行进行了合并汇总,最终存储到了 aggregatedCfgXml 中,如图所示:
在这里插入图片描述
在这里插入图片描述

总之,第一步 Configuration cfg = new Configuration().configure(); 已经把 hibernate.cfg.xml中的信息全部解析了出来并进行了存储。

2. 跟踪第二行代码
//2. 创建 SessinFactory 对象,解析映射信息并生成基本的 sql
SessionFactory factory = cfg.buildSessionFactory();

在这里插入图片描述
由 Configuration 对象的 buildSessionFactory(…)方法创建会话工厂(SessionFactory),该方法的代码非常多,这里只截取了部分关键代码:
* 第 723 行代码从 Properties 中得到配置文件中的数据
* 第 653 行和第 689 行分别创建 MetadataBuilder 对象并调用该对象的 build()方法解析了映射信息,然后存储到 Metadata 对象中,下列截图展示了从映射配置文件或实体类中解析出来的映射数据,包含哪个类和哪个表对应,哪个属性和哪个字段对应:
在这里插入图片描述
在这里插入图片描述
第 708 行调用 SessionFatctoryBuilder 对象的 build()方法生成 sql 语句并返回 SessionFactory 实例,下面截图展示出了生成的 sql 语句:
在这里插入图片描述
在这里插入图片描述
会话工厂(SessionFactory)在 Hibernate 中实际上起到了一个缓冲区的作用,它缓存了Hibernate 自动生成的 SQL 语句和相关映射数据,只要生成了 sql 语句,那么后面实现增删改查就不在话下。

3. 总结流程

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值