您的位置:首页 > 编程语言 > Java开发

致敬经典之Hibernate

2017-07-22 10:41 141 查看
一、经典的原因

Hibernate是一个对象关系映射的框架,顾名思义就是把java的实体映射到数据库,并且自动帮助我们生成sql语句,这样我们就可以使用对象随心所欲的使用对象编程操作数据库,可以说是风靡一时,但是这也成为Hibernate框架的一个诟病,因为sql语句我们无法直接操作,对sql的优化造成了困扰,我想这也是MyBatis兴起的一个重要原因吧,两者的不同和优缺点这里暂时不做详细对比了


二、基础核心

1.Configuration

通过Configuration读取数据库配置文件,并创建好与数据库的链接,当使用anntation方式时,使用AnnotationConfiguration;

2.SessionFactory

session创建的工厂,维护着数据库的连接池,创建session有两种方式

openSession:每次都创建新的session,使用完手动close

getCurrentSession:拿到当前的session,在commit后自动关闭

上述两种创建方式完全不同,不要混合使用具体细节不在赘述

3.Session

接口有着不同的实现,管理一个数据库连接,执行增删改查

4.对象三种状态

hibernate中对象的状态跟主键id有没有存在及位置有关

①没有id:transient

②数据库中有没有id:  persistent 内存中有,缓存中有,数据库中有

③缓存中有没有id:     detached  内存中有,缓存没有,数据库有

缓存指的是session管理的内存

persistent和detached区别在于session时候关闭,如未关闭则处于persistent
关闭则缓存释放,处于detached状态

5.id生成的策略

@GeneratorValue指定我们的id是哪个

strategy:指定具体的id值在生成时候的策略

①GenerationType.IDENTITY            为自增长

②GenerationType.SEQUENCE        支持sequence机制的数据库(mysql不支持),如oracle

③GenerationType.TABLE        使用第三方表生成,根据表名,记录每张表中id的最大值,可指定步长

④GenerationType.AUTO             根据数据库不同,按照不同数据库默认的方式生成

6.常用增删改查

delete:对象必须处于,persistent或detached状态,即有id

get:返回我们需要的对象,直接返回

load:返回我们需要的对象,返回的对象其实是一个代理,真正的sql语句是在对象中拿值的时候执行的,如果在session关闭后取对象中的值会有proxy找不到的错误,因为session已经关闭;解决方案:在拦截器中控制请求结束后关闭session

update:更新数据,默认会把所有的字段都做一遍检查更新

优化处理:

①屏蔽无关内容的更新,在不需要做更新的字段指定updateAble=false

②merge合并,会先load一遍,比较不同之后再做update

③HQL,面向对象的sql语句,很是强大

clear():清除session缓存

flush():强制和数据库进行数据同步,在commit方法内部都有flush的执行


三、关系映射

因为hibernate的思想就是把对象映射到数据库关系中,所以对象之间的关系与数据库对应,并且有单向和双向的区别;方向在与是否能通过一方查找到另一方

①一对一

外键:数据库表中的表现,作为另一张表的外键

单向:@OneToOne,需要有外键的一方指定即可

双向:双方都要指定@OneToOne,一般还需设置一个主导方 通过mappedBy指定,再设置@JoinColumn字段名单向和双向在数据库中的表现都是一样的,一张表中存在外键

主键:不设置外键,不能保证数据库唯一

@PrimaryKeyJonColumn  不会产生外键,只是在形式上做了一种约束,数据库表没变化

②一对多

单向一对多:@OneToManay,默认会当做多对多来处理,生成第三张表

使用@JoinColumn,这时少的一方主键作为多的一方外键来处理

单向多对一:@ManayToOne,直接在多的一方设置即可

双向:分别制定@OneToManay 和 @ManayToOne

一定要配置mappedBy,如果考虑的是多的一方,那么在少的一方配置,反之亦然

③多对多:用联合主键作为第三张表

@ManayToManay

@JoinTable指定第三张表的表名和内容


@JoinTable(name=”“,

joinColumns={@JoinColumn(name=”“)},

inverseJoinColumns={@JoinColumn(name=”“)}

)

joinColumns指定的是当前对象在第三张表中设置,inverseJoinColumns是另外一个类在第三张表中的设置

两者都用的数组,是因为考虑到两个对象本身用的就是联合主键,那么在指定第三张表的时候每个对象可能需要指定多个名字


四、总结

1.hibernate对于对象映射到数据库的配置是真的繁琐,一旦表非常多,应该不是一个很好的选择

2.对于用不用无关字段作为主键这个事情还有待商榷,感觉主键最好用表中的数据

3.估计刚使用hibernate会很懵逼的,对于dao层封装的这么“完整”,完全看不到sql
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hibernate java