持久化概念: 数据从内存到硬盘进行永久保存
持久层框架:
mybaits(ibaits),hibernate
mybaits对数据的操作对应的表和表的列(insert,update,delete,select)
hibernate对应的是实体(添加:save(),删除delete(),更新:update(),查询:get(),load()) Entity
hibernate 对外只提供一个session对象,
支持hql(实体的关联关系)语言,同时也支持sql
hibernate缺点
1.不适用于批量数据操作
2.一个实体只能映射到一张表,不能映射多张表
Hibernate 提供的API
JDBC:事务随session的生成,自动开启,session的关闭,事务自动提交
HIbernate:
Congiguration:解析配置文件
SessionFactory 线程安全的,全局只有一个
Session 是线程不安全的,需要的时候需要创建一个新的session,使用完毕以后要关掉
Transaction:事务是手动的,必须通过session手动开启,只有开启事务以后,才能进行,save,update,delete(select除外)
框架搭建:
1.创建项目
2.导入jar包
3.创建hibernate.cfg.xml配置数据源<session-Factory>
全局配置文件:hibernate.cfg.xml
<session-factory>
<!-- 配置oracle驱动 -->
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<!-- 连接的url -->
<property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
<!-- 用户名 -->
<property name="hibernate.connection.username">scott</property>
<!-- 密码 -->
<property name="hibernate.connection.password">123456</property>
<!-- 配置session的获取方式 currentSession-->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
<!-- 是否输出打印sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 输出打印sql语句的格式化-->
<property name="hibernate.format_sql">true</property>
<!-- 是否创建表-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 注册实体的映射文件 -->
<mapping resource="com/yh/po/User.hbm.xml"/>
</session-factory>
hibernate.hbm2ddl.auto参数的作用主要用于:自动创建|更新|验证数据库表结构。如果不是此方面的需求建议set value="none"。
create:
每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
create-drop :
每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。
update:
最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构,以后加载hibernate时根据 model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等 应用第一次运行起来后才会。
说明:
<property name="hibernate.hbm2ddl.auto">update</property>
一般,做项目期间 开始创建表时,将hibernate.hbm2ddl.auto 的值设置为update, 当表建完时,将其属性值修改为none;
实体文件配置:
实体(pojo):对应的是表
实体的属性对应的表的列
Hibernate实体:必须有一个主键,标示实体的唯一性
Id 配置
<id name="id" type="int">
<column name="ID" />
<!-- <generator class="sequence" />hibernate取调用名字默认叫hibernate_sequence的序列,需要取数据库创建该名字的序列 -->
<generator class="sequence"> <!--不同数据库 取值不同;sqlserver :identity; mysql:increment;oracle:sequence;-->
<param name="sequence">seq_user</param> <!-- 指定序列 数据库中必须定义该序列-->
</generator>
<!-- <generator class="assigned"></generator> 应用指定id -->
</id>
<!--property name:实体对应的属性名称column name:对应的表列名-->
<property name="userName" type="java.lang.String">
<column name="user_name" />
</property>
Hibernate提供了多种内置的设定标识符生成器
Class取值: mysql:increment
Sql server :identity
Oracle :sequence :
native根据底层数据库,自己选择标示符生成器的方式
1.hibernate 默认会去oracle找一个hibernate_sequence的序列,你需要取oracle数据库创建一个名字叫hibernate_sequence的序列
2.自己去指定序列的名称
Hibernate配置文件的解析 核心类:
1.
//1.创建一个解析配置文件的Configuration对象 configure() 默认会去src下找一个叫hibernate.cfg.xml的配置文件
Configuration configuration=new Configuration().configure();
//2.创建数据源代理
SessionFactory sessionFactory=configuration.buildSessionFactory();
/*
//采用默认配置 src文件下的hibernate.cfg.xml
//configuration = new Configuration().configure();
//采用非默认配置 src文件下com.hu.db 包下的hibernate.xml文件配置
configuration = new Configuration().configure("com/hu/db/hibernate.xml");
ServiceRegistry serviceRegistry = (ServiceRegistry) new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
*/
//3.得到一个session对象 sessionFactory 的openSession()
Session session=sessionFactory.openSession();
// Session session = sessionFactory.getCurrentSession();
//4.开启事务 session.beginTransaction()
Transaction tx=session.beginTransaction();
//5.提交事务
tx.commit();
//6.事务回滚
tx.rollback();
//7.关闭session
session.close();
Session作为贯穿Hibernate的持久化管理器的核心,提供了众多持久化方法,如save()、delete()、update()、get()、load()等。
Hibernate 查询:根据id查询实体
get():当查询到id不存在时,返回null,不会发生异常信息 当用Session session = sessionFactory.getCurrentSession();获得的session不能使用get()方法进行数据库查询
load():当查询到id不存在时,报异常信息
Hibernate 增加:
Hibernate中load一个对象跟get一个对象是有区别的。简单的说,load出来的是一个代理对象,而get出来是实实在在的POJO对象。也说是,load的过程做了延迟加载(Hibernate:lazy initializer proxy)。待用到这个对象的问题才去查询数据库,把记录放到对象中。在此,Hibernate不向数据库发SQL,这是load与get的区别。
Hibernate动态代理并不是用Java原生的方式,而是用了Javassist。Javassist可以直接操纵字节码,因此它用代理的效率会高一些
Hibernate 获取session的两种方式
openSession()
getCurrentSession() 需要在配置文件里配置,只能在事务环境下(事务提交/回滚)使用,事务提交或回滚以后session自动关闭。
current_session_context_class 取值value:thread,jta
事务有两种:jdbc ,jta(配置多数据源的环境下,跨数据库)
Jdbc对事务的操作:
自动:
手动:setAutoCommit(false)
提交/回滚
缓存:
一级缓存:基于事务的,基于session的
二级缓存: