Hibernate课堂讲课知识点总结

Hibernate课堂讲课知识点总结:
一. hibernate基础知识
二. hibernate一对一映射
三. hibernate一对多(多对一)映射
四. hibernate多对多映射
五. hibernate的HQL检索学习
一. Hibernate基础知识
1. hibernate:hibernate就是一个可以自动的根据xml或annotation完成对象关系映射(orm),并持久化到数据库的开源框架。是连接java应用程序和关系数据库的中间件,这是对JDBC的封装,主要负责java对象的持久化。
2. ORM(Object Relation Mapping)对象关系映射是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。
3. hibernate映射文件:
    它的作用是描述持久层对象以及让他们的属性和数据库中的表和表的字段之间的对应关系。没有映射文件,Hibernate系统无法完成Java对象和数据库表中的数据的相互转化。只有通过映射文件,Hibernate才能知道所操作的对象与哪个表相关联。
4. hibernate.cfg.xml文件中包含了hibernate与数据库的基本连接信息。在Hibernate工作的初始阶段,由Configuration的对象开启hibernate框架,然后将信息加载到SessionFactory实例中。
5. SessionFactory是Hibernate中的一个类,这个类主要负责保存Hibernate的配置信息,以及对Session的操作。
6. 手动创建hibernate框架的步骤:
a)   拷贝所需Jar包到lib目录下,基本包含(antlr.jar,cglib.jsr,asm.jar,commons-collections.jar,commons-logging.jar,jta.jar,dom4j.jar,hibernate3.jar,hibernate-annotations.jar)
b) 在src目录下创建一个hibernate.cfg.xml文件,该文件包含了hibernate与数据库连接的基本连接信息。在Hibernate工作的初始阶段,这些信息被先后加载到Configuration和SessionFactory实例。
c) 创建一个User.hbm.xml(类名.hbm.xml)。包含Hibernate的基本映射信息,即系统中每一个类与其对应的数据库表之间的关联信息,在Hibernate工作的初始阶段,这些信息通过Hibernate.cfg.xml的mapping节点被加载到Configuration和SessionFactory实例。
7. Hibernate关联映射:一对一:由数据库中共享主键实现(A表一行记录对应B表一行记录)。一对多:由外键约束实现(A表中一行记录对应B表中多行记录)。多对多:中间表约束实现(需要产生一个中间表,两个表与中间表的关联关系为一对多)。
8. hibernate级联关系映射叫高级映射,Hibernate是用于控制类的而不是表。级联关系在类中配置由映射文件进行描述。要想让表有关系,必须让两个类有关系。
9. 高级映射第一点:开启Hibernate的级联关系映射。两个类之间靠互换实例来进行关系访问。(实例主要用来负责级联操作)。
10. 实体对象的三个生命周期:
  所谓的Hibernate实体对象的生命周期就是指Hibernate的实体对象在整个应用中的存在状态。实体对象的生命周期中主要存在三种不同的状态,他们分别是:Transient(瞬态),Persistent(持久态),Detached(游离态),这三种状态的定义与所谓的持久化上下文(persistence context)有关,Hibernate的Session对象就是这个所谓的持久化上下文。
11. Hibernate中load()和get()的异同
相同点:功能上是一样的全是通过该对象的标示符来得到一个持久化对象,可以理解为根据id加载一个对象。
不同点::区别在于返回值的差异,load()如果没有找到该对象的时候它是抛出异常的,而get()如果没有找到该对象将会返回null。Session.get()不支持数据缓存,永远查询数据库。Session.load()支持数据缓存,查询的内存
12. 完成一次Hibernate框架启动的七个步骤:
1创建Configuration对象(Configuration conf=new Configuration();conf.configure();主要作用配置和启动Hibernate框架,读取Hibernate.cfg.xml核心配置文件)
2.创建SessionFactory对象
3.通过SessionFactory对象创建Session对象
4.通过Session开启一个事物并得到一个Transaction对象(Transaction对象主要适用于事务管理,一个事务对象可能包括多个数据库进行操作) 
5.通过Session与数据库进行会话及持久化操作
6.提交操作结束事物提交事务
7.关闭Session释放资源
13. hibernate生成数据库表的两种方式:
第一种:Configuration cfg = new Configuration().configuration();
        SchemaExport export = new SchemaExport(cfg);
        Export.create(true,true);//参数一是否发送Hibernate自定义的建表脚本到数据库中,参数二是否让数据库执行发送过去的脚本。
