Hibernate 入门

这里写图片描述

hibernate的运行过程:
首先,应用程序先调用Configration类,该类读取hibernate的配置文件及映射文件中的信息,并用这些信息生成一个SessionFactory对象,接着,从SessionFacctory对象生成一个Session对象,并用Session对象生成Transaction对象,可通过Session对象的get()、load()、sava()、update()、delete()和saveOrupdate()等方法对PO进行加载,保存,更新,删除等操作;在查询的情况下,可通过Session对象生成一个Query对象,然后利用Query对象执行查询操作,如果没有异常,Transaction对象将提交这些操作结果到数据库中。

Hibernate的优缺点

优点:
一、更加对象化
以对象化的思维操作数据库,我们只需要操作对象就可以了,开发更加对象化。
二、移植性
因为Hibernate做了持久层的封装,你就不知道数据库,你写的所有的代码都具有可复用性。
三、Hibernate是一个没有侵入性的框架,没有侵入性的框架我们称为轻量级框架。对比Struts的Action和ActionForm,都需要继承,离不开Struts。Hibernate不需要继承任何类,不需要实现任何接口。这样的对象叫POJO对象。测试更加方便,提高了效率。
缺点:
一、由于对持久层封装过于完整,导致开发人员无法对SQL进行优化,无法灵活使用JDBC的原生SQL,Hibernate封装了JDBC,所以没有JDBC直接访问数据库效率高。要使用数据库的特定优化机制的时候,不适合用Hibernate 
二、框架中使用ORM原则,导致配置过于复杂,一旦遇到大型项目,比如300张表以上,配置文件和内容是非常庞大的,另外,DTO满天飞,性能和维护问题随之而来
三、如果项目中各个表中关系复杂,表之间的关系很多,在很多地方把lazy都设置false,会导致数据查询和加载很慢,尤其是级联查询的时候。
四、Hibernate在批量数据处理时有弱势,对于批量的修改,删除,不适合用Hibernate,这也是ORM框架的弱点。接着,结合小编目前的项目,做一个简单的实例,来帮助我们更好的来理解hibernate。

Hibernate缓存

Hibernate一级缓存是Session缓存,利用好一级缓存就需要对Session的生命周期进行管理好。建议在一个Action操作中使用一个Session。一级缓存需要对Session进行严格管理。

Hibernate二级缓存是SessionFactory级的缓存。 SessionFactory的缓存分为内置缓存和外置缓存。
内置缓存中存放的是SessionFactory对象的一些集合属性包含的数据(映射元素据及预定SQL语句等),对于应用程序来说,它是只读的。
外置缓存中存放的是数据库数据的副本,其作用和一级缓存类似,二级缓存除了以内存作为存储介质外,还可以选用硬盘等外部存储设备。
二级缓存称为进程级缓存或SessionFactory级缓存,它可以被所有session共享,它的生命周期伴随着SessionFactory的生命周期存在和消亡。

import java.util.Date;    

import org.hibernate.Session;    
import org.hibernate.SessionFactory;    
import org.hibernate.cfg.Configuration;    

public class Client {    
    public static void main(String[]args){    
        //读取hibernate.cfg.xml文件    
        Configuration cfg = new Configuration().configure();    
        //建立SessionFactory    
        SessionFactory factory =cfg.buildSessionFactory();    

        //取得session    
        Session session = null;    

        try{    
            //开启session    
            session = factory.openSession();    
            //开启事务    
            session.beginTransaction();    

            User user = new User();    
            user.setName("jiuqiyuliang");    
            user.setPassword("123456");    
            user.setCreateTime(new Date());    
            user.setExpireTime(new Date());    
            //保存User对象    
            session.save(user);    

            //提交事务    
            session.getTransaction().commit();    

        }catch(Exception e){    
            e.printStackTrace();    
            //回滚事务    
            session.getTransaction().rollback();    
        }finally{    
            if(session != null){    
                if(session.isOpen()){    
                    //关闭session    
                    session.close();    
                }    
            }    
        }    
    }    
} 

Hibernate懒加载:

所谓懒加载(lazy)就是延时加载,延迟加载。
至于为什么要用懒加载呢,就是当我们要访问的数据量过大时,明显用缓存不太合适,因为内存容量有限 ,为了减少并发量,减少系统资源的消耗,
我们让数据在需要的时候才进行加载,这时我们就用到了懒加载。
比如部门ENTITY和员工ENTITY,部门与员工1对多,如果lazy设置为 false,那么只要加载了一个部门的po,就会根据一对多配置的关系把所有员工的po也加载出来。
但是实际上有时候只是需要用到部门的信息,不需要用到员工的信息,这时员工po的加载就等于浪费资源。如果lazy设置为true,那么只有当你访问部门po的员工信息时候才回去加载员工的po的信息。

三种状态
参考

这里写图片描述

自由状态 (Transient)
所谓的Transient状态,即实体对象在内存中自由存在,与数据库中的记录无关,通常是我们的J2EE中VO,并没有被纳入Hibernate的实体管理容器.

Test test =  new Test(); 
test.setName("energykk"); 
// 此时的test对象处于Transient(自由状态)并没有被Hibernate框架所管理 

持久化状态 (Persistent)
实体对象已经处于被Hibernate实体管理容器容器所管理的状态.这种状态下这个实体对象的引用将被纳入Hibernate实体管理容器容器所管理. 处于Persistent状态的实体对象,对它的变更也将被固化到数据库中. 在J2EE中通常指的是一个PO.

