hibernate框架
框架
- 简介
软件的半成品,已经完成了软件的部分功能 - javaEE的最初结构设计
- 演化后的javaEE三层结构
servlet+jsp+javaBean+JDBC使用这套架构可以开发市面上的所有应用。但是在企业中不会使用(过于底层)。企业中开发一般使用SSH(Structs+Spring+Hibernate)、SSM(SpringMVC+Spring+Mybatis)。
hibernate概述
- 简介
在这里插入图片描述
持久层的ORM(Object Relational Mapping 对象关系映射)框架
ORM
利用描述对象和数据库表之间映射的元数据,自动把java应用程序中的对象持久化到关系型数据库的表中。通过操作java对象,就可以完成对数据表的操作。可以把ORM理解为关系型数据和对象的一个纽带,开发人员只需要关注纽带一端映射的对象即可。
- 优势
入门demo
- 利用navicat for mysql工具中建表;
- 创建对应实体类;
- 编写Customer.hbm.xml为前面的表和类创建映射;
- 编写hibernate核心配置文件hibernate.cfg.xml ;
基本参数必须配置,可选配置根据需要配置
dialect方言的作用是根据不同数据库的语法生成数据库语言,相当于翻译。
- 编写测试类HibernateDemo1;
- 可以看到效果:
控制台输出
数据库中显示:
配置
常见配置
xml的提示配置
eclipse中window-preference->
key是bean标签内的http://…,有几个文件就add几次,导入几个依赖文件。
映射配置(关键)
- 【class标签的配置】
– 建立类与表的映射关系
– 属性:
name = 类的全路径
table = 表名(若与类名相同可省)
catalog = 数据库名
shema(mysql) = 数据库名
- 【id标签的配置】
– 建立类中属性和表中主键的对应关系
name = 类中属性名
column = 表中主键名(若与属性名相同可省)
length = 长度
type = 类型
- 【property标签的配置】
name = 类中属性名
column = 表中主键名(若与属性名相同可省)
length = 长度
type = 类型
not-null = 非空
unique = 唯一
- length作用:hibernate帮助建表时使用,默认255。
- type写法:
- java写法:java.lang.String;
- hibernate写法:string;
- 数据库写法:
- 省略不写type,hibernate会自动转换
核心配置
简述
- 必须的配置
– 连接数据库的基本参数:
驱动类、 url路径、 用户名、 密码
– 方言
- 可选的配置
– 显示sql :hibernate.show_sql
– 格式化sql :hibernate.format_sql
– 自动建表:hibernate.hbm2ddl.aoto
none:不使用hibernate自动建表
create:如果数据库已有操作表,删除再新建;如果没有表,新建表。
create-drop:如果数据库已有操作表,删除再新建,执行操作再删除表;如果没有表,新建表,完成操作后删除表。最终数据库中没有相应的操作表
–上述两个适合于测试
update:如果数据库有表,用原表(可以更新表结构)如果没表,新建表。
validate:数据库中没有响应表或者表结构不符合会报错(校验映射和表结构) - 映射文件的引入
配置方式
-
属性文件的方式–hibernate.properties
例如:hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.show_sql=true属性文件的方式不能引入映射文件(手动编写代码加载映射文件) 用得少
-
xml文件的方式–hbn.cfg.xml
mapping标签映射
核心API
Configuration对象
- 简介
- 作用
– 加载核心配置文件
– 加载映射文件//hibernate.properties Configuration cfg = new Configuration(); //hibernate.cfg.xml Configuration cfg = new Configuration().configure();
SessionFactory对象
- 简介
sessionFactory内部维护了hibernate的连接池和二级缓存(现企业常用redis替代);
可简单相当于jdbc中的数据连接池;
是线程安全的;
一个项目只需创建一个对象即可。 - 数据连接池
– hibernate自身的连接池
- 配置log4j.properties,如下图。
error->warn->info->debug->trace
注意:log4j.rootLogger= info时显示error,warn和info级别的信息,即必然显示从error开始的高级别log。
- 可以看到 hibernate连接池的参数。
– c3p0数据池(自行配置)
1.在核心配置文件添加配置代码
2.导入c3p0的jar包
- 抽取工具类
Session对象
- 简介
Session是hibernate和数据库的连接对象,类似connection;
是非线程安全的。
补充:
线程安全指的是:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。
线程安全问题大多是由全局变量及静态变量引起的,局部变量逃逸也可能导致线程安全问题。
- session中的API
– 保存方法:
Serializable save(Object obj);
– 查询方法:
T get(Class c,Serializable id);
T load(Class c,Serializable id);
get方法和load方法的区别?
- debug情况下查看区别效果
– 修改方法
void update(Object obj);
– 删除方法
void delete(Object obj);
– 保存或更新方法
void saveOrUpdate(Object obj)
- 查询所有
Transaction对象:事务对象
- 简介
transaction可选API,在ssh框架中可由spring代替实现。
- 常用API
– commit();
– callback();Session session = ... //hibernate3必须有commit()方法,否则报错 Transaction tx = session.beginTransaction(); ...//核心功能代码 tx.commit(); ...
持久化类的编写规范
- 持久化:将内存中的数据永久存储到关系型数据库(一般在硬盘)中。
- 持久化类:一个java类对象和数据库表建立映射关系,那么这个类就可以称为持久化类。
持久化类=java类+映射文件
持久化类的编写规则 | 原因或作用 |
---|---|
持久化类具有一个无参数的构造方法 | hibernate底层需要使用反射生成实例。 |
属性需要私有,对私有属性提供public的get和set | hibernate中获取,设置对象的值。 |
对持久化类提供唯一的标识oid与数据库主键对应 | java中通过对象的地址区分是否是同一个对象,数据库中通过主键确定是否是同一个记录。在hibernate中通过持久化类的oid的属性区分是否是同一个对象。 |
持久化类中属性尽量使用包装类类型 | 因为基本数据类型默认是0,0有很多歧义(比如不便于区分是未设值默认还是设为零);包装类数据类型默认值是null,避免与0区分不开。 |
持久化类不能用final修饰 | 延迟加载是hibernate的一个优化手段,返回的是一个代理对象(javassist可以对没有实现接口的类产生代理----使用非常底层的字节码增强技术,继承这个类进行代理)。如果不能被继承,就不能产生代理对象,延迟加载也就失效。load和get方法一致。 |
主键生成策略
主键的分类
– 自然主键:主键就是表中的一个字段(实体中的一个具体的属性),比如:身份证号。
– 代理主键:主键不是表中必须的一个字段(不是实体中的某个具体的属性)。
在实际开发中,尽量使用代理主键:因为一旦自然主键参与到业务逻辑中,后期就有可能需要修改源代码。
好的程序设计应遵循开放关闭原则(ocp),即对程序的拓展是open的,对修改源码是close的。
主键生成策略
在实际开发中一般不允许用户手动设置主键,一般将主键交给数据库或者手动编写程序进行设置。hibernate定义了多种主键生成策略。
increment
hibernate中提供的自动增长机制,适用于long,short,int类型的主键。只能在单线程程序中使用,否则易出现线程安全问题。
- 首先发送一条语句,select max(id) from 表;然后让id+1作为下一条记录的主键。
identity
适用于long,short,int类型的主键,使用的是数据库底层的自动增强机制。适用于有自动增强机制数据库(mysql,mssql)。但oracle没有自动增长。
sequence
适用于long,short,int类型的主键,采用的是序列的方式。(oracle支持序列)。但mysql等不能使用。sequence。
uuid
适用于字符串类型主键。使用hibernate中的随机方式生成字符串主键。
native
本地策略,可以根据底层数据库配置在identity和sequence之间自由切换。
assigned
hibernate放弃主键的管理,需要通过手动编写程序或者用户自己设置 。
foreign
外部的。一对一的一种关联映射的情况下使用。(了解)
生成策略的使用
持久化类的状态
三种状态的区分
状态间的转换
瞬时态对象
持久态对象
脱管态对象
持久态对象特性
- 不用写update方法,持久化对象已完成数据库更新。可通过debug模式断点查看。
- 当设置的属性新值和原值相等,将不进行数据库update操作。
- 依赖于hibernate的一级缓存。
hibernate的一级缓存
- 缓存:是一种优化方式,将数据存入内存,使用时直接从缓存中获取,不用通过存储器。
- hibernate的缓存:hibernate框架中提供了缓存和抓取策略的优化手段。其中缓存包括一级缓存和二级缓存(iduessionFactory级别的缓存,需要配置的缓存,现多用redis或spring替代)。
概述
- hibernate的一级缓存就是指session缓存,session缓存是一块内存空间,用来存放相互管理的java对象。
- 在使用hibernate查询对象的时候,首先会使用对象属性的OID值在hibernate的一级缓存中查找,如果找到匹配OID值的对象就直接将该对象从一级缓存中取出,不会查询数据库;否则,将去数据库查找相应数据,并放到一级缓存中。一级缓存的作用是减少对数据库的访问次数。
- 和session的生命周期一致。(一级缓存是由session和一系列java集合构成)。一级缓存是自带的不可卸载的。
一级缓存的快照区
快照区是一级缓存结构的特殊区域,可以比拟成拍的人像照片不会改变,可用来比较有无变化。
一级缓存的清除
采用session对象的clear方法,close方法等。
hibernate的其他API
持续学习才能提高
内容学习自黑马it