第二种:通过保存数据用Save(对象名)方法。
14. 持久化信息的方法:
i. 创建一个Configuration对象:Configuration  conf = new  Configuration();
ii. 通过Configuration对象的configure()方法加载Hibernate配置文件。conf.configure();
iii. 创建一个SessionFactory实例SessionFactory factory = conf.buildSessionFactory();
iv. 通过SessionFactory实例创建Session实例 Session sion = factory.openSession();
v. 通过Session实例开启事务,得到事务对象。Transaction tran = sion.beginTransaction();
vi. 使用Session实例的save()方法,传入实体类对象,将User对象持久化。
Sion.save(Object);
Tran.commit();
vii. 在创建Session实例后,不论是否执行事务,最后都需要关闭Session实例,释放Session实力占用的资源。Session.close();
二. Hibernate一对一映射(人与身份证的关系)
1. 一对一关联映射:可分为主键关联映射和唯一外键关联映射(是多对一的一种特殊表现形式)两种,同时,这两种关联映射又分为单向关联和双向关联。
2. 单向一对一主键关联映射:在任意一方存储另一方的实例对象。一对一级联关系创建及配置的标记用<one-to-one />标签.
3. 双向一对一主键关联映射:双方需要分别存入对方的实力对象。
4. <one-to-one />标签中的常用属性解析
(1) name:<one-to-one />的级联关系需要name指定的成员来实现。
(2) class:为指定的对象类。
(3) constrained=”true”:添加数据库底层约束。表明A表对象必须和一个B表对象关联,也就是说A对象中的B属性不能为空。
(4) fetch:控制两表连接查询。
三. Hibernate一对多(多对一)映射(班级和学生的关系)
1. 一对多(save一方):在多方为一方创建外键。注意:一对一靠类中的对象实现,一对多需要靠容器(集合)实现,在这里我们选择Set集合,因为Set不能存入重复值。并且set中有HashSet,可以用Hash算法辅助数据库查询。一对多级联关系创建及配置的标记用<set />标签中的<one-to-many />标签
2. 一对多级联配置文件的例子:
<set name=”student” cascade=”all”>
  <key column=”classes_id”></key>
  <one-to-many class=”Student”/>
</set>
3. 注意:当一方操作多方的时候(级联关系由一方维护)做添加的时候有7个SQL语句(注意此时的SQL语句数量根据你插入的信息数来看,如果你插入两条信息则是5个SQL语句。如果你插入三条信息则是7个SQL语句)可以用2n+1这个算法来计算产生的SQL语句数。(n表示添加的信息条数)
4. 当一方操作多方时有两个问题:
    第一:当一方操作多方的时候(级联关系由一方维护)做添加的时候有2n+1个SQL语句。(n表示添加的信息条数)
