Hibernate
Hibernate核心技术:
1、 理论基础:分析操作数据库的三个阶段,由操作JDBC、封装JDBC到ORM。讲解ORM对象关系映射理论知识,并由此过渡到Hibernate的持久层概念
2、 Hibernate开发流程:安装Hibernate、Hibernate配置文件、编写映射文件、编写持久化类、编写HibernateSessionFactory辅助类、编写DAO类和Service类
3、 Hibernate映射文件开发:Hibernate各元素的配置
4、 Hibernate核心类用法:Hibernate核心类的使用,类的调用顺序依次为Configuration、SessionFactory、Session、Transaction、Query、Criteria,包括数据库的操纵、查询、条件查询、本地SQL查询及事务的使用。
ORM(Object Relational Mapping)对象关系映射。为了解决面向对象与关系数据库存在的互不匹配的现象的技术。实现数据表到Java对象的映射
逻辑理解:
持久化就是对数据和程序状态的保持,而持久层是一个在系统逻辑层面上用来实现数据持久化的一个相对独立的领域
主键生成机制:
对于大部分常用数据库 对于主键生成机制大部分为Auto-Increase方式所以绝大部分Hibernate映射文件配置主键生成方式多采用native。而对于一些Insert操作较多的数据,相应的表采用uuid.hex作为主键生成机制(uuid.hex:基于128位唯一值产生算法UUID生成十六进制数值作为主键,UUID包含:IP地址,jvm的启动时间(精确到1/4秒))
Hibernate ant映射文件自动生存:
(使用的是Middlegen-Hibernate-r5、apache-ant-1.8.4-bin)
1、 配置ant(环境变量配置ANT-HOME、path(ant bin路径))
2、 配置Middlegen(添加数据库驱动包、配置相应的数据库映射文件如:mysql.xml、修改目录下的build.xml
3、 在命令行下进入Middlegen-Hibernate-r5路径下,然后执行 ant file-build.xml
4、 点击generate
5、 OK
Hibernate核心类简介及作用介绍:
1、 基础操作类
1) Session(Session接口是负责用来执行持久化对象的,通过SessionFactory获得Session对象,且Session对象是非线程安全的)
- i. 对数据库操作方法有save()保存、load()装载、get()装载、flush()强制提交刷新、update()提交游离状态对象、delete()移除持久化对象、refresh()强制装载对象
2) Transaction(Transaction是负责事务相关操作的)
3) SessionFactory(SessionFactory负责初始化Hibernate。它充当数据源的代理并且负责创建Session)
- i. 在使用SessionFactory时为了避免重复实例可设置该实例为静态实例并通过Threadlocal线程来过渡Session获得,一个线程的用户产生一个Session用例
- ii. ThreadLocal机制:ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序,ThreadLocal并不是一个Thread,而是Thread的局部变量。
4) Configuration(Configuration是负责配置并启动Hibernate,并创建SessionFactory对象,在Hibernate启动过程中Configuration实例首先负责定位映射文件、读取配置然后创建SessionFactory)
Configuration加载方式主要有三种:
- 使用hibernate.cfg.xml 该文件设置了数据库连接和映射文件位置
- 使用hibernate.properties配置文件,与第一种不同的是需要指定POJO类(就是持久化类)
- 使用硬编码设置 如:Configuration.addClass().setProperty().setProperty()
5) Query和Criteria:(Query和Criteria是两种不同的数据库查询方式,它们分别使用Hql和Sql两种表达方式
Hql:
From Object as obj where obj.XXX=?
集合映射:Set,List,Map
级联和关系维护:
Cascade对主对象操作时是否对其关联的从对象进行相同操作
(none,all,save-update,delete……)
一般在<one-to-one><one-to-many>这样的关系上进行级联
Inverse和Cascade区别:
Cascade适合所有关联关系而Inverse是一对多的情况下放弃对多的关联关系的维护
继承映射:
三种方式:
1、每个类分层结构一张表(table per class hierarchy)
规则:父类由普通的<class>标签定义 且定义一个<discriminator>标签区分字段名称和类型
子类标签为<Subclass>标签定义 且有一个discriminator-Value标明子类的字段名称和类型 可以父类Class并行或被包含 不平行时子类须 有一extends属性
2、每个子类一张表(table per subclass)
父类同上 只是没有discriminator标签区分
子类有Union-class标签定义 每个子类对应一张表 且包含所有属性 包过继承过来的
3、每个具体类一张表(table per concrete class)
父类定义同上 但表包涵所有父类和子类的记录
子类只定义特有的属性 但需有以<key>标签 用来标明与父类关联属性 其他一样
懒加载:
Session.load():Hibernate.initialize(object);初始化懒加载对象
缓存:
Hibernate一级缓存:get、load都从缓存里拿
Query 是从数据库里查的 uniqueResult();
所有的增删改查都会把数据放入缓存 能拿的只有get和load
二级缓存 :对缓存的扩展
配置:
分布式缓存和中央缓存:
使用条件:读取大于修改、数据量不大、要有对数据的控制权、可以容忍出现冗余数据
事务:
JTATransaction(跨数据库事务):由JTA容器实现
事务边界:通过两种方式管理1)ThreadLocal 2)JTA容器
Session内部缓存:
对于大批量数据处理容易造成内存溢出:为此可以调用Session.flush()与数据库同步更新再清理Session的一级缓存 Session.clear();
无状态Session:StatelessSession接口(不与一级缓存、二级缓存等相交互)
Hibernate动态查询:
N+1次查询
1、Iterate()查询:会先按条件查询符合条件ID然后根据ID先后查询一级缓存、二级缓存、数据库,直到查到数据(比较适合查询有一级或二级缓存的情况)
2、由于懒加载造成N+1次查询
在需要时获取关联对象
本地sql查询与命名查询
本地sql:Query query=Session.createSqlQuery(“sql语句”);
命名查询:1、在映射文件中配置命名sql语句
2、在查询中Query query=Session.getNamedQuery(”命名sql语句”)