下面是我在学习Hibernate中总结的一些相关知识,希望对各位有所帮助。
一、什么是Hibernate?
1>Hibernate是一个面向Java环境的对象/关系数据库映射工具。
2>Hibernate不仅仅管理Java类的数据库映射,还提供数据查询和获取数据的方法。
3>Hibernate的目标是对于开发者通用的数据持久化相关的编程。
4>Hibernate是采用ORM模式实现数据持久层的一个优秀Java组件,它提供了强大 ,更高效的对Java对象进行持久化操作的服务。
基于Java的中间层应用场合中,Hibernate是最好的运用场合
c对于以数据为中心的程序来说,Mybatis是好的解决方案
二、Hibernate工作原理
1>通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件。
2>由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml">读取并解析映射信息。
3>通过config.buildSessionFactory(),创建SessionFactory。
4>通过sessionFactory.openSession(),打开Session。
5>通过session.beginTransaction(),创建事物Transaction。
6>persistent operate,持久化操作。
7>session.getTransaction().commit(),提交事物。
8>关闭Session。
9>关闭SessionFactory。
三、Hibernate优缺点
优点:
1>对JDBC访问数据库的代码做了封装,简化了数据访问层繁琐的重复性代码。
2>映射的灵活性,它支持各种关系数据库。
3>非入侵性,移植性很好。
4>缓存机制:提供一级缓存和二级缓存。
5>简洁的HQL编程。
缺点:
1>无法对SQL进行优化。
2>框架中使用ORM原则,导致配置过于复杂。
3>Hibernate在批处理数据时有弱势。
4>针对单一对象简单的CRUD,适合Hibernate,而对于批量的修改、删除,不适用于Hibernate。
四、什么是ORM?
对象关系映射(Object-Relational Mapping,简称ORM)
O:object对象,在业务逻辑层和表示层将各参与实体进行面向对象封装。
R:rational关系型数据
M:mapping映射
是一种为了解决程序的面向对象模型与数据库的关系模型互不匹配问题的技术;简单的说,ORM是通过使用描述对象和数据库之间映射的元数据(在Java中可以用XML或者是注解),将程序中的对象自动持久化到关系数据库中或者将关系数据库表中的行转换成Java对象,其本质上就是将数据从一种形式转换到另外一种形式。
五、Hibernate生成主键的方式
1>Assigned:由程序生成主键值,并且要在save()之前指定否则会抛出异常。
2>Hilo:使用高低位算法生成主键。
3>Increment:采用自动增长的方式生成新的主键值,但要求底层数据库支持Sequence。
4>Identity:用于MySql数据库。
5>Sequence:用于Oracle数据库。
6>Native:主键生成方式,会根据不同的底层数据库自动选择Identity,Sequence,Hilo等主键生成方式。
7>uuid:使用128位UUID算法生成主键。
8>Foreign guid:用于一对一关系共享主键时,两id值一样。
六、Hibernate的延迟加载机制
延迟加载就是并不是在读取的时候就把数据加载进来,而是等到使用时再加载。Hibernate使用了虚拟代理机制实现延迟加载,我们使用Session的load()方法加载数据或者一对多关联映射在使用延迟加载的情况下从一的一方加载多的一方,得到的都是虚拟代理,简单的说返回给用户的并不是实体本身,而是实体对象的代理。代理对象在用户调用getter方法时才会去数据库加载数据。但加载数据就需要数据库连接。而当我们把会话关闭时,数据库连接就同时关闭了。
延迟加载节省了服务器的开销,从而提高服务器的性能。
七、Hibernate的一级缓存、二级缓存和查询缓存
第一级别的缓存是Session级别的缓存:事物范围的缓存,由Hibernate管理。
Session调用方法时,Hibernate会把该对象加入到一级缓存中,短时间内再次调用同方法时,Hibernate直接从一级缓存中取,而不用访问数据库
第二级别的缓存就是SessionFactory级别的缓存:进程范围或者群集级别缓存,可以进行配置和更改。
同一个SessionFactory创建了某个session执行了相同操作,Hibernate直接从二级缓存中取结果,不用访问数据库。
一级缓存和二级缓存都是对整个实体进行缓存,不会缓存普通属性,如果希望对普通属性进行缓存,可以使用查询缓存。查询缓存是将HQL或SQL语句以及它们的查询结果作为键值对进行缓存,对于同样的查询可以直接从缓存中获取数据。查询缓存默认也是关闭的,需要显示开启。
应用场合:
很少被修改的数据
不是很重要的数据,允许出现偶尔并发的数据
不会被并发访问的数据
参考数据
不适合的数据:
经常被修改
财务数据,绝不允许出现并发
与其他应用共享的数据
八、什么是POJO,实体对象的三种状态
POJO:Hibernate操作的Java对象
1>瞬时(临时transient):不在session的管理之中,数据库中也没有oid。
2>持久(persistent):在session的管理之中。
3>托管(游离detached):不再session的管理之中,数据库中有oid。
瞬时态:当new一个实体对象后,这个对象处于瞬时态,即这个对象只是一个保存临时数据的内存区域,如果没有变量引用这个对象,则会被JVM的垃圾回收机制回收。这个对象所保存的数据与数据库没有任何关系,除非通过Session的save()、saveOrUpdate()、persist()、merge()方法把瞬时态对象与数据库关联,并把数据插入或者更新到数据库,这个对象才转换为持久态对象。
持久态:持久态对象的实例在数据库中有对应的记录,并拥有一个持久化标识(ID)。对持久态对象进行delete操作后,数据库中对应的记录将被删除,那么持久态对象与数据库记录不再存在对应关系,持久态对象变成移除态(可以视为瞬时态)。持久态对象被修改变更后,不会马上同步到数据库,直到数据库事务提交。
游离态:当Session进行了close()、clear()、evict()或flush()后,实体对象从持久态变成游离态,对象虽然拥有持久和与数据库对应记录一致的标识值,但是因为对象已经从会话中清除掉,对象不在持久化管理之内,所以处于游离态(也叫脱管态)。游离态的对象与临时状态对象是十分相似的,只是它还含有持久化标识。
九、什么是懒加载,session的get和load方法区别
懒加载(延迟加载):用的时候在加载
get():不支持懒加载
load():支持懒加载
十、session的save和saveOrUpdate方法区别
save():不管记录存在与否,直接保存
saveOrUpdate():如果记录不存在则保存,存在则进行更新
十一、关联关系映射
单向关联:在一方维护关联信息,在另一方不做处理。
many-to-one
one-to-many
双向关联:在关联的两方同时维护关联信息
举例:商品和订单、学生和课程都是典型的多对多关系
many-to-many
cascade="save-update":级联操作
inverse="true":依赖倒转,将控制权移交给权限多的另一方
十二、Log4J
是Apache的一个开放源代码项目,它是一个日志操作包
配置的内容:
根目录
目的地
输出样式
错误优先级:低——高
debug
info
warn
error
fatal
十三、opensession()和getCurrentSession()的区别
1>getCurrentSession()它会先查看当前线程中是否绑定了session,如果有则直接返回,没有在创建;opensession()则是直接new一个新的session并返回。
2>使用ThreadLocal来实现线程session的隔离。
3>getCurrentSession()在事务提交的时候会自动关闭session;opensession()需要手动关闭。
十四、Hibernate实现分页查询
通过Hibernate实现分页查询,开发人员只需要提供HQL语句(调用Session的createQuery()方法)或查询条件(调用Session的createCriteria()方法)、设置查询起始行数(调用Query或Criteria接口的setFirstResult()方法)和最大查询行数(调用Query或Criteria接口的setMaxResults()方法),并调用Query或Criteria接口的list()方法,Hibernate会自动生成分页查询的SQL语句。
十五、Hibernate查询数据的方式
1>HQL查询
2>QBC查询
3>SQL查询
因为是初学者,所以难免有所疏漏和不足,欢迎大牛们指正。