java学习——Hibernate

Hibernate是什么

Hibernate是java三大框架之一,是用于Dao的框架也就是持久层,它是一个开源的ORM框架(ORM:Object Relational Mapping,对象关系映射),它对JDBC进行了轻量级的封装使得java开发人员使用面向对象的编程思想来操作数据库,它将POJO与数据表建立映射关系,可以自动生成sql语句,自动执行。

为什么要用

使用面向对象来操作数据库可以简化代码量便于更改和维护,提高工作效率,我们可以看一个代码的例子来对比一下

public int addProduct(Product productParameter) throws SQLException {
        //使用传统JDBC操作数据库
        QueryRunner queryRunner = new QueryRunner(C3p0Untils.getDataSources());
        String sql = "insert into product(pname,market_price,shop_price,pimage,is_hot,pdesc,cid) values(?,?,?,?,?,?,?)";
        Object[] params = {productParameter.getPname(),
                productParameter.getMarket_price(),
                productParameter.getShop_price(),
                productParameter.getPimage(),
                productParameter.getIs_hot(),
                productParameter.getPdesc(),
                productParameter.getCid()};
        int result = queryRunner.update(sql,params);
        //使用Hibernate操作数据库
        Configuration cfg = new Configuration().configure();
        SessionFactory sessionFactory = cfg.buildSessionFactory();
        Session session = sessionFactory.openSession();
        result = (int) session.save(productParameter);
        return result;
    }

可以看到传统的JDBC需要使用大量的getset语句,重复工作量大,如果数据表里有十几个字段,那么一个一个写会很麻烦,如果使用Hibernater直接使用save(JavaBean对象)的方式,而查找,更改,删除的方式类似,都很简单。

Hibernate的优势

  • Hibernate对JDBC访问数据库的代码做了轻量级的封装,大大的简化了数据访问层重复性的代码,并且减少了内存消耗,加快了运行效率。
  • Hibernate是一个基于JDBC的主流化框架,是一个优秀的ORM实现,它很大程度的简化了DAO层编码工作。
  • Hibernate的性能非常好,映射的灵活性非常好,它支持很多关系数据库,从一对一到多对多的各种复杂关系。
  • 可扩展性强,由于代码的开源以及API的开放,当本身功能不够用时,可以自行编码进行扩展。

Hibernate网上的教学资料很多,查查怎么配置映射和核心文件,还有函数怎么用,就可以开发了,而重要的是理解它的原理。

工作原理

持久化对象的三种状态:

1.瞬时态(transient)

         瞬时态也称为临时态或者自由态,瞬时态的实例是用new命令创建、开辟内存空间的对象,不存在持久化标识OID(相当于主键值),尚未与Hibernate Session 关联,在数据库中也没有记录,失去引用后将被JVM回收。瞬时状态的对象在内存中是孤立存在的,在数据库中的数据无任何关联,仅是一个信息携带的载体。

2.持久态(persistent)

          持久态的对象存在持久化表示OID,加入到了Session缓存中,并且相关联的Session没有关闭,在数据库中有对应的记录,每条记录只对应唯一的持久化对象,需要注意的是,持久态对象是在食物还未提交前变成持久态的

3.脱管态(detached)

           脱管态也称离线或者游离态,当某个持久化状态的实例与Session的关联被关闭时就变成了脱管态。脱管对象存在持久化标识OID,并且仍然与数据库中的数据存在关联,只是失去了与当前Session的关联,脱管状态对象发生改变时Hibernate不能检测到。

public void demo(){
        Session session = HibernateUntils.openSession();
        Transaction tx = session.beginTransaction();

        Product product = new Product(); //瞬时态对象,没有持久化标识OID,没有被session管理

        product.setPname("小米");

        Serializable id = session.save(product);//持久态对象:有持久化标识OID,被session管理

        tx.commit();
        session.close();

        System.out.println(product); //脱管态对象:有持久化标识OID,没有被session管理
    }

product对象由new关键字创建,此时还未与Session进行关联,它的状态称为瞬时态;在执行了session.save(product)操作后,product对象纳入了session的管理范围,这时的product对象变成了持久态对象,此时Session的事务还没有被提交;程序执行完commit()操作并关闭了Session后,product对象与session的关联被关闭,此时product对象就变成了脱管态

三种状态之间的转换

三种状态的相互转换图里写的很清楚,理解三种状态对于理解Hibernate框架很有帮助。

另外说明一点特殊的,持久态对象可以能够自动更新数据库,也就是说不使用update()方法就可以自动更新数据库,之所以持久态对象可以自动更新是因为Hibernate的一级缓存功能

一级缓存

Hibernate的缓存分为一级缓存和二级缓存,这两级缓存都位于持久化层,存储的都是数据库数据的备份。其中第一级缓存为Hibernate的内置缓存,不能被卸载。Hibernate的一级缓存就是指Session缓存,Session缓存是一块内存空间,用来存放相互管理的java对象,在使用Hibernate查询对象的时候,首先会使用对象属性的OID值在Hibernate的一级缓存种进行查找,如果找到匹配OID值的对象,就直接将该对象从一级缓存种去除使用,不会再查询数据库;如果没有找到相同的OID,则会去数据库种查找相应数据。当从数据库种查询到所需数据时,该数据信息也会放置到一级缓存种。Hibernate的一级缓存的作用就是减少对数据库的访问次数。

举个例子,当我们第一次使用get方法时,hibernate会先查找session中有没有对应的数据也就是OID值匹配,而这时是没有的,于是就生成sql语句从数据库中查找,如果我们再次使用get方法查找同一条数据时,也是先查找session中对应的OID值匹配,这时因为session中有对应的数据,则直接从session中调取,我们可以差看控制台,会发现第二次get时没有生成sql语句显而易见的是,这种机制在对重复查找数据时会很大的加快运行速度。

public static void main(String args[]) {
        Session session = HibernateUntils.openSession();
        Transaction transaction = session.beginTransaction();
        Product product1 = session.get(Product.class, "1");
        Product product2 = session.get(Product.class, "1");
        System.out.println(product1);
        System.out.println(product2);
    }

根据控制台输出的结果可以看到,第二次get时并没有生成sql语句,而两条相同的数据都获取到了

一级缓存的内部结构

Hibernate向一级缓存放入数据时,同时复制衣服数据放入到Hibernate快照中,当使用commit()方法提交事务时,同时会清理Session的一级缓存,这时会使用OID判断一级缓存中的对象和快照中的对象是否一致,如果两个对象的属性发生变化则执行update语句,将缓存的内容同步到数据库,并更新快照,如果一致,则不执行update语句。快照的作用就是确保一级缓存中的数据和数据库中的数据一致。这个机制也就解释了为什么上面我们不执行update语句数据却更新了。

Hibernate其他的事务控制,隔离级别,相关操作之类的网上有很多资料可以查到,而这个框架实用的原因是它的机制和原理,所以剖析一下对使用很有帮助,而这也是我们最应该先关心的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值