Hibernate要点总结

1、什么是Hibernate

1)Hibernate是数据访问层的框架,对JDBC进行了封装,是针对数据访问层的面向对象的解决方案。

2)Hibernate允许我们直接访问对象,然后将访问自动转化为SQL去执行,从而达到间接访问数据库的目的,简化代码开发,提升开发效率。

2、为什么使用Hibernate

1)使用JDBC开发出现的问题

--需要在代码中写大量的SQL

--需要给大量的?赋值

--需要将结果集转换为实体对象

--在SQL中可能会写不同数据库特定的函数,移植性差。例如分页查询、主键生成方法、数据库函数等。

2)使用Hibernate可以解决上面的问题

--基本上不需要写SQL,因为Hibernate可以自动生成SQL并执行

--可以自动给?赋值

--可以自动将结果集转换为实体对象

--Hibernate提供通用的API来访问不同的数据库,移植性好。

3)补充JDBC与Hibernate的优缺点

a、JDBC优点:效率高

b、Hibernate缺点:效率相对于JDBC要低

*3、Hibernate的设计原理(思想)

1)Hibernate是采用了ORM的思想,对JDBC进行的封装。

2)ORM:Object Relation Mapping,即对象关系映射,指的是Java对象和关系数据库的映射。

Hibernate框架是ORM的一种实现,解决了对象和数据库数据映射问题。在数据库添加或更新时,可以将一个对象自动写入或更新数据表;查询时,可以将记录自动封装成对象返回。这些操作在中间执行时所涉及的细节开发者不用参与和关注。

--之前使用JDBC开发时,需要知道数据库表和实体对象的关系,以及字段和对象属性的关系,比如需要知道COST表和Cost对象的关系。那么这种关系我们之前是手动维护的,比如:

cost.setName(rs.getString("name"));

ps.setString(2,cost.getName());

--ORM思想是希望将这种关系的维护提炼出来,用一个公共的组件描述,那么在我们访问数据库时,需要使用这种关系时,可以复用基于ORM思想提炼出来的关系

--正是由于存在这样通用关系的描述,Hibernate才可以让我们直接访问Java对象,从而通过关系转换成SQL自动执行。

--Hibernate中将这种关系定义在XML配置文件中。

4、Hibernate体系结构

1)hibernate.cfg.xml(1个)

是Hibernate的主配置文件,用于配置数据库连接参数,以及Hibernate框架参数。

2)POJO实体类(n个)

是Java类型,用于封装表中的数据

3)xxx.hbm.xml(n个)

是关系映射文件,用于配置表与实体类的关系,以及表中字段与类中属性的关系。

4)Hibernate底层API

主要是用于解析主配置文件,以及关系映射文件,然后根据关系自动生成SQL并执行。

5、Hibernate常用API

1)Configuration

用于解析主配置文件的,同时也可以加载hbm.xml信息

2)SessionFactory

用于创建Session对象,对JDBC的connection对象的封装。

3)Session

是数据库连接会话,相当于是数据库连接。负责执行增删改操作,提供了save,update,delete等方法。

注意:此Session和HttpSession没有任何关系。

4)Transaction

用于控制事务。默认情况下,Hibernate不会自动提交,因此需要事务控制才能对数据库更新。

5)Query

用于做特殊查询(HQL)

*6、Hibernate使用步骤

1)导包(Hibernate开发包、数据库驱动包)

2)引入主配置文件hibernate.cfg.xml

3)创建实体类Emp

4)*创建关系映射文件Emp.hbm.xml

--该配置文件必须和实体类同名

--该配置文件必须和实体类位于同一个包下

--在主配置文件中引入该关系映射文件

5)使用Hibernate的API,来进行增、删、改、查

*7、Hibernate映射类型

1)Hibernate中支持2种映射类型

--Java类型

--Hibernate定义的类型

2)使用Java类型不能自动处理布尔值,如果想使用Java类型来处理,需要自己定义一个类型,该类型需要实现一个接口UserType

举例:创建类

com.*.type.MyBoolean implements UserType

在hbm.xml中,type="com.*.type.MyBoolean"

3)Hibernate定义的映射类型(推荐使用)

--整数:byte,short,integer,long

--小数:float,double

--字符:string

--日期(年月日):date

可以将数据库日期类型转换为java.sql.Date

--时间(时分秒):time

可以将数据库日期类型转换为java.sql.Time

--时间戳(年月日时分秒):timestamp

可以将数据库日期类型转换为java.sql.Timestamp