第二:外键不允许为空(null)的时候一方无法操作多方。
5. 对多对(save多方):在多的一方存入一方的类对象。
6. 注意:进行多对一操作时,此时多方需要给自己添加一个外键,即在<many-to-one></many-to-one>中加一个column,<many-to-one name=”classes” class=”Classes” column=”classes_id”></many-to-one>,这里的外键(column)的值最好和在一方的映射文件中的<key />标签的column值相同。
7. 瞬时状态异常产生的原因(一对多和多对多经常出现):数据库中无存入的信息。即操作不级联时会产生瞬时状态异常。此时应设置cascade属性值为all,注意cascade的属性值应该谨慎设置。
8. 当多方操作一方的时候昨天加的时候出现4个SQL语句,因为多方不需要额外拼写修改外键的语句。
9. 双向级联关系:(在双向一对多的时候,一方和多方都需要配置外键,并且两个外键的名字相同。)当双方的关系都存在的时候,Hibernate框架默认选择一方为级联关系的主控方(一对多)。因此,如果希望让多方来维护,则要在一方的映射配置文件中的<set />标签中添加inverse属性值为true。
10. inverse=”true” 属性表示让当前一方反转出级联关系的主控权。由多方来维护级联关系。Inverse属性设置在集合类中,而<many-to-many>和<one-to-one>则无此属性.
11. 注意:多方控制级联关系的性能强于一方,并且双向级联时双方的策略都需要存在。
12. Cascade是Hibernate提供的级联方案。Cascade=“all”表示无论何时(无论什么操作)都产生级联操作。Cascade属性是设置级联操作的也就是在操作一端的数据如果影响到多端数据时会进行级联操作。默认cascade=”none”。使用该属性时应该慎重(比如在进行删除操作时最好将Cascade的属性值设置为save-update)
13. 延迟加载:
延迟加载策略:设置延迟加载策略时需要把抓取策略删除即fetch=”join”删除。Lazy=”true”延迟加载策略(此时为懒的状态)。//一般为此状态Lazy=”false”(此时为不懒的状态),只要类被加载则和其有级联关系的类也会被加载。
Lazy会照成性能的损耗。
延迟加载是Hibernate为了解决性能问题而出现的。
Lazy属性值为true时,该属性的值不会被立刻加载,只有在真正的读取该属性的值时,其值才会真正的从数据库中读取,这在处理大型字段时非常有用。例如:在用户信息表中可能有一个很长的用户简介字段,但在很多情况下并不需要显示和处理这个字段,所以可以将其Lazy属性的值设置为true。以避免每次读取这个对象的时候都将用户的简介字段读出。
四. Hibernate多对多映射(用户和角色)
1. 多对多(用户和角色):两个表本身都无法描述他们的多对多关系。此时需要通过第三张表进行多对多描述,此时即产生一张中间表。注意:需要在A表中和B表中分别存入以双方为泛型的Set集合对象。 
2. 中间表:中间表中存储的是A类和B类的主键,在中间表中当外键。
3. 多对多和一对多操作中<key />标签的区别:<key />标签用来为别的表产生外键。在多对多中,<key />标签用来指定该持久类为中间表创建的外键名。在一对多中,<key />标签用来指定一方为多方创建的外键名称。
4. <man-to-many />标签和<many-to-one />标签中column的区别:<many-to-many>中的column代表在中间表中生成的外键。<many-to-one />中的column代表在本表中生成的外键名。即在多方生成的外键名称。
5. 在配置多对多关系时应注意:
第一:双方的set都必须指定table,而且table名字必须一致。
第二:双方都有key标记,单独一方的key标记中的column的名字,应该对应另外一方的<many-to-many />标签中column名字。
注意:如果table不一样,会产生两个中间表。Column值不一样会在中间表中产生四个外键。
6. 注意:对多对和多对一操作时,只操作单一的一方即可,一对多时如果是双向级联,则需要添加双方的级联策略。
五. Hibernate的HQL检索学习
1. HQL查询:连接查询在项目开发中是非常常用的技术,Hibernate推出了HQL查询,它提供了更加丰富和灵活的查询特性,同时也提供了更加面向对象的封装。HQL查询非常类似于标准SQL查询。HQL查询在整个Hibernate实体操作体系中占据核心地位,我们可以通过实体查询,实体的更新和删除,属性查询,分组与排序,参数绑定来体验HQL的实际应用。
2. Hibernate框架的六种检索方式:
  第一种:OID(Object ID)检索方式,session的get()和load()方法。该种检索方式一般为单条检索,id不能重复。相当于Select * from where id=?
第二种:HQL检索方式,(出现复杂查询时使用),它是一种语法类似于SQL,但是,是面向对象的查询语言。SQL语言面向的数据库。
第三种:面向对象的检索(通过ORM,操作持久态对象进行检索)
第四种:QBC(条件拼接查询)检索方式,
第五种:QBE(多维查询)检索方式(BI业务上通用,BI的业务主要是对于数据库,主要工作是数据的抓取,数据分析,多维分析)
第六种:SQL(原生SQL的检索方式)
3. HQL语句中的检索技术:
    第一种:实体查询(实体等于对象,等于实例)查询出来的都是实体=查询出来的都是持久态对象=表中的行,该种查询查出来的记录都是一行一行的。SQL语句中没有行查询,但是HQL语句中有。
