* ORM(Object/Rlationship Mapping) 对象/关系映射
ORM框架 实际上 是对jdbc的封装
* hibernate 标准 ORM框架
* 编写 hibernate 步骤 :
1.创建hibernate 配置文件
2.创建持久化类
3.创建对象关系映射文件
4.通过 hibernate API 编写访问数据库的代码
* Session简介
Hibernate是对jdbc的封装,不建议直接使用jdbc的connection操作数据库,而是通过使用session操作数据库。
Session可以理解为操作数据库的对象。
Session与connection,是多对一关系,每个session都有一个与之对应的connection,一个connection不同时刻可以供多个session使用。
把对象保存在关系数据库中需要调用session的各种方法,如save(),update(),delete(),createQuery()等。
* 获取session的两种方式:
1.openSession :在事务提交或回滚之后需要手动关闭;每次创建新的对象
2.getCurrentSession :在事务提交或回滚之后会自动关闭;单例模式
如果使用getCurrentSession需要在hibernate.cfg.xml文件中进行配置
如果是本地事务(jdbc事务)
<property name=”hibernate.current_session_context_class”>thread</property>
如果是全局事务(jta事务)
<propertyname=”hibernate.current_session_context_class”>jta</property>
openSession与getCurrentSession的区别
1.getCurrentSession在事务提交或者回滚之后会自动关闭,而openSession需要你手动关闭。如果使用openSession而没有手动关闭,多次之后会导致连接池溢出。
2.openSession每次创建新的session对象,getCurrentSession使用现有的session对象。
* session缓存(一级缓存)的作用,查询的时候会先去缓存里面查看
1.flush(); 这个方法会 强制 使数据库的状态与session缓存里面对象的状态同步,如果不一致则可以能会发送对应的sql语句使其一致
2.reflesh();这个方法会 强制 发出一条 select语句,使session缓存里面的数据与数据库一致
3.clear();这个方法会 清理掉session里面的缓存
* session的核心方法:
* save();
1.是一个临时对象变为持久化对象
2.为对象分配Id
3.在flush缓存时会发送一条insert语句
* get() 和 load()
1.get 立即检索,load延迟检索(会返回一个代理对象)
2.若数据库没有对应的记录象,get返回null;load则会抛出异常
* update();
1.若更新一个持久化对象,不需要显示调用update方法,因为在提交事务时会先调用session的flush方法
2.若更新一个游离对象(数据库有记录,session里面没有)时需要显示调用update方法
* hibernate 把持久化类的属性分为两种
1.值类型:没有OID,不能被单独持久化,生命周期依赖于所属的持久化类的对象的生命周期
2.实体类型: 有OID,可以被单独持久化
* Transaction简介
Hibernate对数据的操作都是封装在事务当中,并且默认是非自动提交的方式。
所以用session保存对象时,如果不开启事务,并且手工提交事务,对象并不会真正保存在数据库中。
***********************************************************************
* JPA与hibernate的关系
JPA是标准接口,hibernate是实现,hibernate功能更强大
* hibernate 注解的方式开发
1.类级别注解
@Entity :使用这个注解时必须要指定主键属性
@Table :与@Entity配合使用
@Embeddable 嵌入类注解
2.属性级别注解(常用的)
(注解可以添加在get方法上面,也可以添加在属性上面)
@Id :(如果使用联合主键(有多个@Id),目标实体类需要实现序列化接口 Serializable )
(如果字符串类型的属性作为主键,需要指定长度,例如添加 @Column(length=8) 主键长度为8)
@GeneratedValue :(可选)用于定义主键生成策略,默认为AUTO,注意:不适用于字符串类型的主键
@Column :属性映射成字段的注解,使用该注解来覆盖默认值,可以省略
@Embedded :嵌入属性的注解,需要和(@Embeddable 嵌入类注解)配合使用
@EmbeddedId :使用嵌入式主键类实现复合主键,需要和(@Embeddable 嵌入类注解)配合使用
嵌入式主键类必须实现Serializable接口;必须有无参构造方法;必须重写equals和hashCode方法
@Transient :加上此注解后,不会映射此属性到数据库的表的字段中
3.关联关系注解
1. 一对一单向外键
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name="pid",unique=true)
注意:保存时应该先保存外键对象,再保存主表对象
2.一对一双向外键
主控方的配置同一对一单向外键关联
@OneToOne(mappedBy="card") //被控方
注意:双向关联,被控方必须要设置mappedBy属性,card为主控方外键属性
3.一对一双向外键联合主键
创建主键类(需要@Embeddable 注解)
主键类必须实现Serializable接口;必须有无参构造方法;必须重写equals和hashCode方法
实体类 (需要@EmbeddedId注解)
4.多对一单向外键(多方持有一方的引用)
@ManyToOne(cascade={CascadeType.ALL},fetch=FetchType.EAGER) //属性为级联关系和抓取策略(积极加载)
@JoinColumn(name="cid",referencedColumnName="CID") //属性为映射的外键名称和字段名称
5.一对多单向外键(一方持有多方的引用)
@OneToMany(cascade={CascadeType.ALL},fetch=FetchType.LAZY) //属性为级联关系和抓取策略(懒加载)
@JoinColumn(name="cid") //属性为映射的外键名称
6.多对一(一对多)双向外键
7.多对多单向外键
@ManyToMany
@JoinTable(name="",joinColumns={@JoinColumn(name="")},inverseJoinColumns={@JoinColumn(name="")})
8.多对多双向外键
//一方
@ManyToMany(mappedBy="")
//另一方
@ManyToMany
@JoinTable(name="",joinColumns={@JoinColumn(name="")},inverseJoinColumns={@JoinColumn(name="")})