--布尔:

yes_no:数据库中存y/n,对应属性true/false

true_false:数据库中存t/f,对应属性true/false

使用:

type="timestamp"

注意:

Hibernate定义的映射类型都是小写的

8、Hibernate主键生成方式

Hibernate框架提供了多种主键生成方式,使用时,通过hbm.xml文件<id>元素部分,利用<generator class="主键生成类型">指定。

1)sequence

--是采用sequence来生成ID,针对的是Oracle数据库

--<generator class="sequence">

<param name="sequence">序列名</param>

</generator>

2)identity

--采用数据库主键自增长的机制来生成ID,针对初Oracle外的数据库,如MySql,SqlServer

--<generator class="identity"></generator>

注意:创建表时,指定主键可以自增长

3)native

--Hibernate会根据你设置的方言,判断出是哪种数据库,如果是Oracle就使用sequence方式生成主键,如果不是就使用identity方式生成主键。

--<generator class="native">

<param name="sequence">序列名</param>

</generator>

4)increment

--也是采用自增长的方式生成主键,但是这种方式不是用数据库的机制,而是Hibernate自己的机制,并且适用于所有的数据库。

--Hibernate提供一个组件,在需要主键时,它会从表中查询出最大的ID值,然后+1,以此结果作为新的主键。

--<generator class="increment"></generator>

--注意:通常不用,原因时在并发量大时可能会出现并发问题。

5)assigned

--Hibernate放弃生成主键,由程序员自行维护主键字段的值。

--<generator class="assigned"></generator>

6)uuid、hilo(高低位算法)

--采用uuid/hilo算法来生成一个主键,该主键是一个没有规律的,不重复的,长的字符串

--<generator class="uuid"></generator>

*9、Hibernate一级缓存(默认开启)

1)什么是一级缓存?

--Hibernate在创建Session时,会自动的给Session分配一块内存空间,用于存储该Session取到的对象值,那么这个内存空间就是一级缓存,或称为Session级缓存。

2)一级缓存的维护

--在使用Session进行查询时,Hibernate会优先上一级缓存中查找对应的数据,如果缓存中已经存在则直接返回,不用查库。如果缓存中不存在,再去执行查询数据库的行为。减少了对数据库的访问。

--Session在执行完查询数据库后,会将新查到的数据自动放入一级缓存中。

3)一级缓存的管理

--session.evict(Object);

把传入的对象从一级缓存中移除。

--session.clear();

移除一级缓存中所有的对象。

--session.close();

关闭session,释放缓存空间。

4)*重点关注

--Session级缓存是独享的,即每创建一个Session

对象,就给这个对象分配一个独立的缓存区,

其他的Session不能访问当前Session的缓存区。

--Session仅仅是把查询到的数据放入缓存区,

没有查询过的,是不会放入缓存区。

注意:

--一级缓存缓存的目标只能是实体对象

10、Hibernate对象持久性

1)Hibernate中实体对象具有3种状态,围绕着这三种状态的转换过程,我们称之为对象持久性。

2)3种状态

a、临时态

--通过new创建的对象是临时态的

--临时态的对象可以被垃圾回收

--持久态的对象通过delete方法可以转化为临时态

*b、持久态

--通过session的save,update方法可以将临时态/游离态的对象转化为持久态

--通过session的get,load方法将查询到的对象默认置为持久态

特点:

--持久态的对象不能被垃圾回收

--持久态的对象存在于一级缓存中,由Session负责管理

--持久态的对象可以自动的与数据库同步更新

--持久态的对象同步的时机是事务提交时即ts.commit,实际上是调用session.flush()时触发同步的,commit方法中调用了session.flush()

注意:session.flush();//将缓存中改变的对象数据更新到数据库记录仅仅是触发同步,但并没有提交事务

即:ts.commit()=session.flush()+原有事务提交功能

c、游离态

--通过session的evict,clear,close方法可以将持久态的对象

转化为游离态(从一级缓存中移除)

--游离态的对象可以被垃圾回收

11、flush()和commit()扩展:

session.flash()和缓存相关。执行时会清除session缓存并向数据库发送SQL语句并执行,但此时如果数据库当前存在一个事务,数据库会先将这些SQL语句缓存起来,那么此时在数据库中是无法看到SQL语句执行结果的。除非执行commit提交了事务。只要没有执行commit()方法,就能通过rollback()方法进行回滚。

1)session在什么情况下清理缓存:

--默认情况下,当应用程序提交事务,如:Transaction.commit;

