Hibernate-ORM框架基础

对象保存在内存中,内存不能永久保存数据,如果要永久保存就需要对象持久化(将对象存储到数据库中).
关系型数据库存放关系型数据,它是非面向对象的,对象和关系数据都是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据.
内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联,继承关系等
因此,把对象持久化到关系数据库中,需要进行对象-关系的映射(Object Relation Mapping)即ORM

持久化为什么不使用JDBC?

  • JDBC是java中最原始和最直接的访问关系型数卡的方式
  • JDBC优点是运行效率高
  • JDBC缺点是java程序中嵌入大量sql语句,使得项目难以维护
  • 如果关系型数据库关系很复杂,业务逻辑很混乱,那么使用JDBC编程实现持久化需要更专业的知识(比如:缓存机制,日志等)

hibernate API分类

  • 提供访问数据库(增删改查)的接口( Session, Transaction, Query )
  • 配置Hibernate接口:Configuration
  • 使应用程序拦截Hibernate内部发生的事情,不做出反应,这些接口包括:Interceptor, LoadEventListener, SaveEventListener等
  • 扩展Hibernate功能的接口,UserType, CompositeUserType, IndentiFierGenerator等,如有需要应用程序可以扩展这些接口;
  • hibernate内部封装了JDBC, JTA, JNDI, 其中JTA和JNDI使hibernate能够和JavaEE应用服务器集成;

hibernate核心接口

  • Configuration接口:
    Configuration对象用于配置, 启动hibernate ,
    hibernatey应用通过Configuration对象获取对象-关系映射文件中元数据库,以及动态配置hibernate属性;创建SessionFactory对象
  • SessionFactory接口 :
    • 初始化Hibernate, 创建Session对象
    • 是线程安全的,意味着同一个实例可以被多个线程共享;
    • 重量级的,不能随意创建和销毁他的实例,如果应用只访问一个数据库,只需要创建一个SessionFactorys实例;
  • 如果同时访问多个数据库,则需要为每个数据库创建单独的一个SessionFactorys实例.
  • SessionFactory之所以是重量级别的,是因为它需要一个较大的缓存,用来存放预定义的sql语句以及映射元数据等.我们还可以为SessionFactory配置一个缓存插件,该插件叫做Hibernate的第二级缓存,该缓存用来存放被工作单元读过的数据,将来其他工作单元可能会重用这些数据,因此这个缓存中的数据可以被所有工作单元共享,一个工作单元通常对应一个数据库事务;
  • Session接口:
  • 负责增,删,改,加载/查对象
  • 也称为持久化管理器
  • 和HttpSession没有任何关系
  • 不是线程安全的,因此在使用过程中应避免多个线程共享同一个session实例
  • 轻量级的,创建和销毁不会销毁太多资源,意味着程序中可以经常创建和销毁Session实例;
  • Session有一个缓存,被称为Hibernate的第一级缓存,存放的是当前工作单元加载的对象,每个Session实例都有自己的缓存,该缓存只能被当前工作单元访问;
  • Transaction接口:管理事务
  • Query和Cirteria接口:
  • 执行复杂数据库查询;
  • Query包装了HQL查询语句,与Sql相似,但是HQL查询是面向对象的,它引用类名以及属名,而不是表名和字段名;
  • Criteria接口封装了基于字符串的查询语句,比query接口更加面向对象,Criteria接口擅长进行动态查询;
Hibernate-ORM框架基础_第1张图片
Paste_Image.png

事务处理接口

当程序通过Hibernate来加载,保存,更新,删除对象时,会触发Hibernate拦截器以及事件监听器做处理;

映射类型接口

org.hibernate.type.Type接口表示将域对象数据类型映射为数据库的关系数据,Hiberate为Type实现了各种实现类,比如:InterType, FloatType等

可扩展的接口

Hibernate-ORM框架基础_第2张图片
Paste_Image.png

一.hibernate功能

  • hibernate是开源的
  • ORM映射
  • 是java领域的一款开源的ORM框架技术
  • 对JDBC进行了非常轻量级的对象封装
  • 是业务逻辑和数据库中间的持久化层( 中间件 )
  • 数据查询和缓存
  • 可以应用在独立的java程序和web应用中;
  • 可以和多种Web服务器,应用服务器良好集成
  • 支持几乎所有流行的数据库


    Hibernate-ORM框架基础_第3张图片
    Paste_Image.png
  • 点击查看练习代码

