JAP是一个规范,Hibernate是该规范的一种实现
DAO 模式 Data Access Object
将数据访问与业务逻辑相分离
Service层完全不关心DAO层如何与数据库交互,只需要将请求交给DAO层即可
POJO Plain Ordinary Java Object 没有业务逻辑代码的值对象
PO Persistence Object 进行数据存储的对象,如Entity实体对象
VO Value Object 值对象,用来进行一些数据临时封装的对象
DTO Data Transfer Object 与VO类似吧
Hibernate配置文件中的属性配置
通过Hibernate目录下的etc/hibernate.properties文件,根据其中定义的属性进行配置
hbm2ddl.auto属性的说明:
create-drop 每次运行都先创建表,运行结束后,再删除表
create 每次运行都会先删除表(如果存在),再创建表(测试时用,便于清理上一次的数据)
update 如果表结构不对应,则进行更新(不会删除已存在的多余字段)
validate 校验实体与表是否对应,如果不对应,则报错(确保表结构的稳定)
JDBC操作数据库,默认自动提交,除非设置autoCommit(false);
Hibernate缺省不自动提交,必须在一个Transaction中进行显示提交;
SessionFactory
负责创建Session,它通过读取Hibernate配置文件,使用Configuration对象创建SessionFactory
openSession() 每次打开一个新的Session会话对象;
getCurrentSession() 获取与当前线程绑定的Session对象,确保在1个事务中使用的是同一个Session会话进行数据操作;
Transaction
在于数据库进行交互的过程中,事务非常非常的重要!
必须保证Session在事务中进行,要么全部操作成功,要么全部回退
========================================================================
Hibernate对象的3种状态及其转换
session中维护了1个Map,session.save(obj)就是把obj对象放入到Map中
Hibernate会在某个时候,批量的将Map中的对象持久化到数据库中
Transient
瞬时对象,跟session没有关系,数据库中没有对应的记录
new() 新创建的对象
session.delete() 数据库中没有对应记录,但内存中该对象仍存在
Persistent
持久化对象,被session所管理(被放到session内部的Map中),数据库中有对应的记录
session.get()
session.load()
session.save()
session.saveOrUpdate()
session.update()
Detached
离线对象,不被session对象管理,数据库中有对应的记录
session.evit()
session.clear()
session.close()
session.get()
先找一级缓存,无--->找二级缓存,无--->查询数据,无---> retrun null
session.load()
返回代理对象
获取property时查询数据库,无---> 抛异常
========================================================================
Hibernate主键生成策略
native
将主键生成工作交给数据库完成,不同数据库有不同的主键生成机制
mysql,sql server采用identity
oracle 采用sequence
assigned
由程序员手动分配id
sequence
Oracle的主键生成机制,当使用Oracle数据库时使用
identity
MySQL或SqlServer数据库使用
hilo
高低位算法生成数据库主键值
uuid
uuid.hex,全网络上主键都是唯一的
========================================================================
Cascade
all 将所有类型的操作都级联到关联对象上
save-update 保持和更新时进行级联保持或更新
delete 删除时进行级联删除
all-delete-orphan 当被关联对象失去宿主时,将其级联删除
none 不进行级联操作
Inverse(等效于mappedBy)
默认inverse=false, 则"一方"与"多方"都可以维护关联关系
让"一方"维护关联,Hibernate将额外发出update语句更新"多方"的外键,不推荐
inverse=true,强制将关联关系交给"多方"进行维护
========================================================================
通过一个基类来定义统一的ID生成机制,子类继承即可
package model; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.MappedSuperclass; @MappedSuperclass public class BaseEntity { @Id @GeneratedValue(strategy=GenerationType.AUTO) private int id; public int getId() { return id; } public void setId(int id) { this.id = id; } }
一对多单向关联 One To Many
一方
@Entity @Table(name="t_group") public class Group extends BaseEntity { private String name; @OneToMany(cascade=CascadeType.ALL) @JoinColumn(name="gid") //如果没有指定JoinColumn,Hibernate会创建第3张表存储关联关系 private Set<Person> persons; public Group() {} public Group(String name) { this.name = name; } public Set<Person> addPerson(Person p) { if(persons == null) { persons = new HashSet<Person>(); } persons.add(p); return persons; } //getters&setters }
多方
@Entity public class Person extends BaseEntity { private String name; public Person() {} public Person(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
@Test public void testOne2Many() { session.beginTransaction(); Group g = new Group("g1"); Person p1 = new Person("p1"); Person p2 = new Person("p2"); g.addPerson(p1).add(p2);//通过一端保存关联关系 session.save(g); session.getTransaction().commit(); }
将发出额外的update语句来设置外键(因为外键字段在多的一方的表中)
Hibernate: insert into t_group (name) values (?)
Hibernate: insert into Person (name) values (?)
Hibernate: insert into Person (name) values (?)
Hibernate: update Person set gid=? where id=?
Hibernate: update Person set gid=? where id=?
一对多双向关联 One To Many
一方
@Entity @Table(name="t_group") public class Group extends BaseEntity { private String name; @OneToMany(mappedBy="group",cascade=CascadeType.REMOVE) private Set<Person> persons; public Group() {} public Group(String name) { this.name = name; } public Set<Person> addPerson(Person p) { if(persons == null) { persons = new HashSet<Person>(); } persons.add(p); return persons; } getters&setters }
多方
@Entity public class Person extends BaseEntity { private String name; @ManyToOne @JoinColumn(name="gid") private Group group; public Person() {} public Person(String name) { this.name = name; } getters&setters }
@Test public void testOne2Many2() { session.beginTransaction(); Group g = new Group("g1"); session.save(g);//先持久化,避免TransientException Person p1 = new Person("p1"); Person p2 = new Person("p2"); //通过多方保存关联,不会发出额外的update语句 p1.setGroup(g); p2.setGroup(g); session.save(p1); session.save(p2); session.getTransaction().commit(); }
没有额外的update语句发出
Hibernate: insert into t_group (name) values (?)
Hibernate: insert into Person (gid, name) values (?, ?)
Hibernate: insert into Person (gid, name) values (?, ?)