--当我们显示调用flush的时候

--在执行某些查询的时候,如:iterate

2)session.flush()主要完成两件事情:

--清理缓存

--执行sql

3)flush执行的顺序:hibernate按照save,update,delete顺序提交相关操作commit()和事务相关。执行时会先隐式调用flush()方法,再提交事务。执行之后无法rollback()进行回滚。

*12、Hibernate延迟加载

1)什么是延迟加载?

Hibernate中有一些方法,在查询时并不是立刻查询数据库返回结果,而是给返回一个空(属性值)对象,当我们真正去使用这个对象getter时,才触发查询。这种将查询时机推迟到使用时间的机制,称之为延迟加载。

2)哪些方法具有延迟加载机制

a、session.load(Emp.class, id);//查询单个对象

--当调用该方法时,Hibernate并没有立刻查询数据库,而是new Emp(),然后setId(id),即我们得到的对象是一个只有id有值,其他属性为空的对象。

--当我们调用该对象时,比如e.getName()时,此时会触发查询。我们使用这个对象任何一个属性都可以触发查询,但使用id却不触发。

--不管是调用哪个属性触发的查询,那么本次查询都会将当前的记录完整的返回,此时对象中属性都可以有值。

b、query.iterate();//查询多个对象集合

--当调用该方法时,Hibernate会返回一个迭代器,迭代器中存的是一个空(属性空)的对象,该对象中仅仅是id有值,其他属性为空。

--此时,Hibernate执行了一次查询,但是为了效率,仅仅是查询出了ID的值select id from emp;

--当我们从迭代器中读取出对象,并且使用该对象时会触发真正的查询,将其他属性都查询出来,此时是根据当前对象的ID查询当前ID对应的一条记录,并非是查询所有的记录。

c、关联属性查询

3)延迟加载的好处

--可以提升内存资源的使用率

--可以降低对数据的并发访问(使用时机错开)

4)在使用延迟加载时要注意,不能在使用对象前关闭Session否则会报错:

LazeInitializationException:No Session

两种解决办法:

--不使用延迟加载的方法session.load()、query.iterate(),可使用session.get()、query.list()等

--在使用对象后关闭Session

5)在项目中,采用OpenSessionInView的机制来保证session关闭的时机。

a、OpenSessionInView指的是在视图层加载阶段保证Session处于非close状态,而视图层加载完成后,再关闭Session。

b、如何实现

--Servlet:监听器

public class MyFilter implents Filter{
    public void doFilter(request,response,chain){
        //添加逻辑--前期处理
        //通过过滤器,调用后续资源
        chain.doFilter(request,response);
        //添加逻辑--后期处理(关闭session)
    }
}

--Struts2:拦截器

创建拦截器OpenSessionInViewInterceptor,在拦截方法中,先调用ai.invoke(),该方法实际上会调用Action的业务方法,并根据返回值找Result,且加载JSP页面,因此在此方法后调用HibernateUtil.closeSession()方法就相当于是在页面加载完成后关闭Session,从而达到了推迟关闭Session的目的。

public class MyInterceptor implements Interceptor{
    public  String intercept(ActionInvocation in){
        //前期处理
        in.invoke();//执行Action--Result
        //后期处理(关闭session)
    }
}

--Spring:AOP

6)延迟加载实现原理

a、Hibernate是采用CGLIB的动态代理技术,在我们调用load,iterate方法时,返回的是指定类型的子类对象,这种在程序运行过程中创建子类对象的方式称为动态代理技术。

b、代码解读

public class Emp$.$.EnhancerByCGLIB$.$.88def978 extends Emp {//.是分割示意用,避免排版紊乱

//覆写get方法

public String getName() {

if(没有查询过) {

1.查询并给当前对象所有属性赋值

2.设置当前对象为查询后的状态

}

return this.name;

}

...

}

13、扩展1(大批量数据的分批同步处理方法—避免缓存溢出)

Session session = HibernateUtil.getSession();
Transaction ts = session.beginTransaction();
for(int i=0;i<10000;i++){//不做处理,容易使一级缓存溢出
    Foo foo = new Foo();//foo处于临时态
    //TODO 设置不同属性
    session.save(foo);//foo处于持久状态,会放入缓存
    if(i%20==0){
        session.flush();//将缓存foo对象同步
        session.clear();//清除缓存foo对象
    }
}
tv.commit();//不能分批提交,即不可破坏事务的完整性
session.close();

14、扩展2(大批量数据对象的单独处理方法—避免缓存溢出)

