Hibernate 核心接口 三种对象状态 四种操作方法
a)Configuration
i.AnnotationConfiguration(5里面已经没有这个类了)
ii.进行配置信息管理
iii.用来产生SessionFactory
iv.可以在configure方法在指定hibernate配置文件
v.只需要关注一个方法:buildSessionFactory
b)SessionFactory
i.用来产生和管理session
ii.通常情况下每个应用只需要一个SessionFactory
iii.除非要访问多个数据库的情况
iv.关注两个方法即可:openSesion getCurrentSession
Opensession每次都是新的
getCurrentSession从上下文找,如果有,用旧的,如果没有,建新的
1. 用途,界定事务边界
2. 事务提交自动close
3. 上下文配置可参见xml文件中
<property name="current_session_context_classs">thread</property>
c)Session
管理一个数据库的任务单元(简单说就是增删 改 查)
Get与load的区别(面试重点,原理)
1. 不存在对应记录时表现不一样
2. load返回的是代理对象,等到真正用到对象的内容时才发出sql语句
3. get直接从数据库加载,不会延迟
get方法首先查询session缓存,没有的话直接发送sql查询数据库,一定要获取到真实的数据,否则返回null,并不适用二级缓存;反而load方法创建时首先查询session缓存,没有就创建代理,实际使用数据时才查询二级缓存和数据库,hibernate对于load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,就抛异常(所谓延迟加载也称为懒加载就是当在真正需要数据的时候,才真正执行数据加载操作。可以简单理解为,只有在使用的时候,才会发出sql语句进行查询。)
(代理实际就是空的对象 并没有去数据库查询得到的 我们叫代理对象,如果 去数据库查询了 返回到了这个对象 我们叫实体对象 就是这个对象真实存在)
g)Clear方法
无论是load还是get 都会首先查找缓存(一级缓存),如果没有,才会从数据库查找,调用clear()方法可以强制清除session缓存
Session.Commit() 这个方法它自动调用了close()和flush()方法
h) 调用flush()可以强制从内存到数据库的同步
i)三种状态的区别
区分方法: 有没有id, 数据库中有没有,session缓存中有没有
Trasient(临时状态): 没有id, 数据库中没有, session缓存没有 例:People people=new People()给该对象赋值后,满足数据库和缓存都没有,即游离状态
或者删除方法后,即数据库没有对应但是缓存仍然还有
Persistent(持久化状态):有id, 数据库有, session缓存有 例:session.save(people);session.getTransaction().commit(); 提交后,都有,即持久化
Detached(游离状态): 有id, 数据库有, session缓存没有 例:session关闭 即缓存没有但是数据库有
1.
hibernate注解版
放在要对应表的实体类的首部
@Entity
@Table(name="human")//如果实体类的名字和对应表名不同时 指定表名
@GeneratedValue
注解在主键
@Id下:
@Id
@GeneratedValue
默认策略 auto/native ;如果你使用MySQL,那么自动使用 auto_increment
指定ID生成策略 @GeneratedValue
@GeneratedValue(strategy=GenerationType.AUTO)
@GeneratedValue(strategy=GenerationType.IDENTITY)
@GeneratedValue(strategy=GenerationType.SEQUENCE) @GeneratedValue(strategy = GenerationType.SEQUENCE)//主键生成策略
@GeneratedValue(strategy=GenerationType.TABLE)
例如
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer getId() {
return id;
}
对应列注解
@Column
放在对象属性(对应列名)的get方法上
@Column
public String getName() {
return name;
}
联合主键
i.要重写equals和hashCode保证主键的唯一性
ii.要实现serializable 数据转移时需要
将联合主键的属性提取出来,重新编写一个StudentPK类(原Student类中的id,name要删除并新加入属性“StudentPK”)
例如:
@EmbeddedId
public StudentPK getPk() {
return pk;
}