二.开发工具介绍以及安装

开发工具:Eclipse Standarg Kepler
Hibernate Tools for Eclipse Plugins
Hibernate Tools是JBoss公司推出的一个Eclipse综合开发工具插件,该插件可以简化ORM框架Hibernage, 以及JBoss Seam, EJB3等的开发工作,所以在Eclipse中安装Hibernate Tools之前要先确认Eclipse版本,在找对应的Hibernate Tools版本,我的eclipse版本是Eclipse Mars 4.5.2,以下是具体Hibernage Tools安装步骤,
参考文章

  • 点击Eclipse -> Help -> Eclipse Marketplace


    Hibernate-ORM框架基础_第4张图片
    Paste_Image.png
  • 在Find中输入Hibernate找到JBoos Tools,选中下一步后只把Hibernate Tools选中,然后安装,

  • 安装完毕后重启Eclipse,选择File->new->输入Hibernate,以下图片代表安装成功


    Hibernate-ORM框架基础_第5张图片
    Paste_Image.png

三.开发前准备

  • 导入Hibernate jar包
  • 首先要知道自己的Hibernate版本,我在eclipse目录下的plugins中找到的hiberate版本为org.hibernate.eclipse.console_5.0.1.Final-v20160331-1852-B88我的理解为5.0.1.Final,可以 点击下载
  • 下载后将hibernate-release-5.0.1.Final.zip解压,hibernate-release-5.0.1.Final/lib/required目录下就是我们要的Hibernate的jar包
  • 在eclipse中点击window -> Preferences-> java -> Build Path -> User Liberies -> New,输入hibernate-core(新建hibernate类库)确定.
  • 然后导入外部jar包,点击Add External Jars,找到hibernate-release-5.0.1.Final/lib/required下的所有jar包并导入
  • 导入junit4 jar包
  • 点击下载
  • 下载的包是junit-4.10.jar
  • 下载后,在eclipse中新建junit4类库,方式参考以上方式(区别就是junit只有一个jar包)
  • 导入mysql-connector-java-5.1.38.jar
    在eclipse中新建mysql-jdbc类库方式参考以上方式.

  • 在工程中导入我们以上创建的三个类库

  • 创建java project名为 hibernate-1
  • hibernate-1 右键 -> properties -> java Build Path -> Libraries -> Add Library -> User Library 将刚刚创建的三个类库选中,点击Finsh就可以成功导入了.
  • 导入工程成功的样子


    Hibernate-ORM框架基础_第6张图片
    Paste_Image.png

四.创建第一个Hibernate

  • 创建hibernate配置文档
    src-> New -> other -> Hibernate -> cfg.xml


    Hibernate-ORM框架基础_第7张图片
    Paste_Image.png
  • 创建持久化类( 实体类 )Students
    javaBeans类创建原则:

    • 类必须是公有的
    • 提供公有的不带参数的默认的构造方法
    • 属性私有
    • 属性setter/getter封装
  • 创建关系对象映射文件(该文件是做数据库字段和实体类属性映射所用)
    src-> New -> other -> Hibernate -> hbm.xml


    Hibernate-ORM框架基础_第8张图片
    Paste_Image.png

    点击下一步找到我们刚才建立的实体类(Student)


    Hibernate-ORM框架基础_第9张图片
    Paste_Image.png

    最后Finsh完成;
  • 使用junit单元测试
    注解小执行方法的顺序为:

    • 1.@Before: 初始化方法
    • 2.@Test : 测试方法
    • 3.@After : 释放资源
      建立测试项目:在Hibernate-1项目名右击 -> New -> Source Folder ->输入Test,在该目录下创建StudentsTest类:
package firstTest;
import java.util.Date;
import javax.print.attribute.standard.MediaPrintableArea;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import entity.Students;

/**
 * 测试类
 * @author lxf
 *
 */

