持久化对象的三种状态
-
瞬时态
由new命令创建,开辟内存空间的对象,不存在持久化标记OID(相当于主键值),尚未与Hibernate session 关联,在数据库也没有记录,失去引用后被jvm回收。瞬时状态的对象在内存中是孤立存在的,与数据库中的数据无关联,仅是一个信息携带的载体
-
持久态
持久态的对象存在持久化标识OID,加入到session缓存中,并且相关联的session并没有关闭,在数据中有对应的记录,每条记录只对应唯一的持久化对象,需注意的是持久态对象在事务还未提交之前变为持久态的。
持久态对象可以动态更新数据库
-
脱管态
脱管态对象无法直接获取,由其他状态对象转换来,当某个持久化状态的实例与session关联被关闭时,就变成了托管态。托管态对象存在持久化标识OID,并且人与数据库的数据关联,只是失去了与当前session的关联,脱管状态对象发生改变时,Hibernate不能检测到。
[图片上传失败...(image-d5d29-1510802804288)]
备注:
瞬 -- 脱:为瞬间态设置持久化标识OID
脱-- 瞬:为瞬间态设置持久化标识OID设置为null
hibernate一级缓存(Session缓存)
Hibernate向一级缓存放入数据时,同时复制一份数据到hibernate快照中,当时用commit()方法提交事务时,会清理session一级缓存,这时会使用oid判断一级缓存中的对象和快照中的对象是否一致,否则执行update语句,将缓存内的内容同步到数据库,并更新快照
事务的特性
原子性,一致性,隔离性,持久性
管理session对象的方法
-
session对象的生命周期与本地线程绑定(thread)
SessionFactory.getCurrentSession();
这个方法必须配合hibernate.cfg.xml
配置(下方) -
session对象的生命周期与JTA事务绑定(jta)
-
Hibernate委托程序管理Session对象的生命周期(managed)
hibernate.cfg.xml
配置<property name="hibernate.current_session_context_class">thread</property>
表的关系
- 一对一
- 唯一外键对应,假设一对一的任意一方为多,在多的一方创建外键指向一的一方的主键,然后将外键设置成唯一
- 主键对应,一方的主键作为另一方的主键
- 一对多
- 在多的一方创建外键,指向一的一方的主键
- 多对多
- 创建一个中间表,中间表至少有两个字段最为外键分别指向多对多双方的主键
级联保存及更新
-
用来简化代码书写
//ALL:增删改都可以级联(cascade)
//save-update:增加和更新可以级联
//delete:删除可以级联
//如果不设置,则增删改都不可以级联
//注意:查询例外,不受级联权限的控制,默认级联
@Cascade(value=CascadeType.ALL) -
级联操作
当定义方执行保存,更新,删除操作时,其关联对象也执行相应的操作
关系维护
-
为了减少sql语句的条数,提高执行效率
-
inverse属性配置关系是否维护,强调外键维护权
true:放弃外键维护权
false:不放弃外键维护权(默认值)
-
注解通过mappedBy来实现此功能
-
当双向维护关系时,才需要强调外键维护权
一对多维护:一的一方放弃维护,多的一方不放弃维护。如果一方放弃维护关系,则可以省略相关维护的代码
多对多维护:如果进行了双向维护关系,就必须有一方放弃外键维护权,一般由被动方放弃
查询方式
-
Query
多表查询,但不复杂时使用,可使用?占位符及:命名占位符
-
Criteria
单表条件查询
-
SQLQuery
复杂的业务查询
检索方式
-
对象图导航检索
根据已加载的对象导航到他的关联对象
Session session = HibernateUtils.getCurrentSession(); Transaction transaction = session.beginTransaction(); LinkmanEntity linkmanEntity = session.get(LinkmanEntity.class, 4); CustomerEntity customerEntity = linkmanEntity.getCstCustomerByLkmCustId(); transaction.commit();
-
OID检索方式
用session的get()或load()方法加载某条记录对应的对象
LinkmanEntity linkmanEntity = session.get(LinkmanEntity.class, 4); LinkmanEntity linkmanEntity = session.load(LinkmanEntity.class, 4);
-
HQL检索
面向对象的查询语言,它与SQL查询语言有些类似,但它使用的是类,对象,属性概念,没有表和字段的概念,在Hibernate提供的各种检索方式中,HQL是官方推荐的查询语言,也是最广泛的一种检索方式。功能如下:
-
在查询语句中设定各种查询条件
-
支持投影查询,即检索出对象部分属性
-
支持分页查询
-
支持分组查询,使用group by和having关键字
-
提供内置聚合函数,如sum(),min()和max()
-
能够调用用户定义的SQL函数
-
支持子查询即嵌套查询
-
支持动态绑定参数
-
多表查询
-
迫切内链接与内链接区别在于封装数据的形式
内链接会将两个表的数据封装到两个实体类中,执行查询会返回
list<Object[]>
对象,Object[]内容是两个表的实体Query query = session.createQuery("select c.custId,c.custLinkman,l.lkmName from Customer c inner join c.linkmans l"); List<Object[]> customerList = query.list();
迫切内链接则会仅返回一个实体类,另一个数据库相关的实体类会封装到返回的实体类中,但是迫切内链接封装后会出现重复数据的问题,所以要进行去重
-
撒
-
-
-
BQC检索
是Hibernate提供的另一种检索对象的方式,主要由Criteria接口,Criterion接口和Expression类组成。Criteria接口是Hibernate API中的一个查询接口,需要由session来创建。Criterion是查询条件,在Criteria中提供了add(Criterion criterion)方法来添加查询条件。
-
SQL检索
多表查询
-
连接查询
-
交叉连接
交叉连接返回的是被连接的两个表中所有数据行的卡迪尔积,也就是返回第一个表中符合查询条件的数据行数乘以第二个表中符合插叙吧条件的数据行数
select * from 表1 cross join 表2
select * from 表1,表2
-
内连接
内连接又称简单连接或自然连接,是一种常见的连接查询。内链接使用比较运算符对两个表中的数据进行比较,并列出与连接条件匹配的数据行,组合成新的记录,也就是说在内连接查询中,只有满足条件的记录才能出现在查询结果中。
select 查询字段 from 表1 [inner] join 表2 on 表1.关系字段=表2.关系字段
inner join用于连接两个表,on用来指定连接条件,其中inner可以省略
-
隐式内连接
我们看不到 inner join的关键字,而使用where关键字来替代
select * from 表1,表2 where 表1.关系字段 = 表2.关系字段
-
显示内连接
select * from 表1 inner join 表2 on 表1.关系字段=表2.关系字段
select * from 表1 join 表2 on 表1.关系字段=表2.关系字段
-
-
外连接
返回的查询结果中不仅包含符合条件的数据,而且还包括左表(左连接或左外连接)、右表(右连接或右外连接)或两个表(全外连接)中所有的数据,此时就需要使用外连接查询,外连接分为左连接和右连接。
select 所查字段 from 表1 left|right [outer] join 表2 on 表1.关系字段=表2.关系字段 where 条件
left join
,right join
关键词左边的表叫做左表,右边的表叫做右表,使用左连接和右连接查询时,查询结果不一致-
left join(左连接):返回符合连接条件的查询记录及左表中剩余的所有记录
select * from 表1 left outer join 表2 on 表1.关系字段=表2.关系字段 where 条件
select * from 表1 left join 表2 on 表1.关系字段=表2.关系字段 where 条件
-
right join(右连接):返回符合连接条件的查询记录及右表中剩余的所有记录
select * from 表1 right outer join 表2 on 表1.关系字段=表2.关系字段 where 条件
select * from 表1 right join 表2 on 表1.关系字段=表2.关系字段 where 条件
-
-
网友评论