美文网首页
十、Hibernate初体验

十、Hibernate初体验

作者: 肖sir_嘉立老师 | 来源:发表于2018-11-09 11:47 被阅读0次

Hibernate是持久层的ORM映射框架,专注于数据的持久化工作。所谓的持久化,就是将内存中的数据永久存储到关系型数据库中。

  • 主要知识点:
    一、什么是Hibernate?
    二、如何使用Hibernate?
    三、Hibernate的执行过程?如何调用?
    四、第一个Hibernate程序

一、什么是Hibernate?

Hibernate是一个开放源代码的ORM框架,它对JDBC进行了轻量级的对象封装,使得Java开发人员可以使用面向对象的编程思想来操作数据库。

ORM:就是利用Java对象与数据库表之间的映射的元数据,实现自动把Java对象持久化到关系型数据库的表中。

ORM原理图

其中,Hibernate框架具有一下优点:
1.对JDBC做了轻量级封装,简化了持久层的代码重复性。
2.是一个优秀的ORM实现,简化了DAO层编码工作。
3.使用Java的反射机制并实现透明性。
4.支持关系型数据库,从一对一到多对多的各种复杂关系。
5.可扩展性强,当功能不够用时,可以自行编码进行扩展。

二、如何使用Hibernate?

步骤1:引入Java包

Hibernate跟Struts一样,都是一套框架,也就是别人已经写好封装好的Java代码。因此,我们要使用Hibernate,就必须引入Hibernate的Jar包。
同理,Jar包统一存放于WEB-INF/lib中。

  • 主要的Jar包如下:
    § dom4j(必需):Hibernate在解析XML配置和XML映像元文件时需要使用dom4j。
    § CGLIB(必需):Hibernate在运行时使用这个代码生成库强化类(与Java反射机制联合使用)。
    § Commons Collections, Commons Logging(必需):Hibernat使用Apache Jakarta Commons项目提供的多个工具类库。
    § ODMG4(必需):Hibernate提供了一个可选的ODMG兼容持久化管理界面。如果你需要映像集合,你就需要这个类库,就算你不是为了使用ODMG API。
    § EHCache(必需):Hibernate可以使用不同的第二级Cache方案。如果没有修改配置的话,EHCache提供默认的Cache。
    § Log4j(可选):Hibernate使用Commons Logging API,后者可以使用Log4j作为底层实施log的机制。如果上下文类目录中存在Log4j库,Commons Logging就会使用Log4j和它在上下文类路径中找到的log4j.properties文件。

步骤2:创建实体类(持久化类)

关系型数据库中的表数据要映射成Java对象,必须要有一个对应的与关系表结构一样的实体类,用于存放数据库中取出来的结构化数据。

  • 其中,持久化类的编写应该遵循以下规则:
    1.持久化类中必须提供无参数public构造器
    2.所有属性使用private修饰并提供setter和getter方法
    3.必须提供标识OID,与数据库表的主键对应
    4.持久化类属性应尽量使用基本数据类型对应的包装类型
    5.持久化类不要使用final修饰,否则将无法产生代理对象

步骤3:创建实体类对应的Hibernate映射文件

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="XXX" table="xxx">
               <id name="id" column="id"> 
            <generator class="native"/>
               </id>
               <property name="XXX" column="xxx" type="string" />
   </class>
</hibernate-mapping>

步骤4:Hibernate全局配置文件

同时,跟Struts一样,框架本身需要一个全局配置文件,用于记录调用框架时所需的相关配置信息,例如:数据库服务器地址、数据库名称、数据库管理员账号、密码等。

<?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>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">itcast</property>    
    <property name="hibernate.show_sql">true</property>
    <property name="format_sql">true</property> 
    <mapping resource="cn/demo/domain/Student.hbm.xml" />
 </session-factory>
</hibernate-configuration>

三、Hibernate的执行过程?如何调用?

在Hibernate执行过程中通常会用到5个核心接口,分别为:Configuration接口、SessionFactory接口、Session接口、Transaction接口和Query接口。通过调用这些Hibernate所提供的接口,我们可实现以下调用执行过程:


[Hibernate执行过程.png]

1.Configuration接口

Configuration实例主要用于启动、加载、管理Hibernate的配置文件信息。