第二种:属性查询 = 查询出来的都是持久态对象的属性 = 表中的列
注意:有没有select是实体查询和属性查询的一个主要区别。并且在HQL中select和from中间是持久态类的对象。
第三种:条件查询 = 函数(组函数=聚合函数count(*) ,sum(), max() ,min() ,avg()),统计查询属于条件查询的一种。
注意:组函数的一个主要特点为结果集唯一!返回的值为单一值!
第四种:DML风格(delete,update,insert)在HQL语句中永远没有insert插入语句,因为Hibernate有Save()方法。
第五种:外置查询
第六种:过滤查询
第七种:导航查询(在有级联关系的基础上进行查询的)
第八种:连接查询(在有级联关系的基础上进行查询的)
第九种:分页查询
注意:HQL语句需要转义成SQL语句进行执行,HQL可以省略动词,SQL一共九个动词。HQL语句按照hibernate.cfg.xml配置中的数据库的方言转义成相应的SQL语句。Hibernate面向对象,SQL语句面向数据库。
4. Hibernate中的N+1问题:首先查询这个表中所有的id,再按照每一个id进行查询。.iterate()结果集支持数据库的缓冲技术。.list()结果集不支持。
      N+1问题的解决方案:首先把数据从数据库中查找出来,存到list中,在进行iterate查询操作。
5. 数据库的缓存技术:数据缓存指的是把数据加载到缓存区中,首页从缓存区中查询数据。在进行第一次查询的同时,将数据从数据库加载到首页的同时也将数据加载到缓存区中(即内存中),再进行刷新时就从内存中进行查询。Iterate()方法不找数据库,它查询数据缓存。
  注意:.list()方法不支持数据库缓存,查询的是数据库。.iterate()方法支持数据缓存,查询的是内存。Hibernate执行list()方法会默认的把数据放入到缓存中。
Session.get()不支持数据缓存,永远查询数据库。Session.load()支持数据缓存,查询的内存。get()方法如果没有查到值返回null,load()如果没有查到值出现异常。

6. 实体查询:
实体查询技术的实现,需要将实体对象中的所有数据存储到List对象中,例如查询出User实体对象对应的所有数据,而且将每条数据封装成User实体对象,并且放入List中返回。代码如下:
String hql = “from User user”;
List list = session.CreateQuery(hql).list();
因为HQL语句与标准SQL语句相似,所以也可以在HQL语句中使用where子句,并且可以在where子句中使用各种表达式,比较操作符以及使用“and”,”or”连接不同的查询条件的组合。如:
from User user where user.age=20;
from User user where user.age between 20 and 30;
from User user where user.age in(20,30);
from User user where user.name is null;
from User user where user.name like ‘%zx%’;
from User user where (user.age%2)=1;
from User user where user.age=20 and user.name like ‘%zx%’;
7. 实体的更新和删除:
实体更新和删除技术是Hibernate 3新加入的功能,在Hibernate 2中是不具备的。比如在Hibernate 2中,如果想将数据库中所有18岁用户的年龄改为20岁,那么要首先将年龄为18岁的用户检索出来,然后将他们的年龄修改为20岁,最后调用Session.update()语句进行更新。在Hibernate 3中对这个问题提供了更加灵活和有效率的解决办法,如下面的代码:
Transaction trans = session.beginTransaction();
String hql = “update User user set user.age = 20 where user.age=18”;
Query queryupdate = session.createQuery(hql);
Int ret = queryupdate.executeUpdate();
Trans.commit();
通过这种方式可以在Hibernate 3中一次性完成批量数据的更新,对性能的提高非常可观。同样也可以通过类似的方式来完成delete操作,代码如下所示:
Transaction trans = session.beginTransaction();
String hql = “delete from User user where user.age=18”;
Query queryupdate = session.createQuery(hql);
Int ret = queryupdate.executeUpdate();
Trans.commit();
8. 属性查询:
很多时候我们在检索数据时,并不需要获得实体对象所对应的全部数据,而只需要检索实体对象的部分数据对应的数据,这时候就可以利用HQL属性查询技术,如下所示:
List list= session.createQuery(“select user.name from User user”).list();
for(int i=0;i<list.length();i++){
                      System.out.println(list.get(i));
}
      也可以一次检索User对象的多个属性,如下面的程序:
      List list=session.createQuery(“select user.name , user.age from User user”).list();
      for(int i=0;i<list.length();i++){
              Object[] obj=(Object[])list.get(i);
              System.out.println(obj[0]);
              System.out.println(obj[1]);
}
      从面向对象的角度考虑,上面返回Object[]不符合面向对象风格,这时我们可以利用HQL提供的动态构造实例的功能对这些平面数据进行封装,如下面的程序代码:
      List list = session.createQuery(“select new User(user.name , user.age) from  User user ”).list();
      for(int i=0;i<list.length();i++){
                      User user = (User)list.get(i);
                      System.out.println(user.getName());
System.out.println(user.getAge());
}
      上面的实现更加符合面向对象风格,但这时所返回的User对象,只是一个普通的java对象,除了查询结果值之外,它的属性值都为null(包括主键值id),也就是说不能通过Session对像对此对象执行持久化的更新操作。

