Day One
ORM、Hibernate的简单介绍和基本使用,详情:
Hibernate API
Hibernate入门和基础配置
Day Two
- 实体类编写规则
- 实体类操作
- 实现类的三种状态和SaveOrUpdate方法
- 缓存
- 事物操作
实体类编写规则
- Hibernate要求实体类具有一个唯一的属性值(id)。
- 实体类中的属性不建议使用基本类型,应该使用包装类型,因为该属性的值可能为空,而基本类型的值不能为null。
主键生成策略
通过在映射文件中的id标签中添加generator
标签,指定class属性,可以指定主键生成策略。常见的有以下几种:
名称 | 操作 |
---|---|
increment | 用于long、short、int,递增 |
identity | 采用底层数据库提供的主键标识符,条件是数据库支持自动增长类型 |
sequence | 根据底层数据库序列生成标识符 |
native | 根据底层数据库对自动生标识符的能力来选择以上三种中的一种,使用于跨平台开发 |
uuid | 采用128位的UUID算法来生成标识符,结果为一个32位的16进制字符串 |
assigned | 由Java程序生成主键,默认 |
实体类操作
添加
|
|
查询
查询单个
User user = session.get(User.class,1);
查询多个
之后再讲
修改
|
|
删除
|
|
实现类的三种状态和SaveOrUpdate方法
瞬时态
|
|
上面这个对象就是游离态,代码中刚new出来的对象,和session没关系,只是一个普通的类。
持久态
|
|
重session中取出来的对象就是持久态,因为这个对象肯定是持久化的,因为在数据库中有这个记录
托管态
当给瞬时态的对象附上了标识符,即设置了ID,但是和session没有关系,也就是没有持久化,那么它就是托管态。
SaveOrUpdate
session.saveOrUpdate(user);
如果user是瞬时态,save;如果user是托管态或持久态,update。
缓存
一级缓存
默认打开,单个session内生效。
二级缓存
默认关闭,sessionFactory有效,通常用redis替代
事物操作
规范写法
|
|
Hibernate绑定session
核心配置文件需要添加属性配置<property name="current_session_context_class">thread</property>
使用sessionFactory.getCurrentSession方法,可以获取与当前线程绑定的session,得到与线程关联的唯一session,factory会帮我们管理,而不用手动关闭。
Day Three
主要是多表关系和对应的配置和操作
一对多关系
以分类-商品为例
编写实体类。
在基础字段之上,添加映射对象,如,在分类实体类中添加Set<Goods> goodsSet
,表示一个分类下有多个商品;同时,在商品实体类中添加Category category
属性,表示一个商品属于一个分类。同时添加getter、setter方法。如:1 2 3 4 5 6 7 8 9 10 11 12 13 14
public class Category { private int cid; private String name; private Set<Goods> goodsSet = new HashSet<Goods>(); } //--------------------- public class Goods { private int gid; private String name; private Double price; private Category category; }
编写映射文件,在基础的属性-字段映射关系上添加表间一对多关系。
hibernate中需要在外建的双端都添加关系。
在一对多的“一”端,这里也就是分类实体类的映射文件中,需要添加set标签,格式如下:Category.hbm.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="entity.Category" table="category"> <id name="cid" column="cid"></id> <property name="name" column="name"></property> <set name="goodsSet"> <!-- 本表中的键名 --> <key column="cid"></key><!-- 外建名 --> <one-to-many class="entity.Goods"></one-to-many><!-- 有关系的类的全路径 --> </set> </class> </hibernate-mapping>
在一对多的“多”端,需要添加<many-to-one>
标签Goods.hbm.xml
|
|
在编写代码时,只需要添加一方依赖,或者去掉一方的依赖,即可进行级联保存和删除,可以在‘一’端的映射文件的set标签中给inverse
属性设置值为true,即可关闭‘一’端的级联保存/删除功能,这个做法通常用来提升性能。
多对多关系
和一对多的区别时,两张表都有set标签,并且需要给set标签添加table属性(表示多对多关系的表),然后set标签中,key标签的column属性值为第三张表中关联当前表的外建名,many-to-many标签中class属性的值表示关联的另一个实体类的全路径,以及这个关联类在第三张表中的外键名。
在多对多关系中,所有的关系用第三张表表示,所以在管理如用户-角色这样的多对多关系时,只需要维护第三张表即可。
Day Four
Hibernate的查询方式:
- 对象导航 和 oid 查询
get() - HQL查询
类似SQL,不过面向的是实体类和属性而不是 表和字段 - QBC查询
Criteria
Hibernate检索策略
get 和 load方法的区别load是懒加载,只有需要访问对象中的属性的时候才真正执行sql语句从数据库中取记录。
Hibernate批量抓取
通过给一对多关系的映射文件中的一端的set标签设置一个batch-size,可以在遍历list,从数据库取值的时候,将多次取一条优化为一次取多条,减少查询时间