//方法一、默认加载src下的hibernate.cfg.xml配置文件
Configuration config = new Configuration().configure();
//方法二、指定路径下加载hibernate.cfg.xml配置文件
Configuration config = new Configuration().configure("xml文件位置");
//方法三、默认加载src目录下hibernate.properties配置文件
Configuration config = new Configuration();

2.SessionFactory接口

SessionFactory接口,负责Hibernate的初始化和建立Session对象。它在Hibernate中起到一个缓冲区作用,Hibernate可以将自动生成的SQL语句、映射数据以及某些可重复利用的的数据放在这个缓冲区中。同时它还保存了对数据库配置的所有映射关系,维护了当前的二级缓存。

  • 通常SessionFactory接口会与Configuration实例一起使用,二者结合封装成一个HibernateUtils的工具类
public class HibernateUtils {
    private static final Configuration config;
    private static final SessionFactory factory;
    static {
        config = new Configuration().configure();
        factory = config.buildSessionFactory();
    }
    public static Session getSession() {
        return factory.openSession();
    }
}

3.Session接口

Session 是应用程序与数据库之间交互操作的一个单线程对象,它的主要功能是为持久化对象提供创建、读取和删除的能力,所有持久化对象必须在session的管理下才可以进行持久化操作。

Session session = sessionFactory.openSession();
Session session = sessionFactory.getCurrentSession();
  • 在Session中提供了大量的常用方法,具体如下:
    (1)save()、update() 和saveOrUpdate()方法:用于增加和修改对象。
    (2)delete()方法:用于删除对象。
    (3)get()和load()方法:根据主键查询。
    (4)createQuery() 和createSQLQuery()方法:用于数据库操作对象。
    (5)createCriteria()方法:条件查询。

4.Transaction接口

Transaction接口主要用于管理事务,它是Hibernate的数据库事务接口,且对底层的事务接口进行了封装。Transaction接口的事务对象是通过Session对象开启的。

Transaction transaction = session.beginTransaction();

调用后,Session执行完数据库操作后,要使用Transaction接口的commit()方法进行事务提交,才能真正的将数据操作同步到数据库中。发生异常时,需要使用rollback()方法进行事务回滚,以避免数据发生错误。因此,在持久化操作后,必须调用Transaction接口的commit()方法和rollback()方法。如果没有开启事务,那么每个Session的操作,都相当于一个独立的操作。

5.Query接口

Query代表面向对象的一个Hibernate查询操作。在Hibernate中,通常使用session.createQuery()方法接受一个HQL语句,然后调用Query的list()或uniqueResult()方法执行查询。所谓的HQL是Hibernate Query Language缩写,其语法很像SQL语法,但它是完全面向对象的。

  • 在Hibernate中使用Query对象的步骤,具体所示:
    (1)获得Hibernate Session对象。
    (2)编写HQL语句。
    (3)调用session.createQuery 创建查询对象。
    (4)如果HQL语句包含参数,调用Query的setXxx设置参数。
    (5)调用Query对象的list() 或uniqueResult() 方法执行查询

6.Criteria接口

Criteria是一个完全面向对象,可扩展的条件查询API,通过它完全不需要考虑数据库底层如何实现,以及SQL语句如何编写,它是Hibernate框架的核心查询对象。Criteria 查询,又称为QBC查询(Query By Criteria),它是Hibernate的另一种对象检索方式。

  • 通常,使用Criteria对象查询数据的主要步骤,具体如下:
    (1)获得Hibernate的Session对象。
    (2)通过Session获得Criteria对象。
    (3)使用Restrictions的静态方法创建Criterion条件对象。
    (4)向Criteria对象中添加Criterion 查询条件。
    (5)执行Criterita的 list() 或uniqueResult() 获得结果。

四、第一个Hibernate程序

1.引入Hibernate的Jar包

引入Hibernate必须的Jar包

2.hibernate.cfg.xml

新建Hibernate框架的全局配置文件,用于存放数据库连接字符串等数据库配置信息。