for(String id : ids){//如果数据量大,所有取出的对象放进一级缓存而不作处理,容易溢出
    Foo foo = (Foo)session.load(Foo.class,id)
    //处理foo
    session.evict(foo);//手动移除对象,提升健壮性
}
时间: 2024-08-30 05:14:21

Hibernate要点总结的相关文章

Struts 2 + Hibernate + Spring 整合要点

Struts 2 和 Spring 的功能有重合,因此有必要说明下,整合中分别使用了两种框架的哪些技术. Struts 2 使用功能点: 1.拦截器.一处是对非登录用户购物进行拦截,一处是对文件上传的格式进行拦截.前者的拦截器文件需自己手动编写,后者可直接用 Struts 2 框架封装好的拦截器. 2.数据校验,重写 Validate() 方法.对用户注册信息进行校验. 3.核心控制器 FilterDispatcher,限制只有管理员才能访问后台. Spring 使用功能点: 1.配置 bean

ssh整合思想初步 structs2 Spring Hibernate三大框架各自要点

Web层用Structs2的action Service层用Spring的IoC和aop以及JdbcTemplate或者Transaction事务(创建对象及维护对象间的关系) Dao层用Hibernate的crude操作 看上去是Structs2和Spring(把Structs2的action交给Spring整合,action处理表单,通常都是多实例用Spring <bean id="" class="" scope="prototype"

Hibernate【inverse和cascade属性】知识要点

Inverse属性 Inverse属性:表示控制权是否转移.. true:控制权已转移[当前一方没有控制权] false:控制权没有转移[当前一方有控制权] Inverse属性,是在维护关联关系的时候起作用的.只能在"一"的一方中使用该属性!Inverse属性的默认值为fasle,也就是当前一方是有控制权的 从一下的几个方面看看Inverse在维护关联关系时是否起作用: 保存数据 获取数据 解除关联关系 删除数据对关联关系的影响 保存数据 将inverse属性设置为ture,使dept

Hibernate【缓存】知识要点

对象状态 Hibernate中对象的状态: 临时/瞬时状态 持久化状态 游离状态 学习Hibernate的对象状态是为了更清晰地知道Hibernate的设计思想,以及是一级缓存的基础...当然啦,也就一点点知识 临时/瞬时状态 当我们直接new出来的对象就是临时/瞬时状态的.. 该对象还没有被持久化[没有保存在数据库中] 不受Session的管理 持久化状态 当保存在数据库中的对象就是持久化状态了 当调用session的save/saveOrUpdate/get/load/list等方法的时候,

Hibernate利用关联关系操纵对象

利用关联关系操纵对象 数据对象之间关联关系有一对一.一对多及多对多关联关系.在数据库操作中,数据对象之间的关联关系使用JDBC处理很困难.本节讲解如何在Hibernate中处理这些对象之间的关联关系.本节使用到4个类,它们分别是Student(学生).Card(学生证).Group(班级)和Course(课程),它们之间的关联关系如图1-1所示.这些实体存在级联(cascade)问题.例如,当删除一个班级的信息时,还要删除该班的所有学生的基本信息.如果直接使用JDBC执行这种级联操作,会非常烦琐

Struts2 hibernate spring 概念总结

Hibernate工作原理及为什么要用? 原理:1.通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件2.由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml"/>读取并解析映射信息3.通过config.buildSessionFactory();//创建SessionFactory4.sessionFactory.openSession();//打

hibernate基础学习---hierbnate2级缓存

1:开启二级缓存sessionFactory需要安装jar包 2:在实体类配置文件添加(配置二级缓存).我的配置文件是Account.hbm.xml <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapp

《Beginning Hibernate-For Hibernate 5, 4th Edition》(01_导读介绍)

<Beginning Hibernate-For Hibernate 5, 4th Edition> 这是一本介绍Hibernate5的图书,Hibernate 5是Hibernate框架的最新版本,这是目前市面上唯一一本介绍Hibernate5特性的图书,图书的链接https://www.amazon.cn/%E5%9B%BE%E4%B9%A6/dp/1484223187/ref=sr_1_1?ie=UTF8&qid=1491804196&sr=8-1&keyword

hibernate复习第(二)天

今日要点: 关联映射 多对一(Employee - Department) 一对多(Department - Employee) 一对一(Person - IdCard) 多对多(teachet - student) 组件映射(User - Name) 集合映射(set,list,map,bag) inverse和cascade(Employee - Department) 多对一: <many-to-one name="depart" column="depart_i