美文网首页
Hibernate-ORM框架基础

Hibernate-ORM框架基础

作者: liangxifeng833 | 来源:发表于2017-03-03 11:48 被阅读773次

    对象保存在内存中,内存不能永久保存数据,如果要永久保存就需要对象持久化(将对象存储到数据库中).
    关系型数据库存放关系型数据,它是非面向对象的,对象和关系数据都是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据.
    内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联,继承关系等
    因此,把对象持久化到关系数据库中,需要进行对象-关系的映射(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接口擅长进行动态查询;
    Paste_Image.png

    事务处理接口

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

    映射类型接口

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

    可扩展的接口

    Paste_Image.png

    一.hibernate功能

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


      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


      Paste_Image.png
    • 在Find中输入Hibernate找到JBoos Tools,选中下一步后只把Hibernate Tools选中,然后安装,

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


      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就可以成功导入了.
    • 导入工程成功的样子


      Paste_Image.png

    四.创建第一个Hibernate

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


      Paste_Image.png
    • 创建持久化类( 实体类 )Students
      javaBeans类创建原则:

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


      Paste_Image.png

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


      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常用配置


      Paste_Image.png
    • Hibernate执行流程


      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()


        Paste_Image.png
    • openSession 和getCurrentSession区别

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

    • 单表映射

    • 基本类型


      Paste_Image.png
    • 日期类型


      Paste_Image.png
    • 对象类型


      Paste_Image.png
    • 组件属性


      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框架基础

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