【学习笔记】Y2-1-4 Hibernate入门
框架
框架Framework是一个提供了可重用的公共结构的半成品,他为我们构建新的应用程序提供了极大便利
主流框架
1.Struts
Struts2
2.Hibernate
3.Spring
数据持久化
数据持久化是将内存中的数据模型转化为存储模型,以及将存储模型转化为内存中的数据模型的统称
例如:文件存储 读取
//Hibernate
Hibernate是数据持久化工具,是一个开源的对象关系映射框架
封装了通过JDBC访问数据库的操作,向上层应用提供面向对象的数据访问API
//ORM
ORM(Object/Relational Mapping) 对象/关系映射
一种数据持久化技术
在对象模型和关系型数据库之间建立起对应关系,并提供一种机制,通过JavaBean对象去数据表中的数据
Hibernate优点
1.功能强大,是Java应用与关系数据库之间的桥梁,代码量大大减少,提高了持久化代码的开发速度,降低了维护成本.
2.支持许多面向对象的特性,组合 继承 多态等,方便开发人员进行领域驱动的面向对象设计与开发
3.可移植性好
4.开源免费
适用于大中型项目
1.下载并部署jar包,并添加引用
2.创建Hibernate.cfg.xml配置文件
3.hbm.xml映射文件
//hibernate.cfg.xml代码 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- 配置连接数据库的基本信息 --> <property name="connection.driver_class">oracle.jdbc.OracleDriver</property> <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property> <property name="connection.username">sword</property> <property name="connection.password">1</property> <!--方言 --> <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property> <!--在控制台自动显示sql语句 --> <property name="show_sql">true</property> <!-- 格式化sql --> <property name="format_sql">true</property> <!--自动建表 --> . <property name="hbm2ddl.auto">update</property> <!--关联小配置 --> <mapping resource="cn/sword/entity/Student.hbm.xml" /> </session-factory> </hibernate-configuration>
//hbm映射文件 <hibernate-mapping package="cn.sword.entity"> <class name="Student" table="STUDENT"> <id name="sid" column="SID"> <!--主键生成策略--> <generator class="native"/> //native 自动自增 //sequence 自己指定序列 //assiged //identity </id> <property name="name" type="string" column="NAME"/> <property name="age"/> </class> </hibernate-mapping>
3.书写小配置文件
4.在hibernate.cfg.xml中用mapping节点关联小配置
5.书写测试类
//idea有严格的目录区分
resource 资源目录 相当于classpath下
src 源码目录
test 测试目录
持久化与ORM
Object Relational Mapping 对象关系映射
编写程序的时候程序员更倾向于以面向对象的思维方式
保存数据时却以关系型数据库的方式存储
持久化是程序数据在瞬时状态和持久状态间转化的过程
//Hibernate实现了ORM Framework思想 //toplink . jdo . JPA标准下的具体框架 conf=new Configuration().configure(); sessionFactory=conf.buildSessionFactory(); //SessionFactory是重量级的 //一个程序中只能有一个 并且是线程安全的 //SessionFactory 保存了当前数据库配置信息和所有映射关系以及预定义的SQL语句. 在SessionFactory中内置了连接池 两个常用用法 openSession() --从连接池中随机获取一个链接 getCurrentSession() --将session和ThreadLocal绑定,确保在一次请求中,只有一个session对象 //session是线程非安全的 每个线程一份 需要关闭 //Hibernate中的session不是http协议中的session //可以看成Connection 但并不是 session=sessionFactory.openSession(); tx=session.beginTransaction(); ... tx.commit(); session.close();
3.PO VO DO DTO
//POJO
plain Ordinary Java Object //普通的java对象(实体类?)
JavaBean=POJO
PO=POJO+xml配置
//Hibernate框架是位于应用程序和数据库之间,将数据库底层操作完全封装,应用程序通过PO对象,进行Hibernate操作,完成对数据库操作
核心配置文件 默认在src目录下
Hibernate.properties 常用属性:key value
另一个是hibernate.cfg.xml
<property name="hbmddl.auto">update</property>
取值说明
(表结构)
//create 表示启动时先drop再create
//create-drop 表示创建,只不过在系统关闭前执行以下drop
//update 启动时去检查数据库schema是否一致,如果不一致去做schema更新
//validate 启动时验证现有的schema与配置的Hibernate是否一致,如果不一致会抛出异常并不做更新
4.
Configuration cfg=new Configuration().configure();
SchemaExport se=new SchemaExport();
se.create(boolean script,boolean export)
//两个参数分别决定控制台生成脚本,和影响到数据库
! openSession和getCurrentSession的区别
1.采用getCurrentSession创建的session会绑定到当前线程中,openSession创建的不会
2.getCurrentSession创建的session在commit或者rollback时会自动关闭,而采用openSession创建的session必须手动关闭
3.使用getCurrentSession需要在hibernate.cfg.xml中加入以下配置
如果是本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
//如果是全局事务(jta事务) 则替换为jta
5.Hibernate中Java对象的三种状态
//瞬(临)时状态Transient
//持久状态Persistent
//游离状态Detached
1.瞬时状态
Student stu=new Student();//Session和数据库中都没有
2.持久态(有OID)
//Java中按内存地址不同区分同一个类的不同对象
//关系数据库用主键区分同一条记录
//Hibernate使用OID来建立内存中对象和数据库中记录的对应关系
5.5 OID
什么是OID?
持久化类与数据表主键对应属性 用来
Session.save(stu);//session和数据库中都有
3.游离态(有OID)
Session.close();//session中没有,数据库中有
6.Load()和get()区别
1.如果程序中提供的OID对应的底层数据库没有编号,load()报错,get()得到null
2.延迟加载
load()延迟加载 因为产生的是代理对象
//第一次访问真实属性(非OID之外的属性)的时候 才去数据库加载
get()非延迟加载 因为是对象本身
//共同特点
策略:先检索session级别的缓存,如果没有,接着检索二级缓存.如果二级缓存也没有,检索数据库
7.session存储机制 一级缓存(session)和二级缓存(SessionFactory区别)
get()获取的对象会进入一级缓存(session中)
//session 存储数据的结构'
8.脏检查
tx.commit();//清理缓存 是让数据库中的数据和session同步
session会在一下时间点刷新缓存
1.事务的commit
2.session.flush()
刷新缓存(某一时间点触发的动作) 和
脏检查(刷缓存时候做的事情)
9.如何在Hibernate集成log4j日志框架
10.数据库的四种隔离级别
Oracle数据库默认事务隔离界别
事务并发多问题:
脏读 不可重复读 幻想读 丢失更新问题
为了解决数据库事务并发运行时的各种问题 数据库系统提供四种事务隔离级别
1.Serializable串行化
2.Repeatable Read 可重复读
3.Read Commited 可读已提交
4.Read Uncommited 可读未提交
@Entity //(用jpa的)
@Table(name=GRADE)
public class Grade{
@ID
private Integer id;
@Colum
private String name;
}
//大配置文件:
<mapping class="cn.sword.entity.grade" />
class Configuration 一个类 主要用来读取配置文件
包:org.hibernate.cfg
定义所有配置和映射的源,是建立一次性SessionFactory的前提条件
Interface SessionFactory 包:org.hibernate
通常应用程序具有一个SessionFactory实例为客户端请求提供服务的线程从这个工厂获取会话实例.
SessionFactory有两种方案获取到session
2.刷新缓存和脏检查
脏检查:当事务提交时,Hibernate会对session中持久状态的对象进行检测,判断对象的数据是否发生变化
为什么要进行脏检查?
如果对象发生了改变,就需要将改变更新到数据库,以确保内存中的对象与数据库中的数据保持一致.
//如何进行脏检查
当一个对象被加入到Session缓存(一级缓存) Session会为对象的值类型的属性复制一份快照.
当session刷新缓存后,会先进行脏检查,即比较对象的当前属性值和它的快照,来判断对象的属性是否发生了变化. 如果发生了变化,session会根据脏对象的最新属性,生成sql语句更新到数据库中.
3.Hibernate中 update saveOrUpdate merge的区别
1. update 和 merge的区别
首先在执行更新操作的时候,两者都必须要有id
update是直接执行update 语句,执行后状态为持久化状态
而merge则不一样:
1. 如果session中有与之对应的对象,也就是主键相同,则会把要保存的obj的值copy给session中的对象,然后update被复制后的session中的对象
2. 如果session中没有,则会先从数据库中select,然后把obj给查出来的对象copy,则update查出来的对象。
3. 所以merge会先select 再update
4. 所以merge后原来的对象obj状态为脱管。