Hibernate详解

 

Hibernate-02使用步骤 2

Hibernate-03核心接口 3

Hibernate-04持久对象的生命周期 3

Hibernate-05_Session接口的基本用法及生命周期 3

Hibernate-06_Query接口 4

Hibernate-07基本映射标签和属性 4

Hibernate-08多对一关联映射 5

Hibernate-09一对一主键关联映射-单向 6

Hibernate-10一对一主键关联映射-双向 7

Hibernate-11一对一唯一外键关联映射-单向 8

Hibernate-12一对一唯一外键关联映射-双向 9

Hibernate-13一对多关联映射-单向 10

Hibernate-14一对多关联映射-双向 11

Hibernate-15多对多关联映射-单向 12

Hibernate-16多对多关联映射-双向 13

Hibernate-17延迟加载lazy 14

Hibernate二级缓存 15

延迟加载 16

 

 

 

 

Hibernate 开源O/R映射框架(ORM)

 

分层:下层为上层提供服务

三层架构

表示层:struts  webWork JSF

业务逻辑层:spring

持久层:与业务无关 hibernate(冬眠:让对象冬眠) ibatis

数据库:

 

OOA:面向对象的分析

OOD:面向对象的设计

OOP:面型对象的编程

 

阻抗不匹配(Java类中的继承关系不能体现在关系型数据库中)

 

创建的其他O/R映射框架:

Apache OJB

JDO java数据对象

Toplink(oracle)

EJB(2.0 cmp)(3.0 JPA)

IBatis(严格意义上讲不是OR框架,轻量级)

 

Hibernate优点:

 1,无需SQL,效率更高(JDBC不需要我们写了)

 2,使开发更面向对象化

 3,移植性高

 4,实现了透明持久化,不需要继承或实现Hibernate包中的任何类或接口(pojo)

 5,没有侵入性(轻量级)

 

Hibernate缺点:

 1,不支持批量操作

 2,使用到数据库特用功能的时候就不能使用Hibernate(因为sql是自动生成的)

 

 

Hibernate-02使用步骤

pojo.hbm.xml:映射文件

1,新建项目

 