public class StudentsTest {
    private SessionFactory sessionFactory;
    private Session session;
    private Transaction transaction;
    @Before
    //初始化配置
    public void init()
    {
        /*
         * 注意:我的hibernate是5.0和慕课网上讲的Hibernate4.2.4(就是4.0)两个版本的配置方法不一样
         */     
        //创建服务注册对象
        //如果.cfg.xml取了其他的名字,要改为.configure("名字.cfg.xml")
        StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
        //创建会话工厂对象
         sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();       
         //创建会话对象
         session = sessionFactory.openSession();
        //开启事务
         transaction = session.beginTransaction();      
    }
    
    @Test
    //真实的单元测试
    public void testSaveStudent()
    {
        Students st = new Students(1,"张三丰", "nan", new Date(), "wds");
        //保存对象进入数据库
        session.save(st);   
    }
    
    @After
    //释放资源
    public void destroy()
    {
        //提交事务
        transaction.commit();
        //关闭会话
        session.close();
        //关闭会话工厂
        sessionFactory.close(); 
    }
}

在StudentsTest.java右键Run as -> Junit Test执行,程序执行testSaveStudent罗辑,判断数据库hibernate中是否有students表,如果有则删除,没有则创建,然后将new Students(1,"张三丰", "nan", new Date(), "wds");对象属性insert到数据库的字段中;

五.Hibernate常用配置

  • hibernate.cfg.xml常用配置


    Hibernate-ORM框架基础_第10张图片
    Paste_Image.png
  • Hibernate执行流程


    Hibernate-ORM框架基础_第11张图片
    Paste_Image.png
  • transaction简介

  • hibernate对数据库的操作都是封装在事务中,并且默认是非自动提交的方式,所以用session保存对象时,如果不开启事务,并且手工提交事务,对象并不会真正保存到数据库中;
  • 如果想让hibernate自动提交事务,必须调用session.doWork()方法获取jdbc的connection后,设置为自动提交,(不推荐使用
    @Test
    //真实的单元测试
    public void testSaveStudent()
    {
        Students st = new Students(1,"张三丰", "nan", new Date(), "wds");
        session.doWork(new Work(){
            @Override
            public void execute(Connection connection) throws SQLException {
                // TODO Auto-generated method stub
                //开启关系型数据库的自动提交
                connection.setAutoCommit(true);
            }   
        });
        //保存对象进入数据库
        session.save(st);   
        session.flush();
    }
  • session简介
  • Hibernate是对JDBC的一个封装,所以不建议使用jdbc的connection操作数据库,而是通过使用session操作数据库;
  • 可以session就是操作数据库的对象
  • session与connection是多对一的关系,每个session都有一个与之对应的connection, 一个connection不同时刻可以提供多个session使用;
  • 所以想把对象保存在关系型数据库中需要调用session的各种方法,如:save(), update(), delete(), createQuery()等等;
  • 如果获取session对象的两种方式

    • (1). sessionFactory.openSession()
    • (2). sessionFactory.getCurrentSession()


      Hibernate-ORM框架基础_第12张图片
      Paste_Image.png
  • openSession 和getCurrentSession区别

  • openSession每次创建新的session对象, 而getCurrentSession使用现有的session对象(单例模式)
  • getCurrentSession对象在事务提交或回滚后自动关闭,而openSession需要手动关闭,(如果使用openSession没有手动关闭,则会导致连接池溢出)
  • 对象关系配置文档hbm常用配置
    参考文章

  • 单表映射

  • 基本类型


    Hibernate-ORM框架基础_第13张图片
    Paste_Image.png
  • 日期类型


    Hibernate-ORM框架基础_第14张图片
    Paste_Image.png
  • 对象类型


    Hibernate-ORM框架基础_第15张图片
    Paste_Image.png
  • 组件属性


    Hibernate-ORM框架基础_第16张图片
    Paste_Image.png
  • 单表CURD操作
  • 获取单条数据有session.get()和session.load()
  • get和load区别是:
    (1) 在不考虑缓存的情况下,get方法会在调用之后立刻向数据库发出sql语句,返回持久化对象;
    (2)而load方法会在调用后返回一个代理对象,该代理对象只保存实体对象的id,直到使用对象的非主键属性时菜会发出sql语句查询数据库;
    (3)查询数据库中不存在的数据库时,get方法返回null,而load方法则会抛出异常:org.hibernate.ObjectNotFoundException

你可能感兴趣的:(Hibernate-ORM框架基础)