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 persons;
public Group() {}
public Group(String name) {
this.name = name;
}
public Set addPerson(Person p) {
if(persons == null) {
persons = new HashSet();
}
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 persons;
public Group() {}
public Group(String name) {
this.name = name;
}
public Set addPerson(Person p) {
if(persons == null) {
persons = new HashSet();
}
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 (?, ?)