Transaction tr = session.beginTransaction(); 
session.save(test); 
// 此时的test对象已经处于Persistent(持久状态)它被Hibernate纳入实体管理容器 
tr.commit(); 
Transaction tr2 = session.beginTransaction(); 
test.setName("xukai"); 
// 在这个事务中我们并没有显示的调用save()方法但是由于Persistent状态的对象将会自动的固化到
// 数据库中,因此此时正处在Persistent状态的test对象的变化也将自动被同步到数据库中 
tr2.commit();

游离状态 (Detached)
处于Persistent状态的实体对象,其对应的session关闭以后,那么这个实体就处于Detached状态.
我们可以认为session对象就是一个Persistent的宿主,一旦这个宿主失效,那么这个实体就处于Detached状态.

session.close(); 
// 与test对象关联的session被关闭,因此此时的test对象进入Detached(游离状态) 
 session2 = HibernateSessionFactory.getSession(); 
Transaction tr3 = session2.beginTransaction(); 
session2.update(test); 
// 此时正处于Detached状态的test对象由于再次借助与session2被纳入到Hibernate的实体管理容器所以此时的
// test对象恢复到Persistent状态 
test.setName("jjjj"); 
tr3.commit(); 
session2.close();

差异就在于处于Transient状态的只有一个Name的属性.此时的test对象所包含的数据信息仅限于此,他与数据库中的记录没有任何瓜葛.
但是处于Detached状态的实体已经不止包含Name这个属性,还被赋予了主键也就是通常POJO里的id属性,由于id是主键,他可以确定数据库表中的一条
唯一的记录,那么自然的处于Detached状态的实体就能与数据库表中拥有相同id的记录相关联.

查看SQL语句

这里写图片描述

getCurrentSession()与openSession()的区别

  1. 采用getCurrentSession()创建的session会绑定到当前线程中,而采用openSession()
    创建的session则不会
  2. 采用getCurrentSession()创建的session在commit或rollback时会自动关闭,而采用openSession()
    创建的session必须手动关闭
package com.spring.base;

import java.util.List;

import org.hibernate.Session;

public interface BaseTemplate<T> {

    public T find(Class<T> clazz,Integer id);

    public List<T> findByHQL(String hql,Integer page,Integer rows);

    public List<T> findBySQL(String sql,Integer page,Integer rows);

    public void save(T t);

    public void update(T t);

    public void execHQL(String hql);

    public void execBySQL(String sql);

    public void saveOrUpdate(T t);

    public void delete(T t);

    public Session openSession();

    public Session getCurrentSession();

    public void close(Session session);

    public int countBySQL(String sql);

    public int countByHQL(String hql);

}
package com.spring.base;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;

public class BaseTemplateImpl<T> implements BaseTemplate<T> {

    @Autowired
    private SessionFactory sessionFactory = null;

    @Override
    public T find(Class<T> clazz, Integer id) {
        Session session = openSession();
        Transaction tx = session.beginTransaction();
        T t = (T) session.get(clazz, id);
        tx.commit();
        close(session);
        return t;
    }

    @Override
    public void save(T t) {
        Session session = openSession();
        Transaction tx = session.beginTransaction();
        session.save(t);
        tx.commit();
        close(session);
    }

    @Override
    public void update(T t) {
        Session session = openSession();
        Transaction tx = session.beginTransaction();
        session.update(t);
        tx.commit();
        close(session);
    }

    @Override
    public void saveOrUpdate(T t) {
        Session session = openSession();
        Transaction tx = session.beginTransaction();
        session.saveOrUpdate(t);
        tx.commit();
        close(session);
    }

    @Override
    public void delete(T t) {
        Session session = openSession();
        Transaction tx = session.beginTransaction();
        session.delete(t);
        tx.commit();
        close(session);
    }

    /**
     * 事务提交后自动关闭session
     */
    @Override
    public Session getCurrentSession() {
        return this.sessionFactory.getCurrentSession();
    }

    /**
     * openSession 需要 session 显式关闭
     */
    @Override
    public void close(Session session) {
        if (session.isOpen()) {
            session.clear();
            session.flush();
            session.close();
        }
    }

    @Override
    public Session openSession() {
        return this.sessionFactory.openSession();
    }

    @Override
    public List<T> findByHQL(String hql, Integer page, Integer rows) {
        Session session = openSession();
        Query query = session.createQuery(hql);
        if (page != null && rows != null && page > 0 && rows > 0) {
            query.setFirstResult((page - 1) * rows);
            query.setMaxResults(rows);
        }
        List<T> list = query.list();
        close(session);
        return list;
    }

    @Override
    public List<T> findBySQL(String sql, Integer page, Integer rows) {
        Session session = openSession();
        SQLQuery query = session.createSQLQuery(sql);
        if (page != null && rows != null && page > 0 && rows > 0) {
            query.setFirstResult((page - 1) * rows);
            query.setMaxResults(rows);
        }
        List<T> list = query.list();
        close(session);
        return list;
    }

    @Override
    public void execHQL(String hql) {
        Session session = openSession();
        Transaction tx = session.beginTransaction();
        (session.createQuery(hql)).executeUpdate();
        tx.commit();
        close(session);
    }

    @Override
    public void execBySQL(String sql) {
        Session session = openSession();
        Transaction tx = session.beginTransaction();
        (session.createSQLQuery(sql)).executeUpdate();
        tx.commit();
        close(session);
    }

    @Override
    public int countBySQL(String sql) {
        Session session = openSession();
        SQLQuery query = session.createSQLQuery(sql);
        int ans = ((Number) query.uniqueResult()).intValue();
        close(session);
        return ans;
    }

    @Override
    public int countByHQL(String hql) {
        Session session = openSession();
        Query query = session.createQuery(hql);
        int ans = ((Number) query.uniqueResult()).intValue();
        close(session);
        return ans;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值