Hibernate知识点.docx
- 文档编号:28323093
- 上传时间:2023-07-10
- 格式:DOCX
- 页数:38
- 大小:31.29KB
Hibernate知识点.docx
《Hibernate知识点.docx》由会员分享,可在线阅读,更多相关《Hibernate知识点.docx(38页珍藏版)》请在冰豆网上搜索。
Hibernate知识点
1什么是Hibernate
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
Hibernate可以应用在任何使用JDBC的场合
,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任
2Hibernate的核心类和接口:
<1>Configuration
负责管理Hibernate的配置信息,这些配置信息都是从配置文件hibernate.cfg.xml或者
Hibernate.properties读取的,当然也可以自定义文件名称,只要在实例化Configuration
的时候指定具体的路径就可以了
<2>SessionFactory
Configuration的实例会根据当前的配置信息,构造SessionFactory实例。
SessionFactory是线程安全的,一般情况下一个应用中一个数据库共享一个SessionFactory实例。
<3>Session
一般的持久化方法(CRUD)都是通过Session来调用的,Session是非线程安全的
<4>Transaction
事务管理
<5>Query
查询的接口
3Hibernate的原理及步骤
1.读取并解析配置文件
//采用默认的hibernate.cfg.xml来启动一个Configuration的实例
例:
Configurationconfiguration=newConfiguration().configure();
//如要修改默认配置文件名当然你可以选择不修改
Configurationconfiguration=newConfiguration().configure(newFile("src/xxx.xml"));
2.读取并解析映射信息,创建SessionFactory
例:
SessionFactory sessionFactory=configuration.buildSessionFactory();
3.打开Session实例(它是线程不安全的,是共享同一个session,所以要ThreadLocal模式来控制)
例:
Sessionsession=sessionFactory.openSession();
4.创建事务Transaction
例:
Transactiontransaction=(Transaction)session.beginTransaction();
5.CRUD操作(执行数据操作CRUD增删查改)
例:
增加
session.save(pojo对象);
增加或者修改
session.saveOrOpdate(pojo对象)//当修改时候,id不存在将被抛出异常
删除
session.delete(pojo对象)
//根据主键加载
p1=(Person)session.load(pojo类.class,主键值);
6.提交事务
例:
mit();
7.关闭Session实例及SessionFactory
例:
session.close();
sessionFactory.close();
4.Session的管理
Session是Hibernate运作的中心,对象的生命周期、事务的管理、数据库的存取,都与Session息息相关,
就如同在编写JDBC时需关心Connection的管理,以有效的方法创建、利用与回收Connection,以减少资源的消耗,
增加系统执行效能一样,有效的Session管理,也是Hibernate应用时需关注的焦点。
Session是由SessionFactory所创建,SessionFactory是线程安全的(Thread-Safe),您可以让多个
线程同时存取SessionFactory而不会有数据共享的问题,然而Session则不是设计为线程安全的,所以试图让
多个线程共享一个Session,将会发生数据共享而发生混乱的问题。
在各种Session管理方案中,ThreadLocal模式得到了大量使用。
ThreadLocal是Java中一种较为特殊的
线程绑定机制。
通过ThreadLocal存取的数据,总是与当前线程相关,也就是说,JVM为每个运行的线程,
绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制。
首先,我们需要知道,SessionFactory负责创建Session,SessionFactory是线程安全的,多个并发线程
可以同时访问一个SessionFactory并从中获取Session实例。
而Session并非线程安全,也就是说,如果
多个线程同时使用一个Session实例进行数据存取,则将会导致Session数据存取逻辑混乱
5 Hibernate三种查询方式1hql2qbc《qbe ---querybyexample》3sql
1.hql
1.1冒号法
Queryquery=session.createQuery("fromPersonpwherename=:
xxx");//from后面跟的是PO对象名,而不是表名
query.setString("xxx","ttt");
List
for(Personp:
list)
System.out.println(p.getName())
1.2问号法
Queryquery=session.createQuery("fromPersonpwherename=?
");
query.setString(0,"ttt");
List
for(Personp:
list)
System.out.println(p.getName())
模糊查询举例
问号法
Queryquery=session.createQuery("fromPersonpwherenamelike?
");
query.setString(0,"%a%");
冒号法
Queryquery=session.createQuery("fromPersonpwherenamelike:
xxx");
query.setString("xxx","%w%");
2.QBC( querybyCriteria)
Criteria接口与DetachedCriteria(二者的区别就是DetachedCriteria可以离线操作,而Criteria不可以)
<1>利用Restrictions进行条件筛选
方法 說明
Restrictions.eq等於
Restrictions.allEq使用Map,使用key/value進行多個等於的比對
Restrictions.gt大於>
Restrictions.ge大於等於>=
Restrictions.lt小於<
Restrictions.le小於等於<=
Restrictions.between對應SQL的BETWEEN子句
Restrictions.like對應SQL的LIKE子句
Restrictions.in對應SQL的in子句
Restrictions.andand關係
Restrictions.oror關係
Restrictions.sqlRestrictionSQL限定查詢
<2>criteria.addOrder(Order.asc("id"));//排序
举例1
Criteriacriteria=session.createCriteria(Person.class);
criteria.add(Restrictions.like("name","ad%")); //模糊查询,姓名以ad开头,注意要加%号
criteria.add(Restrictions.between("age",20,30)); //年龄在20到30之间
criteria.addOrder(Order.asc("id"));//
List
for(Personp:
list){
System.out.println(p);
}
上面是与查询,如果是或查询 查询等于20或者或者年龄为空的记录
Criteriacriteria=session.createCriteria(User.class);
criteria.add(Restrictions.or(
Restrictions.eq("age",newInteger(20)),
Restrictions.isNull("age")
));
Listusers=criteria.list();
DetachedCriteria使用 //?
离线操作的意义何在?
DetachedCriteriadc=DetachedCriteria.forClass(Person.class);
dc.add(Restrictions.eq("name","aaa"));
List
for(Personp:
list){
System.out.println(p.getId());
}
3.Sql
<3.1>采用addScalar方法一个字段一个字段指定类型
SQLQuerysQLQuery=session.createSQLQuery("select*fromuser"); //普通的SQL语句
sQLQuery.addScalar("id",Hibernate.INTEGER);
sQLQuery.addScalar("name",Hibernate.STRING);
List
for(Object[]object:
list){
System.out.println(Arrays.toString(object)); //在这里可以根据自己的需要,进行封装
}
<3.2>采用addEntity方法 如果想返回的是list里是person对象
SQLQuerysQLQuery=session.createSQLQuery("select{person.*}fromperson");//注意这里的语法{person.*}
sQLQuery.addEntity("person",Person.class);
sQLQuery.addScalar("id",Hibernate.INTEGER);
sQLQuery.addScalar("name",Hibernate.STRING);
List
for(Personobject:
list){
System.out.println(object);
}
总结:
不管是SQL还是HQL,当你查询出来的不是整个对象,而是其中的某些字段,或者说:
当几个表关联查询的时候,取二个表中的某些字段,
返回的不是一个封装好的对象的List集合,那么这个List里到底是什么东西呢,这里分为两种情况
<1>如果只有一个字段,list里每个元素都是Object
<2>如果多于一个字段,list里每个元素都是Object[],所以,这时候就需要自己去封装对象了,将object数组中的元素迭代出来,
然后封装到一个对象里。
三种查询方式优缺点
HQL功能最强大,适合各种情况,但是动态条件查询构造起来很不方便
Criteria最适合动态条件查询,不太适合统计查询,QBE还不够强大,只适合相当简单的查询
NativeSQL可以实现特定数据库的SQL,但是可移植性就牺牲了
利用Query接口的setMaxResults方法表示一次从list里拿多少条记录 通常用于分页中
6.pojo的3种状态
瞬态 持久化 托管(离线)
一个PO有三种状态:
1、未被持久化的VO
此时就是一个内存对象VO,由JVM管理生命周期
2、已被持久化的PO,并且在Session生命周期内
此时映射数据库数据,由数据库管理生命周期
3、曾被持久化过,但现在和Session已经detached了,以VO的身份在运行
这种和Session已经detached的PO还能够进入另一个Session,继续进行PO状态管理,此时它就成为PO的第二种状态了。
这种PO实际上是跨了Session进行了状态维护的。
在传统的JDO1.x中,PO只有前面两种状态,一个PO一旦脱离PM,就丧失了状态了,不再和数据库数据关联,成为一个纯粹的内存VO,它即使进入一个新的PM,也不能恢复它的状态了
POJO
POJO
一种纯粹的java,即private属性及对这个属性的get/set方法,不实现,不继承任何java框架的接口,类。
PO
持久对象,,
有时也被称为Data对象,对应数据库中的entity,可以简单认为一个PO对应数据库中的一条记录。
在hibernate持久化框架中与insert/delet操作密切相关。
PO中不应该包含任何对数据库的操作。
可以是由POJO发展而来
POJO(plainoldjavaobject)-------->PO(persistanceObject)
POJO是沒有状态的,加了状态之后就变成了PO(POJO+xml就是PO);
7HIbernate主键详解
1.Assigned
Assigned方式由程序生成主键值,并且要在save()之前指定否则会抛出异常
特点:
主键的生成值完全由用户决定,与底层数据库无关。
用户需要维护主键值,
在调用session.save()之前要指定主键值。
主键由外部程序负责生成,无需Hibernate参与。
2.Hilo
Hilo使用高低位算法生成主键,高低位算法使用一个高位值和一个低位值,
然后把算法得到的两个值拼接起来作为数据库中的唯一主键。
Hilo方式需要额外的数据库表和字段提供高位值来源。
默认请况下使用的表是通过hi/lo算法实现的主键生成机制,
需要额外的数据库表保存主键生成历史状态。
3.hibernate_unique_key
默认字段叫作next_hi。
next_hi必须有一条记录否则会出现错误。
特点:
需要额外的数据库表的支持,能保证同一个数据库中主键的唯一性,
但不能保证多个数据库之间主键的唯一性。
Hilo主键生成方式由Hibernate维护,
所以Hilo方式与底层数据库无关,但不应该手动修改hi/lo算法使用的表的值,
否则会引起主键重复的异常。
4.Increment
Increment方式对主键值采取自动增长的方式生成新的主键值,但要求底层数据库的支持Sequence。
如Oracle,DB2等。
需要在映射文件xxx.hbm.xml中加入Increment标志符的设置。
特点:
由Hibernate本身维护,适用于所有的数据库,不适合多进程并发更新数据库,
适合单一进程访问数据库。
不能用于群集环境。
主键按数值顺序递增。
此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,
之后每次需要生成主键的时候将此值加1作为主键。
这种方式可能产生的问题是:
如果当前有多个实例访问同一个数据库,那么由于各个实例各自维护
主键状态,不同实例可能生成同样的主键,从而造成主键重复异常。
因此,如果同一数据库有多个
实例访问,此方式必须避免使用。
5.Identity
Identity当时根据底层数据库,来支持自动增长,不同的数据库用不同的主键增长方式。
特点:
与底层数据库有关,要求数据库支持Identity,如MySQl中是auto_increment,SQLServer
中是Identity,支持的数据库有MySql、SQLServer、DB2、Sybase和HypersonicSQL。
Identity无需Hibernate和用户的干涉,使用较为方便,但不便于在不同的数据库之间移植程序。
采用数据库提供的主键生成机制。
如DB2、SQLServer、MySQL中的主键生成机制。
6.Sequence
Sequence需要底层数据库支持Sequence方式,例如Oracle数据库等
特点:
需要底层数据库的支持序列,支持序列的数据库有DB2、PostgreSql、Qracle、SAPDb等在不
同数据库之间移植程序,特别从支持序列的数据库移植到不支持序列的数据库需要修改配置文件
采用数据库提供的sequence机制生成主键。
如Oralce中的Sequence。
与hilo类似,通过hi/lo算法实现的主键生成机制,只是主键历史状态保存在Sequence中,
适用于支持Sequence的数据库,如Oracle。
7.Native
Native主键生成方式会根据不同的底层数据库自动选择Identity、Sequence、Hilo主键生成方式
特点:
根据不同的底层数据库采用不同的主键生成方式。
由于Hibernate会根据底层数据库采用
不同的映射方式,因此便于程序移植,项目中如果用到多个数据库时,可以使用这种方式。
由Hibernate根据底层数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式。
8.uuid.hex
UUID使用128位UUID算法生成主键,能够保证网络环境下的主键唯一性,也就能够保证在不同
数据库及不同服务器下主键的唯一性。
特点;能够保证数据库中的主键唯一性,生成的主键占用比较多的存贮空间
由Hibernate基于128位唯一值产生算法生成16进制数值(编码后以长度32的字符串表示)作为主键。
9.ForeignGUID
Foreign用于一对一关系中。
GUID主键生成方式使用了一种特殊算法,保证生成主键的唯一性,
支持SQLServer和MySQL
使用外部表的字段作为主键。
一般而言,利用uuid.hex方式生成主键将提供最好的性能和数据库平台适应性。
10.uuid.string
与uuid.hex类似,只是生成的主键未进行编码(长度16)。
在某些数据库中可能出现问题(如PostgreSQL)。
8在Hibernate应用中如何处理批量更新和批量删除?
---executeUpdate()方法支持
Hibernate3.0对批量更新和批量删除提供了支持,能够直接执行批量更新或批量删除语句,无需把被更新或删除的对象先加载到内存中。
以下是通过Hibernate3.0执行批量更新的程序代码:
Sessionsession=sessionFactory.openSession();
Transactiontx=session.beginTransaction();
StringhqlUpdate="updateCustomersetname=:
newNamewherename=:
oldName";
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Hibernate 知识点