Hibernate入门教程(二)
2018-05-19 本文已影响33人
叩丁狼教育
讲师:钟昕灵,叩丁狼教育高级讲师。原创文章,转载请注明出处。
在上一节中,我们使用Hibernate实现了基本的CRUD操作,可以看出整个过程还是比较简单的,但是我们还是需要去分析一下其执行的流程,达到灵活使用的目的.
![](https://img.haomeiwen.com/i11387429/aa13df3d7e3869a8.png)
save方法的执行流程:
首先,回顾一下保存操作实现的代码:
public void save(User u) {
// 创建hibernate的配置对象
Configuration conf = new Configuration();
// 加载hibernate的配置文件
conf.configure("/hibernate.cfg.xml");
// 创建SessionFactory对象:可理解为一个连接池对象
SessionFactory factory = conf.buildSessionFactory();
// 创建Session对象:可理解为一个连接对象
Session session = factory.openSession();
// 获取事务管理对象
Transaction transaction = session.getTransaction();
// 开启事务
transaction.begin();
// 调用session的save方法完成数据的保存操作
session.save(u);
// 提交事务
transaction.commit();
// 释放资源
session.close();
}
执行流程分析:
- 创建Configuration对象,加载Hibernate.cfg.xml和Xxx.hbm.xml文件
- 通过加载的配置文件中的信息,创建SessionFactory对象,该对象相当于一个连接池(DataSource)对象
- 从SessionFactory工厂中获取Session对象,该对象相当于一个连接(Connection)对象
- 获取事务,并开启事务,将增删改的操作放在一个事务空间中
- 调用save方法,将需要保存的数据传入该方法
- Hibernate需要为我们拼接出保存的SQL语句:
insert into user (username, password, age, hiredate) values (?, ?, ?, ?) - 使用反射,获取到传入user对象的类型名称(User),然后将名称首字母小写(user),作为SQL中需要的表名
- 使用内省机制,获取到对象中的属性名称(uusername,upassword,uage,uhiredate),以及各个属性对应的属性值("admin","12345",10,"2017-01-01"),并根据映射文件中配置的属性和列的映射关系,找到每个属性对应的列名(username, password, age, hiredate),拼接到SQL中
- 得到以上数据后,Hibernate就能够为我们拼接出执行保存操作时需要的SQL语句了
- 创建PreparedStatement对象,将获取到的属性值设置给预编译语句对象
- 提交SQL到数据库中,进行预编译的处理
- Hibernate需要为我们拼接出保存的SQL语句:
- 提交事务,在数据库中执行保存的sql,将数据保存到数据库中
7.释放资源
![](https://img.haomeiwen.com/i11387429/b79b435392391e46.png)
通过以上我们对保存的执行流程的分析得知,Hibernate要自动的为我们生成对应的sql语句,映射文件的作用也就显现出来了,我们可以通过映射中的配置,可以获取到当前类对应的表名, 当前类中属性对应的列名,在使用内省机制,可以获取到对应的属性名,最后生成sql,执行sql
get方法的执行流程
接下来,我们在使用相同的方式来分析一下get方法的执行流程
代码如下:
@Override
public User get(long id) {
// 创建hibernate的配置对象
Configuration conf = new Configuration();
// 加载hibernate的配置文件
conf.configure("/hibernate.cfg.xml");
// 创建SessionFactory对象:可理解为一个连接池对象
SessionFactory factory = conf.buildSessionFactory();
// 创建Session对象:可理解为一个连接对象
Session session = factory.openSession();
// 调用session的delete方法完成数据的删除操作
User user = session.get(User.class, id);
// 释放资源
session.close();
return user;
}
执行流程分析:
session.delete(u);
- 调用get方法前后的步骤和上面基本一致(查询不需要放在事务中),这里不再赘述
- 调用get方法执行查询单条数据的操作
- Hibernate为我们生成的SQL:
select
user0_.id as id1_0_0_, user0_.username as username2_0_0_, user0_.password as password3_0_0_, user0_.age as age4_0_0_, user0_.hiredate as hiredate5_0_0_
from
user user0_
where
user0_.id=? - sql中需要的列名和表名和上面的获取方式一样
- Hibernate的get方法是针对根据主键查询设计的查询操作,所以在sql需要拼接主键相关的条件
- 在映射文件中可以获取到该表的主键列名和属性名,到这里sql拼接就完成了(Hibernate为每个列生成了别名, 这里不需要太过在意)
-
根据内省机制获取到主键属性的值,设置给sql,并执行sql
get方法的执行流程分析
- Hibernate为我们生成的SQL:
到此,我们通过分析save和get方法的执行流程,希望可以通过这一节能够帮助大家对Hibernate中的常用持久化方法的执行流程及原理的理解更加的深刻
小结
Hibernate是面向对象的持久层框架, 为开发人员屏蔽关系型数据库中的细节操作,所以,需要执行的sql语句都是自动生成的, 那么在生成sql的时候, 需要我们开发人员通过配置的方式告知必需的数据,如:表名,列名,执行sql需要的参数等等,一旦了解到这一点之后, 我们会对在使用Hibernate的过程中做的各种配置就会有更加深刻的理解.
![](https://img.haomeiwen.com/i807144/51c846821bc56b4c.jpeg)