Hibernate框架的工作原理

基于JPA、JDBC


本文内容基于Hibernate 5.2.17.Final版本。

1、连接数据库

1.1、加载数据源信息、对象和表的映射关系

通过Configuration类完成数据库连接的初始化操作,对应的示例代码实现如下:

Configuration configuration = new Configuration().configure();

其中Configuration类的configure方法默认加载资源目录(resource)下的配置文件,configure方法不传参数默认加载hibernate.cfg.xml该名称的文件,也可传入指定配置文件的名称。该方法的相关源码如下:

public Configuration configure() throws HibernateException {
	return this.configure("hibernate.cfg.xml");
}

public Configuration configure(String resource) throws HibernateException {
	this.standardServiceRegistryBuilder.configure(resource);
	this.properties.putAll(this.standardServiceRegistryBuilder.getSettings());
	return this;
}

hibernate.cfg.xml配置文件中,需要配置:

  • 数据库url
  • 数据库用户名
  • 数据库密码
  • 数据库连接使用的驱动类
  • 数据库的方言类
  • 对象和表的映射关系
    简单配置示例如下:
<?xml version="1.0" encoding="UTF-8"?>
<!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>
         <!--数据库url-->
        <property name="connection.url">jdbc:mysql://127.0.0.1:3306/db_test?useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=Asia/Shanghai</property>

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

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

        <!--数据库连接使用的驱动类-->
        <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>

        <!--数据库的方言类-->
        <property name="dialect">org.hibernate.dialect.MySQL57Dialect</property>

         <!--注解配置,对象和表的映射关系-->
        <mapping class="org.example.model.Book"></mapping>

        <!--xml配置,对象和表的映射关系-->
        <!--<mapping resource="org/example/model/Book.hbm.xml"></mapping>-->
    </session-factory>
</hibernate-configuration>

此处的注意点

  • url中如果需要符号“&”拼接参数,可能会报错,可用该符号的转义字符&amp;代替。
  • mapping标签配置对象表映射关系主要有两种方式:
    • resource属性:xml文件中通过标签配置表字段和类属性的映射关系
    • class属性:实体类中通过为类属性添加注解映射表字段

1.2、创建连接数据库的会话

先通过Cofiguration的实例获取SessionFactory对象实例,然后通过SessionFactory的API创建会话实例。

SessionFactory sessionFactory = configuration.buildSessionFactory();
1.2.1 openSession方法

该方法创建的会话实例,操作完成后需要调用close()方法进行手动关闭会话,线程不安全。

Session session = sessionFactory.openSession();
1.2.2 getCurrentSession方法

该方法创建的会话实例与当前线程绑定,要求必须开启事务,在事务提交或回滚后、线程结束后,自动关闭会话,线程安全。

Session session = sessionFactory.getCurrentSession();
1.2.3 openStatelessSession方法

该方法创建的会话实例,不会缓存实体的任何状态,适合批量操作时使用。

StatelessSession session = sessionFactory.openStatelessSession();

2、执行SQL

Hibernate底层封装了JDBC。

2.1 读写操作

Hibernate5提供三种执行SQL的方式:

  • Session API
  • Query API
  • Criteria API
2.1.1 Session API 执行SQL

支持增删改查操作。

Book book = new Book();
// 插入
session.save(book);
// 修改
session.update(book);
// 根据参数,执行插入或修改
session.saveOrUpdate(book);
// 删除
session.delete(book);
// 主键查询(立即加载)
session.get(book);
// 主键查询(延迟加载)
session.load(book);
2.1.2 Query API 执行SQL

Hibernate 提供HQL和原生SQL两种方式,均支持增删改查。

  • 插入
// HQL插入操作 (官方文档明确说明可以支持插入功能,部分玩家未get到其实现方式而以为不支持)
Query query = session.createQuery(
                "INSERT INTO Book (name, price) " +
                        "SELECT :name, :price FROM Book");
query.setParameter("name", "水浒传");
query.setParameter("price", 39.9);
query.executeUpdate();

// 原生SQL插入操作
NativeQuery<Book> query = session.createNativeQuery("INSERT INTO book (name,price) values(:name,:price)", Book.class);
query.setParameter("name", "西游记");
query.setParameter("price", 59.9);
query.executeUpdate();
  • 删除
// HQL删除操作
Query query = session.createQuery(
                "DELETE FROM Book WHERE id=:id" );
query.setParameter("id", 6L);
query.executeUpdate();

// 原生SQL删除操作
NativeQuery<Book> query = session.createNativeQuery("DELETE FROM book WHERE id=:id", Book.class);
query.setParameter("id", 9);
query.executeUpdate();
  • 修改
// HQL修改
Query query = session.createQuery(
                "UPDATE Book SET price=:price WHERE id=:id" );
query.setParameter("id", 7L);
query.setParameter("price", 29.9);
query.executeUpdate();

// 原生SQL修改操作
NativeQuery<Book> query = session.createNativeQuery("UPDATE book SET price=:price WHERE id=:id", Book.class);
query.setParameter("id", 10L);
query.setParameter("price", 69.9);
query.executeUpdate();
  • 查询
// HQL查询操作
Query query = session.createQuery(
                "FROM Book WHERE id=:id" );
query.setParameter("id", 7L);
List<Book> list = query.list();

// 原生SQL查询操作
NativeQuery<Book> query = session.createNativeQuery("SELECT * FROM book WHERE id=:id", Book.class);
query.setParameter("id", 10);
List<Book> list = query.list();
2.1.3 Criteria API 执行SQL

Criteria方式为HQL和原生SQL查询提供了一种类型安全的替代方法。
Criteria方式支持删改查操作,暂未看到支持插入操作。

  • 删除
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaDelete<Book> criteria = builder.createCriteriaDelete(Book.class);
Root<Book> root = criteria.from(Book.class);
criteria.where(builder.equal(root.<Long>get("id"), 7));
Query<Book> query = session.createQuery(criteria);
query.executeUpdate();
  • 修改
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaUpdate<Book> criteria = builder.createCriteriaUpdate(Book.class);
Root<Book> root = criteria.from(Book.class);
criteria.set("price", 59.5);
criteria.where(builder.equal(root.<Long>get("id"), 8));
Query<Book> query = session.createQuery(criteria);
query.executeUpdate();
  • 查询
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Book> criteria = builder.createQuery(Book.class);
Root<Book> root = criteria.from(Book.class);
criteria.where(builder.like(root.<String>get("name"), "%三%"));
Query<Book> query = session.createQuery(criteria);
List<Book> list = query.list();

2.2、缓存机制

  • 一级缓存(Session):单个会话内,会话结束、缓存清除。
  • 二级缓存(SessionFactory):所有会话共享,全局的缓存。

3、释放连接资源

session.flush();
session.clear();
session.close();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值