Hibernate 是一个开放源代码的 ORM(对象关系映射)框架
ORM 就是内存中的对象与数据库中的数据间的映射关系。
JPA、ORM 与 Hibernate 间的关系是,ORM 是一种思想。JPA 则是这种思想的具体的表
现形式,是以 Java 语法规范表现出来的一种形式,是一套标准接口。Hibernate 则是这套接
口的具体实现
save()为 Hibernate 的 API,而 persist()为 JPA 的 API。均用于完成持久化(保存操作)
delete的参数也是一个对象,而且对象里面必须要有Id,因为其底层删除也是根据id删除
update 根据id修改
saveOrUpdate
有Id是修改update,没有id是save,如果参数对象具有id,但id在db中不存在,则抛出异常
get 查询无果时,会给出null,但不会抛出异常
load查询无果时。会抛出异常
load支持懒加载,只有当查询除了id以外的属性外,才会发sql语句,才用动态对象实现(不是jdk的动态代理,jdk动态代理只是对实现了接口的类生成代理),cglib库生成的代理,是对类的继承
底层sql语句执行顺序(insert,update,delete)
若要修改其底层的执行顺序,则可通过Session的flush()方法刷新Session完成。flush()会使其前后分隔为两部分,各部分会按增,改,删,顺序执行
Configuration
Configuration实例的获取方法:
Configuration cfg=new Configuration().configure();
(1) new Configuration
会加载一个属性文件hibernate.properties
(2) 无参configure()方法
configure()方法 ,默认用于加载和解析名称为hibernate.cfg.xml.的配置文件(默认路径在src文件夹下),并通过主配置文件找到并解析映射文件,该方法返回一个Configuration对象。
(3)带参configure()方法
SessionFactory 接口
SqssionFactory sessionFactory=cfg.buildSessionFactory();
单例,线程安全的(一般来说单例对象一定是被共享的,是线程不安全的,这里因为其大多数成员变量是final的)
SessionFactory对象一般不手工关闭,而是在应用结束时自动将其销毁,因此,SessionFactory不用进行close()关闭
Session接口
session s=sessionFactory.getCurrentSession();
轻量级的对象 ,线程不安全的,多例的
在web应用中,多个用户对同一应用访问,hibernate会为每个用户创建一个session对象,所以是多例的,Session中包含大量非final成员变量,对于同一个用户的操作,可能会产生多个事务,这多个事务若同时对同一个session的同一个成员变量进行访问,就会引起并发问题,所以session是线程不安全的
session对象的使用原则
session在使用时要做到一个线程一个session,即一个事务一个session,使用完毕,立即关闭
session不要作为某个类的成员变量出现。
Session对象的获取
SessionFactory.openSession() //创建了一个新的session对象
sessionFactory.getCurrentSession()//获取当前线程中的Session对象
当前session上下文
为了保证一个线程一个session,即一个线程中使用session是同一个对象,一般在获取session对象时,使用sessionFactory的getCurrentSession()方法。需在主配置文件中对session所处的上下文环境,即事务环境进行注册
Session中的常用方法
save/persist()添加对象
update() 修改对象
saveOrUpdate() 添加或修改对象
delete删除对象
get()/load()根据主键查询
createQuery/cerateSQLQuery() 创建查询对象
createCriteria() 条件查询,QBC,纯面向对象语句
Transaction接口
由session对象创建
session.getTransaction()
事务的开启: session.beginTransaction() 或 session.getTransaction().begin()
事务的提交:session.getTransaction().commit();
事务的回滚:session.getTransaction().rollback();
自动建表设置
create:每次加载主配置文件时都会删除上一次的生成的表,然后再生成新表,哪怕两次表结构没有任何变化
create-drop:每次加载主配置文件时会生成表,但是sessionFactory一旦关闭,表就自动删除
update:当表字段增加时,会添加字段,当表字段减少时,不会减少字段。若表结构没变化,但数据变化时,会修改数据
c3p0数据库连接池配置
映射文件详解:
(1)实体类与数据库中表的映射关系
(2)属性与表中字段的映射关系
1.
该标签是hibernate映射文件的根元素,其他可以包含多个
2 class标签
该标签用于设置po类和数据表间的映射关系
name属性:指定持久化类。若
table:数据库的名称,若不指定,hibernate将默认为表名与类名相同
catalog:指定数据库,默认为主配置文件中指定的DB
3 id 与property标签
name:类的属性名
column:表中的字段名,如不指定,则默认为name属性同名
length 指定属性所映射字段的长度,单位字节
not-null 为指定字段添加非空约束
unique 为指定字段添加唯一性约束
type: 指定属性所映射的字段的类型,若省略hibernate会自动从持久化类中检测到类型。支持两类 java类型和hibernate类型
sql-type属性
内置主键生成策略
(1)increment 生成策略
该策略是 Hibernate 自己在维护主键的值。当准备在数据库表中插入一条新记录时,首先从数据库表中获取当前主键字段的最大值,然后在最大值基础上加 1,作为新插入记录的主键值,这就是 increment 生成策略。用其生成的主键字段所对应的属性类型可以是 long、short、int 及其封装类的类型。这种生成策略只有在没有其他进程向同一张表中插入数据时才能使用。在高并发下或集群下不能使用。
其测试情况是,后台会产生对当前最大 id 的查询语句
(2 )identity生成策略
该策略使用数据库自身的自增长来维护主键值。如 mysql 使用 auto_increment 来维护。用其生成的主键字段所对应的属性类型可以是 long、short、int 及其封装类的类型。该策略在生成主键值时会出现以下情况:对于插入操作,即使最后的执行是回滚,DB中记录主键值的变量也会增一。因为该生成策略在发生回滚之前已经调用过DB的主键自增,所以无论是否提交,对于 DB 来说已经执行。
其测试情况是,后台不会产生任何有关 id 生成值的语句。因为其使用的是 MySql 自身auto_increment 来为 id 值。
(3 )sequence生成策略
在 Oracle、DB2 和 PostgreSQL 等数据库中创建一个序列(sequence),然后 Hibernate 通过该序列为当前记录获取主键值,从而为实体对象赋予主键字段映射属性值。此即 sequence生成策略,用其生成的主键字段映射属性值的类型可以是 long、short、int 及其封装类的类型。
(4 )native生成策略
由 Hibernate 根据所使用的数据库支持能力从 identity、sequence 生成策略中选择一种。使用这种标识符属性生成策略可以根据不同的数据库采用不同的生成策略,如 Oracle中使用 sequence,在 MySQL 中使用 identity 便于 Hibernate 应用在不同的数据库之间移植。测试情况是,没有生成任何与 id 生成值有关的 SQL 语句。说明使用的是 identity 生成策略。
(5 )uuid生成策略
uuid 生成策略采用 UUID( Universally Unique Identifier,通用唯一识别码) 算法来生成一个字符串类型的主键值,该值使用 IP 地址、JVM 的启动时间(精确到 1/4 秒)、当前系统时间和一个计数器值(在当前的 JVM 中唯一)经过计算产生,可以用于分布式的 Hibernate 应用中。产生的标识符属性是一个 32 位长度的字符串。使用这种生成策略,要求属性的类型必须为 String 类型。这种标识符属性生成策略生成的数值可以保证多个数据库之间的唯一性,并且由于其生成与具体的数据库没有关系,所以其移植性较强。但由于该值是 32 位长的字符串,所以占用的数据库空间较大,并且检索速度较慢。不过,实际开发中使用这种生成策略较多。除了使用 Hibernate 外,在 JDBC 中也可以使用 uuid 生成主键。因为 UUID 是 java.util 包中的一个独立的类。可以打开项目的 JRE System Library 库中的 rt.jar,在其中找到 java.util包,即可看到 UUID 这个类。
(6 )assigned 生成策略
该生成策略的主键值来自于程序员的手工设置,即通过 setId()方法设置。属性类型可以是整型,也可以是 String,但一般为 String。此生成策略,主要应用于业务相关主键。例如学号、身份证号做主键。
hibernate的对象状态
普通内存(与hibernate无关),,Session缓存,数据库
(1) 瞬时态:transient状态,对象在内存中存在,但DB中无记录,与Session无关
(2) 持久态:persistent状态,在内存中存在,DB中有记录,与session相关
(3) 游离态:detached状态,在内存中存在,在DB中有记录,与Session无关
(4) 无名态:在内存中不存在,但在DB中有记录,与session无关
状态转换图
状态转换常用方法
save( ):将瞬时态对象同步到 DB 中。
update( ):将游离态对象同步到 DB 中。
delete( ):将指定的对象从 session 中删除,同时也删除 DB 中的该数据。
close( ):关闭 Session 对象。
clear( ):清空 Session 的缓存。
saveOrUpdate( ):根据参数对象的 id 属性是否为 null 来判断是执行保存还是更新操作。
evict():将指定对象仅仅从 session 中删除,但不删除 DB 中的该数据。
load( )与 get( ):将无名态对象转换为持久态对象