<?xml version="1.0" encoding="UTF-8"?>
<!-- 配制文件的dtd信息 -->
<!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="hibernate.dialect">
            org.hibernate.dialect.MySQLDialect
        </property>
        <!--数据库驱动 -->
        <property name="hibernate.connection.driver_class">
            com.mysql.jdbc.Driver
        </property>
        <!--连接数据库的url -->
        <property name="hibernate.connection.url">
            jdbc:mysql:///hibernatedemo
         </property>
        <!--数据库的用户名 -->
        <property name="hibernate.connection.username">
            root
        </property>
        <!--数据库的密码 -->
        <property name="hibernate.connection.password">
            root
        </property>
        <!--其它配置 -->
        <!-- 显示sql语句 -->
        <property name="hibernate.show_sql">true</property>
        <!-- 格式化sql语句 -->
        <property name="format_sql">true</property>
        <!--自动建表 -->
        <property name="hibernate.hbm2ddl.auto">update</property>
        <!-- 用来关联hbm配置文件,把所有的实体类映射文件注册进来 -->
        <mapping resource="cn/demo/entity/Student.hbm.xml" />
    </session-factory>
</hibernate-configuration>

3.Student.java(实体类)

在src下创建cn.demo.entity包,并在里面创建与数据库表一一对应的映射实体类,用于存放从数据库中取出来的记录。

package cn.demo.entity;

public class Student {
    private Integer id; //id
    private String name; //学生名称
    private String pwd; //登录密码
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + ", pwd=" + pwd + "]";
    }
}

4.Student.hbm.xml

在实体类所在的路径下,创建一个实体类的Hibernate映射文件,用于告诉Hibernate框架Java对象与数据表中字段的映射关系。

<?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="cn.demo.entity.Student" table="student">
        <id name="id" column="id" type="int">
            <generator class="native" />
        </id>
        <property name="name"/>
        <property name="pwd" />
    </class>
</hibernate-mapping>

到此,Hibernate框架配置完毕。

5.HibernateUtils工具类

由上面介绍的Hibernate执行过程可知,Configuration和SessionFactory每次数据库操作时都会被实例化访问,因此我们把他们抽取出来,封装成为一个HibernateUtils的工具类,以便调用时不用每次都写那么多代码。
在src下新建cn.demo.utils包,在包中新建HibernateUtils类

package cn.demo.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtils {
    private static final Configuration config;
    private static final SessionFactory factory;
    static {
        config = new Configuration().configure();
        factory = config.buildSessionFactory();
    }
    // 获取Session
    public static Session getSession() {
        return factory.openSession();
    }
}

6.StudentTest类(测试类)

为了测试当前ORM是否生效,我们新建了一个cn.demo.test的包,用于存放对数据库操作的单元测试实例。并在包中新建一个测试类

package cn.demo.test;

import org.hibernate.Session;
import org.junit.Test;
import cn.demo.entity.Student;
import cn.demo.utils.HibernateUtils;

public class StudentTest {
        @Test
        public void test() {
            // 1.得到session
            Session session = HibernateUtils.getSession();
            // 2.开启事务
            session.beginTransaction();
            // 3.操作
            Student s1 = new Student(); 

            s1.setName("eric");
            s1.setPwd("pwd123");
            session.save(s1); 
            // 4.提交事务
            session.getTransaction().commit();
            // 5.关闭资源
            session.close();
        }
}

其中,JUnit是一个进行单元测试的开源框架。@Test表示用于测试的方法的注解。
若报出Test cannot be resolved to the build path提示,则需要把鼠标移动到 @Test标签处,点击 Add JUnit4 library to the build path,程序会自动将JUnit4的支持包引入到本项目中。
只需点击执行的测试方法—右键—Run As—JUnit Test选项,即可运行单元测试。

单元测试结果截图

改进

我们可以在现有基础上,把针对实体类的操作再进行封装。
cn.demo.entity包存放的是实体类,例如:User.java
cn.demo.operation包存放的是实体对应的操作,例如:UserOperation.java

package cn.demo.operation;

import org.hibernate.Session;
import cn.demo.utils.HibernateUtils;
import cn.demo.entity.User;

public class UserOperation {
    //操作:插入一个用户操作
    public static void InsertUser(User user){
        Session session = HibernateUtils.getSession();
        session.beginTransaction();
        session.save(user);
        session.getTransaction().commit();
        session.close();
        
    }
    //查询一个用户……
    //删除一个用户……
    //更新一个用户……
    //查询符合条件的用户集合……
}

作者: 肖sir@ZHBIT
2018 年 09月 27日


相关文章

网友评论

      本文标题:十、Hibernate初体验

      本文链接:https://www.haomeiwen.com/subject/nmlnxqtx.html