Hibernate框架学习笔记

1.Hibernate简述

Hibernate是一个对象关系映射框架,对JDBC进行轻量级的对象封装。其将POJO与数据库建立yin映射关系,是一个全自动的orm框架。Hibernate应用再任何使用JDBC的场合,既可以在java的客户端程序使用,也可以在Servlet/Jsp的web应用中使用。

1.1 orm框架

orm框架全称为Object-relative-mapping,即将对象和关系型的数据库通过映射的配置文件关联起来,则可达到操作该对象来操作数据库的目的( 利用对象编程来操作数据库)。
(1) O:面向对象领域的Object (JavaBean对象)
(2) R: 关系数据库领域的Relational (表的结构)
(3) M: 映射Mapping(Xml的配置)

1.2 Hibernate优点

(1)对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码
(2)轻量级的框架,支持大多数关系型数据库。

1.3 Hibernate的常用jar包
常用jar包
hibernate-jpa-2.1-api-1.0.0.Final.jarHibernate的标准jar包
hibernate-core-5.2.9.Final.jarHibernate的核心jar包
hibernate-commons-annotations-5.0.1.Final.jarHibernate的注解jar包

2. Hibernate的配置

2.1 Hibernate的配置文件

Hibernate的映射配置文件:

代码如下:

<?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="当前类的全路径" table="对应的表名">
        <!--配置id-->
        <id name="JavaBean的属性"  column="表结构的字段">
            <!--主键的生成策略,native表示采取本地的自增策略-->
            <generator class="native"/>
        </id>
        <property name="JavaBean的属性" colume="表结构字段" length="字段的数据长度,若不写则为默认" type="数据类型,例如java.lang.String。可不写">
        </property>
        <property name="JavaBean的属性" colume="表结构字段">
        </property>
        ...
    </class>
</hibernate-mapping>

Hibernate的核心配置文件:

?xml version="1.0" encoding="GBK"?>
<!-- 指定Hibernate配置文件的DTD信息 -->
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!--配置SessionFactory标签,一个数据库只对应一个SessionFactory>
   <session-factory>
      <!--配置Mysql数据库-->
      <!-- 指定连接数据库所用的驱动 -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <!-- 指定连接数据库的url,hibernate连接的数据库名 -->
        <property name="connection.url">jdbc:mysql://localhost/数据库名</property>
        <!-- 指定连接数据库的用户名 -->
        <property name="connection.username">数据库名</property>
        <!-- 指定连接数据库的密码 -->
        <property name="connection.password">数据库密码</property>
        <!-- 数据库Mysql方言 -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

      <!--可选的配置-->
      <!--控制台显示sql语句-->
       <property name="hibernate.show_sql">true/false</property>
      <!--控制台显示格式化后的sql语句-->
       <property name="hibernate.format_sql">true/false</property>
      <!--生成数据库的表结构,主要作为测试功能-->
       <property name="hibernate.hbm2ddl.auto">create</property>
      <!---->

      <!-- 导入映射配置文件  注意路径 “/-->
      <mapping resource="包路径/mapper配置文件名">
   </session-factory>
</hibernate-configuration>

2.2 Hibernate核心类和接口简述

Hibernate的API一共有6个,分别为:Session、SessionFactory、Transaction、Query、Criteria和Configuration。通过这些接口,可以对持久化对象进行存取、事务控制。

2.2.1SessionFactory

SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。这里用到了工厂模式。其里面缓存了增删改查的sql语句。

(1)一个项目通常只需要一个SessionFactory就够,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。
(2)SessionFactory是线程安全的

SessionFactory的内部组成图
在这里插入图片描述

SessionFactory特点

(1) 由Configuration通过加载配置文件创建该对象。

(2) SessionFactory对象中保存了当前的数据库配置信息和所有映射关系以及预定义的SQL语句。同时,SessionFactory还负责维护Hibernate的二级缓存。

(3)一个SessionFactory实例对应一个数据库,应用从该对象中获得Session实例。
(4)SessionFactory是线程安全的,意味着它的一个实例可以被应用的多个线程共享。
(5) SessionFactory是重量级的,意味着不能随意创建或销毁它的实例。如果只访问一个数据库,只需要创建一个SessionFactory实例,且在应用初始化的时候完成。

2.2.2 Session

        Session接口负责执行被持久化对象的CRUD操作(CRUD即为增删改查SQL语句)。但需要注意的是Session对象是非线程安全的。同时,Hibernate的session不同于JSP应用中的HttpSession。HttpSession对象称为用户session
         简而言之,Hibernate的Session对数据库进行增删改查的。Session共享一个SessionFactory。因为Session是线程不安全的,最好一次请求一个Session。

常用方法用法
save(obj)插入数据
delete(obj)删除数据
get(Class,id)通过主键来查询,查询对应的一条数据。第一个参数为JeanBean的class对象,第二个参数为主键值
update(obj)更新数据
saveOrUpdate(obj)保存或者修改(如果没有数据,保存数据。如果有,修改数据)
createQuery()HQL语句的查询的方式


除了查询操作,增删改都需要加事务。在修改和删除时,先对其进行查询再修改或删除。

2.2.3 Transaction接口

        Transaction 接口是对实际事务实现的一个抽象,这些实现包括JDBC的事务、JTA 中的UserTransaction、甚至可以是CORBA 事务。

常用方法用法
commit()提交事务
rollback()回滚事务
Transaction特点

(1)Hibernate框架默认情况下事务不自动提交.需要手动提交事务
(2)如果没有开启事务,那么每个Session的操作,都相当于一个独立的事务

