一、经典的原因
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