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