首页 > 代码库 > hibernate总结

hibernate总结

一、简介:

1) Hibernate是ORM框架之一,该框架包括JDO,TOPLINK,JPA等,hibernate先于JPA出现,hibernate的开发者参与JPA的开发,其中JPA标准大有一统天下的趋势。

2) Hibernate是面向对象的,JDBC是面向过程的。

3) Hibernate封装了sql语句,用户只需定义实体类、建立数据库,并配置数据库连接(hibernate.cfg.xml),说明实体类与数据库之间的映射关系(hbm.xml文件或annotation)就可完成对象的操作。

4) hibernate的映射两种方式:xml方式,annotation注解方式(着重掌握)。MyEclipse可以根据反向生成类,注解也可正向生成数据库。理论上面向对象应该先类后表,但实际工作中,先见表后建类,因为有些db优化操作注解方式无法生成。

5) Hibernate使用的日志接口是slf4j,可实现多种日志,hibernate的日志slf4j-nodep不常用,可以转换为log4j日志。需要导入:

slf4j-api.jar和slf4j-log4j12.jar.

 

 

二、Hibernate.cfg.xml的配置:

1) <property name="current_session_context_class">thread</property>

a. 使用getCurrentSession方法时需要设置。

b. 取值:

① thread:上下文:从当前线程中找。

② jta(java transaction api):处理分布式事务

事务分类:connection事务,jta事务。

Connection事务使用一个connection处理。

jta事务需要多个connection处理,需要事务管理器TransactionManager实现)。如产品订单,一个数据库处理产品信息,另一个数据库处理支付信息。运行时需要applicationServer的提供TransactionManager,tomcat不具备TransactionManager。Jboss,WebLogic具备。

 

2) <property name="hbm2ddl.auto">create</property>

① Create:每次自动创建表

② Update:字段更新时自动创建DDL,更新表。

 

三、基础配置——主要写在get方法上。

@Entity注解实体

@Table(name="_animal"):修改表名

@Transient  //不往数据库中存,瞬态transient的数据。

@Temporal(TemporalType.DATE):修改Date格式

@Id注解主键

@Column(name="_name"):修改字段名

@Basic  //默认为@Basic

 

四、主键生成策略

1) xml:generator=”native”

① native:自适应DB

② identity:MySQL,SQLServer自增

③ sequence:Oracle自增

④ uuid:唯一

⑤ asssigned:指定

2) annotation:

① AUTO:相当于xml中native

② IDENTITY:同xml

③ SEQUENCE:同xml

④ TABLE:知道即可

 

3) 联合主键:主键类需要实现serializable接口。

① 常用方式1:嵌入主键类并在get上@EmbeddedId

② 常用方式2:实体类上@IdClass(PersonPK.class),主键get方法上@Id

 

五、Hibernate核心开发接口:

1) Configuration(xml方式) & AnnotaionConfiguration(注解方式)

① 管理配置信息:默认名hibernate.cfg.xml

② 用于产生SessionFactory

③ 可以在configure方法中指定hibernate配置文件名称

④ 只需关注一个方法: Configuration().configure().buildSessionFactory();

2) SessionFactory:

① 用来获取和管理Session

② 每个应用通常只需一个,除非要访问多个数据库。

③ 关注两种方法:

a. getCurrentSession():首先查找上下文中的Session,没有则创建新的Session,commit后session自动关闭。可以实现事务(同时成功或同时失败,必须使用同个Session)提交。

b. openSession():总是创建新的session,需要关闭,不建议使用。

 

 

六、对象的三种状态:

1) Transient:瞬态,内存中有,Session缓存中没有,数据库中没有,没有ID

2) Persistent:持久态,内存中有,将对象加载到Session缓存中,数据库有,有ID

3) Detached:托管状态(Session关闭,缓存也没了):内存中有,Session缓存中没,数据库中有,有ID

 

七、Session的方法:

1) clear():清空Session缓存

2) save();

3) delete();

4) flush():刷新Session缓存

5) get(Student.Class,1):立即加载Student对象执行SQL语句,对象成为persistent态,加载到Session缓存中

6) load(Student.Class,1):延迟,生成的是代理对象,用到时才会执行SQL语句并加载到缓存

7) update:更新对象所有字段,若只想更新部分字段,使用HQL:

8) Query query = session.createQuery("update Student s set s.name=‘s‘ where s.id=1");

query.executeUpdate(query);

八、hibernate关系映射(重点)

1) 关系——指的是对象数量之间的关系:一对一,一对多,多对一,多对多。

2) 数据库表与表之间的关系:只有主外键关系。数据库设计时一般遵循主键关联和单向外键关联,比较清晰。

① 单向OneToOne:

数据库设计时,如果两个实体A,B是一对一关系,可以在A中增加B对象的一个引用。并在get方法上写OneToOne。生成表时就把B表的ID作为A表的一个外键。get上写@JoinColumn(name=””)可修改生成的外键的字段名。

② 双向OneToOne:

在B中增加A对象即可,get方法上写@OneToOne  @mappedBy(“”)””中为A中getXXX()方法中的xXX。

组件映射:

@Embedded 相当于组件加到了被嵌入对象中。故不需要ID,不需要@Entity不需要在cfg中引入。

③ 单向ManyToOne:(在多的一方增加少的一方的外键,在多的一方增加少的一方的对象引用)

一般为多的一方增加外键。则多的一方增加另一方的对象引用。get上@ManyToOne即可

@JoinColumn(name=””)指定少的一方外键字段名

④ 单向OneToMany:(在多的一方增加少的一方的外键,在少的一方增加多的set类型的对象引用)

在少的一方增加set类型的另一方类型的引用,get上@OneToMany,则默认用ManyToMany的方式,在数据库中生成一张拥有双方ID的临时表。在get上写@JoinColumn(name=””),名称为少的一方的外键字段名,则生成的数据库结果跟ManyToOne一样。

⑤ 双向OneToMany即ManyToOne:

双向就用mappedBy=”主导的对象名”,@OneToMany @ManyToOne 

生成的数据库跟一个单向的一样。

⑥ 单向ManyToMany:单向设置在其中一个实体类中引入并@ManyToMany即可

⑦ 双向ManyToMany:双向两边都加入实体类并@ManyToMany,mappedBy设置主导一方。

九、性能优化

 

1) 级联(CASCADE):在增加、删除等操作时,一并改变和该实体类有关联的实体。只是操作时比较方便,并不是必要的。

操作:

① 1.在映射关系名后@ManyToMany(cascade={CascadeType.ALL}),设置对象之间的关系。

② 2.如设置Dream和Person之间的关系:dream.setPerson(person);单向设一个,双向设两个cascade关联。

a. ALL,任何时候都级联。

b. PERSIST,添加时级联。

c. REMOVE删除时级联。

级联后,保存、删除一个表中的数据时会自动操作级联的表中的数据。

 

2) 延迟加载/立即加载(fetch)

级联只影响增加删除修改,而fetch影响查询。

① EAGER:查询时关联的表立即加载。

② LAZY:查询时关联的表不加载。

操作:

@ManyToOne(fetch=FetchType.Lazy)即可,则在查询或get,load时改变加载方式。

3) 缓存

① 一级缓存:Session中的缓存

② 二级缓存:SessionFactory中的缓存,当Session中找不到的时候就去二级缓存中找。load,iterator,list查询 默认使用二级缓存。

③ 查询缓存:查询重复sql语句先在查询缓存中找。

适合放在二级缓存中的数据:

a. 经常被访问,

b. 改动不大,

c. 数量有限。

例如:组织机构,帖子类型,用户权限。

 

4) 事务并发处理:

a. 事务:ACID,原子性,一致性,独立型,持久性。

① 脏读:读了另外一个数据没有提交的数据。

② 不可重复读:同一个数据前后读两次值不同,做了更新。

③ 幻读:读数据的过程中另外的事务向其中插入/删除一条数据,影响了查询结果。

b. 事务隔离机制:取值1,2,4,8。(0001,0010,0100,1000算法效率高,拥有几种权限如CRUD,可以合并为0110)。一般情况下不处理幻读,考虑到效率一般设置为2即read-commited级别。所以要解决不可重复读的问题。

隔离机制

取值

是否会脏读

是否会不可重复读

是否会幻读

read-uncommited

1

read-commited

2

×

repeatable read

4

×

×

serialzable

8

×

×

×

 

c. 解决不可重复读的问题:

乐观锁:使用数据库的锁

悲观锁:使用@version

 

 

hibernate总结