2.2.4 底层实现
// 先加载配置文件
			Configuration config = new Configuration();
			// 默认加载src目录下的配置文件
			config.configure();
			// 创建SessionFactory对象
			SessionFactory factory = config.buildSessionFactory();
			// 创建session对象
			Session session = factory.openSession();
			// 开启事务
			Transaction tr = session.beginTransaction();
			// 编写保存代码
			Customer c = new Customer();
			// 保存客户
			session.save(c);
			// 提交事务
			tr.commit();
			// 释放资源
			session.close();
			factory.close();

3. Hibernate的持久化

3.1 持久化编写规则
  1. 提供一个无参数 public访问控制符的构造器。原因是:底层需要进行反射。
  2. 提供一个标识属性,映射数据表主键字段。唯一标识OID。数据库中通过主键,Java对象通过地址确定对象;持久化类通过唯一标识OID确定记录。
  3. 所有属性提供public访问控制符的 set或者get 方法
  4. 标识属性应尽量使用基本数据类型的包装类型
3.2 自然主键与代理主键的区别
自然主键

       对象本身的一个属性,创建一个人员表,每个人都有一个身份证号(唯一的)使用身份证号作为表的主键.。(开发中不会使用这种方式

代理主键

       不是对象本身的一个属性.创建一个人员表,为每个人员单独创建一个字段.用这个字段作为主键.代理主键.(开发中推荐使用这种方式

3.3 主键的生成策略
increment

适用于short,int,long作为主键.不是使用的数据库自动增长机制.
: Hibernate中提供的一种增长机制。不建议使用,并发时容易出问题。
        底层原理是:先进行查询 :select max(id) from user,再进行插入:获得最大值+1作为新的记录的主键。

identity

适用于short,int,long作为主键。但是这个必须使用在有自动增长数据库中,采用的是数据库底层的自动增长机制。
:底层使用的是数据库的自动增长(auto_increment).像Oracle数据库没有自动增长。

sequence

适用于short,int,long作为主键.底层使用的是序列的增长方式。
:Oracle数据库底层没有自动增长,想自动增长需要使用序列。

uuid

适用于char,varchar类型的作为主键。
:使用随机的字符串作为主键

native

本地策略.根据底层的数据库不同,自动选择适用于该种数据库的生成策略.(short,int,long)
:如果底层使用的MySQL数据库:相当于identity;如果底层使用Oracle数据库:相当于sequence。

assigned

主键的生成不用Hibernate管理了.必须手动设置主键。

4持久化对象

4.1 状态

Hibernate为了管理持久化类:将持久化类分成了三个状态。
(1) 瞬时态:Transient Object
(2) 持久态:Persistent Object
(3) 脱管态:Detached Object

状态有无持久化标识有无被session管理
瞬时态
持久态
脱管态
4.2 状态转换

在这里插入图片描述
持久态的对象,有自动更新数据库的能力。
       原因:Session的快照机制。

4.3 Session的一级缓存

       Session接口中,有一系列的java的集合,这些java集合构成了Session级别的缓存(一级缓存).将对象存入到一级缓存中,session没有结束生命周期,那么对象在session中存放着。
:内存中包含Session实例 --> Session的缓存(一些集合) --> 集合中包含的是缓存对象。
       缓存内存储的是对象的引用。
在这里插入图片描述

4.4 绑定本地Session

在这里插入图片描述
       JavaWEB的事务的时候,需要在业务层使用Connection来开启事务。一种是通过参数的方式传递下去,另一种是把Connection绑定到ThreadLocal对象中。
        Hibernate框架中,使用session对象开启事务,所以需要来传递session对象,框架提供了ThreadLocal的方式。

4.4.1 绑定本地Session的配置

业务层开事务步骤如下:
1.需要在hibernate.xml的配置文件中提供配置

<!--开启绑定本地的session-->
<property name="hibernate.current_session_context_class">thread</property>

2.使用SessionFactory的getCurrentSession()方法,获取当前的Session对象。并且该Session对象不用手动关闭,线程结束了,会自动关闭。

			public static Session getCurrentSession(){
				return factory.getCurrentSession();
			}

:想使用getCurrentSession()方法,必须要先配置才能使用

4.4.2 业务逻辑层+事务的原因

        若事务注解@Transactional加在dao层,那么只要与数据库做增删改,就要提交一次事务,事务的特性就发挥不出来.尤其是事务的一致性,当出现并发问题是,用户从数据库查到的数据都会有所偏差。
        将事务设置在业务逻辑上,只要一个业务逻辑出错或异常,则该事务就会回滚(所有的业务都会回到最初始的状态)。同时,一个事务则可参与多个业务的提交。

5.Hibernate框架查询方式

HQL语句

框架Hibernate独有的操作数据库数据的语言。
格式:
1.所有数据查询

session.createQuery("from Users ", Users.class).list();

2.条件查询(常用的)

session.createQuery("from Users where username=:username", Users.class).setParameter("username", username);

3.条件查询

Query query = session.createQuery("from Customer where name = ?");
query.setString(0, "李健");
List<Customer> list = query.list();
System.out.println(list);


(1)第一个参数为HQL语句,第二参数为JavaBean的class对象

Criteria查询接口(条件查询)

1.查询所有记录

Criteria criteria = session.createCriteria(Users.class);
List<Users> list = criteria.list();
System.out.println(list);

2.条件查询

Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.eq("name", "李健"));
List<Customer> list = criteria.list();
System.out.println(list);

3.条件查询

Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.eq("name", "李健"));
criteria.add(Restrictions.eq("age", 38));
List<Customer> list = criteria.list();
System.out.println(list);

5.配置一对多关系

多方的配置

<set name="多方的数据库表名">
<key column="多方的外键"/>
<one-to-many class="多方的JavaBean的全路径名"/>
</set>

一方的配置

<many-to-one name="一方的数据库表" class="一方对应的JavaBean的全路径名" column="多方的外键名"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值