9. 分组与排序:
(1)order by子句
与SQL语句相似,HQL查询也可以通过order by子句对查询结果集进行排序,并且可以通过asc或者desc关键字指定排序方式,代码如下:
from User user order by user.name asc , user.age desc;
(2)group by子句与统计查询
在HQL语句中同样支持使用group by子句分组查询,还支持group by子句结合聚集函数的分组统计查询,大部分标准的SQL聚集函数都可以在HQL语句中使用,如:count(),sum(),max(),min(),avg()等。代码如下:
String hql = “select count(user), user.age from User user group by user.age having count(user)>10”;
List list = session.createQuery(hql).list();
10. 参数绑定:在Hibernate中也提供了查询参数绑定功能,而且在Hibernate中对这个功能还提供了比传统JDBC操作丰富的特性。Hibernate共有3种参数绑定方式
(1)  按参数名称绑定
在HQL语句中定义命名参数要用“:”开头,形式如下:
Query query = session.createQuery(“from User user where user.name=:customername and user.age=:customerage”);
query.setString(“customername”,name);
query.setInteger(“customerage”,age);
(2)按参数位置绑定
在HQL查询语句中用“?”来定义参数位置,形式如下:
Query query = session.createQuery(“from User user where user.name=? and user.age=?”);
query.setString(0,name);
query.setInteger(1,age);
(3)setParameter()方法
在Hibernate的HQL查询中可以通过setParameter()方法绑定任意类型的参数,代码如下:
String hql = “from User user where user.name=:customername”;
Query query = session.createQuery(hql);
query.setParameter(“customername”,name,Hibernate.STRING);
11. 导航查询:
      Hibernate中第一种级联查询方式,导航指在一个类中通过一个类的对象查找到另一个类中。Select s.username from Student s where s.classes.name(此处用到了导航) like ‘%天%’;
12. 连接查询:(left join , inner join, right join,full join(满连接,一般不用)).连接查询必须  依靠导航查询来实现。
(1) 内连接:Select c.name ,s.username from Student s inner join s.classes c;(内连 接)(s.classes相当于得到Classes这个类)
(2) 左连接:会查找出左表全部的记录,和左右表中相同的记录。Select c.name,s.username from Classes c left join c.student s
(3) 右连接:会查找出右表全部的记录,和左右表中相同的记录。Select c.name,s.username from Classes c right join c.student s
13. 源生SQL查询:.createSQLQuery(),此时可以用SQL语句进行修改和删除还有插入。.addEntity(类名.class)可以进行查询。
14. 分页查询:
    Hibernate框架中封装好了分页算法。
需要确定的参数:1.每页显示的信息条数。
                    2.总记录数。
                    3.写一个方法改变查询游标的初始位置。
需要的核心的业务:两个:
第一:必须能控制每次查询的结果集的范围
第二:必须能自定义查询初始游标的位置(相当于Oracle中的RowNum嵌套查询),可以通过上一页(变量-5)或下一页(变量+5)传记录数,也可以传页数,此时上一页(变量-1)  下一页(变量+1)  此时需要用1*每页显示的记录数(5).传记录数和传页数的区别在于出传记录数不需要处理,传页数需要处理。即1*每页显示的记录数。
15. Hibernate操作数据库的两种方法:
      第一种:使用持久化类对象(ORM);
第二种:使用HQL语句
16. 动态构造:查询结果的返回值为自己构造的一个对象。此时需要在持久态类中写上  该构造函数(又叫属性构造器),才可以在HQL语句中使用该构造函数。
实体构造器:无参数的构造函数
属性构造器:自定义参数的构造函数
17. 属性查询由于按照列来查询,其返回的结果集不再是对象。在HQL语句中以from    开头的是实体查询,以select开头的是列查询。
在单一属性查询中我们查询的这个属性它在持久态类中是什么数据类型我们返回的值就是什么类型。(单一查询得到数据类型)
在查询多类型时,其集合元素是对象数组,数组元素的类型和对应的属性在实体类中的类型一致。数组的长度取决与select中属性的个数。(多类型查询得到的是object数组)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值