2,创建User Library,加入jar包

  *HIBERNATE_HOME/hibernate3.jar

  *HIBERNATE_HOME/lib/*.jar

  *数据库驱动jar

 

3,创建Hibernate配置文件:hibernate.cfg.xml(HIBERNATE_HOME/etc)

  为了便于调试,将log4j.properties加入到项目中

 

4,创建一个实体类pojo

 

5,定义User类的映射文件POJO.hbm.xml

 

6,将POJO.hbm.xml引入到件ibernate.cfg.xml中

 

7,写一个类,将实体类生成数据库表

   Configuration cfg = new Configuration().configure();

SchemaExport se = new SchemaExport(cfg);

se.create(true, true);

 

8,通过 Configuration cfg = new Configuration().configure();

       SessionFactory sf = cfg.buildSessionFactory();

       Session session = sf.openSession();

session.beginTransaction();

session.save(u);

session.getTransaction().commit();

session.close();

 

9,show_sql=true:显示hibernate执行的SQL语句

 

Hibernate-03核心接口

 

JNDI:统一管理对象资源,通过友好字符串可以获得一个对象(数据库连接池)

JDBC:事务管理只能针对同一个数据库

JTA:Java事务API,可以实现跨数据库事务的统一管理(银行转账)

 

Hibernate-04持久对象的生命周期

 

瞬时态:新创建的对象,在数据库中没有与之对应的记录

持久态:存入数据库,接收session的管理

游离态:在数据库中有与之对应的记录,但是脱离了session的管理

 

Hibernate-05_Session接口的基本用法及生命周期

 

1,了解Hibernate中的CRUD操作

  save()

  update()

  saveOrUpdate()

  get()

  post()

 

2,了解get和load的区别:

  get(),采用get方法加载数据库中的数据,如果不存在,返回null

  load(),延迟加载,在执行load方法的时候不会发出sql语句,只是返回一个CGLIB代理对象,只有在真正第一次使用查询出对象的时候才发出SQL语句查询数据库;采用load方法加载数据库中的数据,如果不存在,则抛出异常

 

3,transient状态的特征:

    *在数据库中没有与之匹配的数据

    *没有加入session的管理

 

  persistent状态的特征:

    *在数据库中存在(不绝对)

    *同时纳入了session管理

    *在清理缓存(脏数据检查)的时候会和数据库同步

 

  detached状态的特征:

    *在数据库中有与之对应的记录

    *没有纳入session的管理

  

 

Hibernate-06_Query接口

1,Query查询所有记录:

  Query query = session.createQuery("from User");

 

2,Query的分页:

  //设置从的几条开始查询

  query.setFirstResult(3);

  //设置查询多少条

  query.setMaxResults(2);

Hibernate-07基本映射标签和属性

Hibernate的基本映射:

  实体类---表

  实体类中的属性---表字段

 

  采用<class></class>标签将实体类映射成数据库表

name

table

lazy

 

 

  采用<property/>标签将普通属性映射成表字段

name

column

length

type(指定数据库中该字段的类型:一般情况下不需要指定)

update true|false  该字段不会出现在update的Sql语句中

insert true|false

unique 唯一性

not-null 是否为空

 

  采用<id></id>配置数据库主键

<generator class="native" />设置主键的自动增长

class="native/uuid/identity/sequence"

native----Hibernate完成的数字自增1,2,3...

uuid----生成一个32位的字符串

identity----sqlserver的自增

  sequence----oracle的自增(1,2,...)

assigned----手动分配主键

 

  采用<composite-id></composite-id>设置联合主键

Hibernate-08多对一关联映射

多个用户属于一个组:User----Group

 

User              Group

-----------       -----------

id:int            id:int

name:String       name:String

group:Group

 

关联映射的本质:

将关联关系映射到数据库, 所谓的关联关系是对象模型在内存中的一个或 多个引用

 

User.hbm.xml:

<many-to-one name="group" column="groupid" casecade="save-update">

</many-to-one>

Hibernate-08多对一关联映射

多个用户属于一个组:User----Group

 

User              Group

-----------       -----------

id:int            id:int

name:String       name:String

group:Group

 

关联映射的本质:

将关联关系映射到数据库, 所谓的关联关系是对象模型在内存中的一个或 多个引用

 

User.hbm.xml:

<many-to-one name="group" column="groupid" casecade="save-update">

</many-to-one>

Hibernate-09一对一主键关联映射-单向

一个人只有一个身份证:Person---->IDCard

 

Person            IDCard

-----------       -----------

id:int            id:int

name:String       cardNo:String

idCard:IDCard

 

 

单向时指:站在Person这一段可以看到IDCard对象

双向是指:站在Person这一段可以看到IDCard对象同时站在IDCard对象一段页可以看到对用的Person对象

 

主键关联:让关联对象的id(主键)保持一致,不用加任何字段;就是让Person的主键和IDCard保持一致,而不是自动增长

 

 

IDCard.hbm.xml

-----------------------------------------------

<class name="com.softeem.IDCard">

    <id name="id">

        <generator class="native"/>

    </id>

    <property name="cardNo"/>

</class>

 

 

Person.hbm.xml

-----------------------------------------------

<class name="com.softeem.Person">

    <id name="id">

        <generator class="foreign"> :设置成外键关联

            <param name="property">idCard</param>:关联icCard对应主键

        </gennerator>

    </id>

    <property name="name"/>

    <one-to-one name="idCard" constrained="true"/>

添加上外键约束:指示hibernate怎样加载他的关联对象(默认根据主键加载)

一对一主键关联映射中,默认了casecade属性

</class>

 

Hibernate-10一对一主键关联映射-双向

一个人和一个身份证只能唯一对应:Person<---->IDCard

 

Person            IDCard

-----------       -----------

id:int            id:int

name:String       cardNo:String

idCard:IDCard    person:Person

 

 

双向是指:站在Person这一段可以看到IDCard对象同时站在IDCard对象一段页可以看到对用的Person对象

 

主键关联:让关联对象的id(主键)保持一致,不用加任何字段;就是让Person的主键和IDCard保持一致,而不是自动增长

 

 

IDCard.hbm.xml

-----------------------------------------------

<class name="com.softeem.IDCard">

    <id name="id">

        <generator class="native"/>

    </id>

    <property name="cardNo"/>

    <one-to-one name="person">

默认抓取策略fetch=“jion”,只发一条外连接查询语句

</class>

 

 

Person.hbm.xml

-----------------------------------------------

<class name="com.softeem.Person">

    <id name="id">

        <generator class="foreign"> :设置成外键关联

            <param name="property">idCard</param>:关联icCard对应主键

        </gennerator>

    </id>

    <property name="name"/>

    <one-to-one name="idCard" constrained="true"/>

添加上外键约束:指示hibernate怎样加载他的关联对象(默认根据主键加载)

一对一主键关联映射中,默认了casecade属性

</class>

 

Hibernate-11一对一唯一外键关联映射-单向

一个人只有一个身份证:Person---->IDCard

 

Person            IDCard

-----------       -----------

id:int            id:int

name:String       cardNo:String

idCard:IDCard

 

单向时指:站在Person这一段可以看到IDCard对象

 

外键关联:在一张表中添加一个外键,指向关联表的主键(在Person表中添加外键指向IDCard的主键)

 

 

IDCard.hbm.xml

-----------------------------------------------

<class name="com.softeem.IDCard">

    <id name="id">

        <generator class="native"/>

    </id>

    <property name="cardNo"/>

</class>

 

 

Person.hbm.xml

-----------------------------------------------

<class name="com.softeem.Person">

    <id name="id">

        <generator class="native"/>

    </id>

    <property name="name"/>

    一对一就是多对一中的特例:给外键条件了一个唯一性约束

    <many-to-one name="idCard" unique="true"/>

</class>

Hibernate-12一对一唯一外键关联映射-双向

一个人只有一个身份证:Person<---->IDCard

 

Person            IDCard

-----------       -----------

id:int            id:int

name:String       cardNo:String

idCard:IDCard    person:Person

 

外键双向关联:在一张表中添加一个外键,指向关联表的主键(在Person表中添加外键指向IDCard的主键)

 

 

IDCard.hbm.xml

-----------------------------------------------

<class name="com.softeem.IDCard">

    <id name="id">

        <generator class="native"/>

    </id>

    <property name="cardNo"/>

    一对一关联映射默认的是通过主键加载指定的对象

    添加了property-ref属性之后,就表示加载的时候就根据person对象的idCard加载,因为icard也是唯一的,所以实现了一对一的关联

    <one-to-one name="person" property-ref="idCard"/>

</class>

 

 

Person.hbm.xml

-----------------------------------------------

<class name="com.softeem.Person">

    <id name="id">

        <generator class="native"/>

    </id>

    <property name="name"/>

    一对一就是多对一中的特例:给外键条件了一个唯一性约束

    <many-to-one name="idCard" unique="true"/>

</class>

 

Hibernate-13一对多关联映射-单向

一个班级对应多名学生:Classes---->Student

 

Classes                   Student

--------------------      ------------

id:int                    id:int

name:String               name:String

students:Set<Student>

 

多对一关联映射:在一得一端加一个外键,指向多的一端,维护的关系是多指向一

一对多关联映射:在加载一个班级的时候能够加载班级中所有的学生,在多的一端加一个外键,指向一的一端,维护的关系是一指向多

 

Classess.hbm.xml

-----------------------------------------------------

<class name="com.softeem.Classes">

    <id name="id">

        <generator class="native"/>

    </id>

    <property name="name"/>

    <set name="students">

        <!--这一句话的作用是在student表中添加一个主键,指向classes的id-->

<!--执行的时候student表中的classis字段为空,添加classes记录之后执行修改,所以这个字段不能添加非空约束,不然就不能保存-->

        <key column="classid"/>

        <!--指定执行时的加载对象-->

        <one-to-many class="com.softeem.Student"/>

    </set>

</class>

 

Student.hbm.xml

-----------------------------------------------------

<class class="com.softeem.Student">

    <id name="id">

        <generator class="native"/>

    </id>

    <property name="name"/>

</class>

 

 

Hibernate-14一对多关联映射-双向

一对多关联映射双向:Classes<---->Student

 

Classes                   Student

--------------------      ------------

id:int                    id:int

name:String               name:String

students:Set<Student>     classes:Classes

 

一对多双向关联映射:加载Classes的时候能够加载这个班级所有的学生信息,同时在加载一个Student的时候能够加载这个学生所在的班级信息

 

Classess.hbm.xml

-----------------------------------------------------

<class name="com.softeem.Classes">

    <id name="id">

        <generator class="native"/>

    </id>

    <property name="name"/>

    <!--invase反转属性:允许在多的一端维护关系(在学生的classid为null但是关系存在)-->

    <!--相当于反转成了多对一关系:不会再发出update语句-->

    <!--设置反转之后,先将Classes给student对象设置进去,student不用sava了,通过级联完成存储-->

    <set name="students" inverse="true" casecade="all">

        <!--这一句话的作用是在student表中添加一个主键,指向classes的id-->

<!--执行的时候student表中的classis字段为空,添加classes记录之后执行修改,所以这个字段不能添加非空约束,不然就不能保存-->

        <key column="classid"/>

        <!--指定执行时的加载对象-->

        <one-to-many class="com.softeem.Student"/>

    </set>

</class>

 

Student.hbm.xml

-----------------------------------------------------

<class class="com.softeem.Student">

    <id name="id">

        <generator class="native"/>

    </id>

    <property name="name"/>

    <!--映射的时候需要注意,这个字段的名字要和一的一端指定的字段名字相同-->

    <!--多对一存储的时候:需要先存储多的一端的对象-->

    <!--一对多存储的时候:需要先存储多的一端的对象-->

    <many-to-one name="classes" column="classid"/>

</class>

Hibernate-15多对多关联映射-单向

一个用户对用多个角色,多个用户也可能具有同一个角色:User---->Role

 

User              Role

--------------    --------------

id:int            id:int

name:String       name:String

roles:Set

 

 

多对多关联映射通常要采用第三方表,用来存放两者之间的关系

 

tb_user                tb_user_role            tb_role

-----------------      -------------------     --------------------

id   |   name           userid | roleid        id  |  name

-----------------      -------------------     --------------------

1    |  张三             1    |  2             1  |  经理

2    |  李四             1    |  3             2  |  主管

3    |  王五             2    |  1             3  |  领班

 

 

User.hbm.xml

-----------------------------------------------------------------

<class class="com.softeem.User">

    <id name="id">

        <generator class="native"/>

    </id>

    <property name="name"/>

    <!--添加table="tb_user_role",指明要引用第三方表,并且hibernate会自动创建这张表-->

    <set name="roles" table="tb_user_role">

        <!--key标签表示,使用user的主键作为第三方表的一个外键,字段名为userid-->

        <key column="userid"/>

        <!--声明set集合映射到Role类对应得表,并且将映射表的主键作为第三方表的一个字段,并且将引入的这两个字段作为“复合主键”-->

        <many-to_many calss="com.softeem.Role" column="roleid"/>

    </set>

</class>

 

Role.hbm.xml

-----------------------------------------------------------------

<class class="com.softeem.User">

    <id name="id">

        <generator class="native"/>

    </id>

    <property name="name"/>

</class>

Hibernate-16多对多关联映射-双向

一个用户对用多个角色,一个Role也对用多个用户:User<---->Role

 

User              Role

--------------    --------------

id:int            id:int

name:String       name:String

roles:Set         users:Set

 

 

多对多关联映射通常要采用第三方表,用来存放两者之间的关系

 

tb_user                tb_user_role            tb_role

-----------------      -------------------     --------------------

id   |   name           userid | roleid        id  |  name

-----------------      -------------------     --------------------

1    |  张三             1    |  2             1  |  经理

2    |  李四             1    |  3             2  |  主管

3    |  王五             2    |  1             3  |  领班

 

 

User.hbm.xml

-----------------------------------------------------------------

<class class="com.softeem.User">

    <id name="id">

        <generator class="native"/>

    </id>

    <property name="name"/>

    <!--添加table="tb_user_role",指明要引用第三方表,并且hibernate会自动创建这张表-->

    <set name="roles" table="tb_user_role">

        <!--key标签表示,使用user的主键作为第三方表的一个外键,字段名为userid-->

        <key column="userid"/>

        <!--声明set集合映射到Role类对应得表,并且将映射表的主键作为第三方表的一个字段,并且将引入的这两个字段作为“复合主键”-->

        <many-to-many calss="com.softeem.Role" column="roleid"/>

    </set>

</class>

 

Role.hbm.xml

-----------------------------------------------------------------

<class class="com.softeem.Role">

    <id name="id">

        <generator class="native"/>

    </id>

    <property name="name"/>

    <!--指定的第三方表要与User中指定的完全一致-->

    <set column="users" table="tb_user_role">

        <key column="roleid"/>

        <many-to-many class="com.softeem.User" column="userid"/>

    </set>

</class>

 

 

 

 

Hibernate-17延迟加载lazy

实体类的设计原则(POJO):

1,实现一个默认的无参的构造方法

2,提供一个标识属性

3,使用非final的类(影响预加载)

4,为持久化字段声明访问器(提供get和set方法)

 

 

防止已经存在的表在重新导出的时候被覆盖:

在hibernate.cfg.xml里面加上配置

<property name="hbm2ddl.auto">true</property>

  

延迟加载(懒加载):查询出的对象在使用的时候才加载进来

 

可以用在class标签  property标签  set标签 one2one和many2one

 

<class>标签上,可以取值:true/false

<property>标签上,可以取值:true/false 使用类增强工具,修改字节码达到代理的目的

<set><list>标签上,可以取值:true/false/extra

one2one和many2one单端关联,可以取值:false/proxy/noproxy

 

lazy概念,只有真正使用该对象时才会创建;对于Hibernate而言,只有真正使用对象的时候才会发出sql语句

 

 

CGLib可以对普通类进行代理

JDK的代理只能代理实现了接口的类

 

Hibernate二级缓存

二级缓存的生命周期和SessionFactory的生命周期一致,也称为SessionFactory级的缓存或者进程级的缓存

 

因为二级缓存是一个可插拔的缓存插件,所以使用二级缓存一定要先配置.

 

二级缓存的配置:

    *将echcache.xml文件拷贝到src下

    *在hibernate.cfg.xml中添加配置,开启二级缓存的使用

     hibernate.cache.use_second_level_cache=true

    *在hibernate.cfg.xml中配置二级缓存的提供商

     hibernate.cache.provider_class=[API中查找]

    *在hibernate.cfg.xml中指明哪些pojo实体对象需要用到二级缓存

     <class-cache/>

 

延迟加载

 

延迟加载:当需要使用到该数据的时候才进行加载(进行查询)

get不支持延迟加载,load支持延迟加载

 

延迟加载:lazy="true"

当lazy="false" 时,不会延迟加载

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值