Hibernate学习总结(1)(根据王勇 Hibernate 教学视频总结)

Hibernate学习总结

第一个hibernate项目

 

1、新建java项目

 

2、创建User Library,加入如下jar

         * HIBERNATE_HOME/hibernate3.jar

         * HIBERNATE_HOME/lib/*.jar

         * MySql jdbc驱动

        

3、创建hibernate配置文件hibernate.cfg.xml,为了便于调试最好加入log4j配置文件

 

4、定义实体类

 

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

 

6、将User.hbml.xml文件加入到hibernate.cfg.xml文件中

 

7、编写hbm2ddl工具类,将实体类生成数据库表

 

8、开发客户端

        

为了方便跟踪sql执行,在hibernate.cfg.xml文件中加入<property name="hibernate.show_sql">true</property>

 

测试实体对象的生命周期

 

junit简介:

         * 编写测试类xxxTest,需要继承TestCase

         * 编写单元测试方法,测试方法必须以test开头,测试方法不能含有参数和返回值,如:

           public void testHello1() {}

         * 最好单元测试的代码单独建立一个目录

        

了解HibernateCRUD操作

 

了解getload的区别?

         * get不支持lazyload支持lazy

         * 采用get加载数据,如果没有匹配的数据,返回null,而load则抛出异常

        

transient状态的特征?

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

         * 没有纳入session的管理

        

persistent状态的特征?

         * persistent状态的对象在数据库中有与之匹配的数据

         * 纳入了session的管理

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

        

detached状态的特征?

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

         * 没有纳入session的管理                  

        

hibernate基本映射

 

实体类---

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

 

采用<class>标签映射成数据库表,通过<property>标签将普通属性映射成表字段

所谓普通属性指不包括自定义类、集合和数组等

 

注意:如果实体类和实体类中的属性和sql中的关键字重复,必须采用tablecolumn重新命名

 

实体类的设计原则:

         * 实现一个默认的(即无参数的)构造方法(constructor

         * 提供一个标识属性(identifier property)(可选)

         * 使用非final的类 (可选)

         * 为持久化字段声明访问器(accessors)      

 

主键生成策略:

         uuidnativeassigned

 

hibernate多对一关联映射

 

关联映射的本质:

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

 

<many-to-one>会在多的一端加入一个外键,指向一的一端,这个外键是由<many-to-one>

中的column属性定义的,如果忽略了这个属性那么默认的外键与实体的属性一致

 

<many-to-one>标签的定义示例:

          * <many-to-one name="group" column="groupid"/>

          

理解级联的含义?

         * 是对象的连锁操作    

                

hibernate一对一主键关联映射(双向关联Person<---->IdCard

需要在idcard映射文件中加入<one-to-one>标签指向person,指示hibernate如何加载person

默认根据主键加载

hibernate一对一主键关联映射(单向关联Person---->IdCard

 

一对一主键关联映射:让两个实体对象的id保持相同,这样可以避免多余的字段被创建

 

具体映射:

 

         <id name="id">

                   <!-- person的主键来源idCard,也就是共享idCard的主键 -->

                   <generator class="foreign">

                            <param name="property">idCard</param>

                   </generator>

         </id>

         <property name="name"/>

         <!-- one-to-one标签的含义,指示hibernate怎么加载它的关联对象,默认根据主键加载,

         constrained="true"     表明当前主键上存在一个约束,person的主键作为外键参照了idCard

          -->

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

 

hibernate一对一唯一外键关联映射(单向关联Person---->IdCard

 

一对唯一外键关联映射是多对一关联映射的特例

 

可以采用<many-to-one>标签,指定多的一端的unique=true,这样就限制了多的一端的多重性为一

通过这种手段映射一对一唯一外键关联

 

hibernate一对一唯一外键关联映射(双向关联Person<---->IdCard

 

一对一唯一外键关联双向,需要在另一端(idcard),添加<one-to-one>标签,指示hibernate如何加载

其关联对象,默认根据主键加载person,外键关联映射中,因为两个实体采用的是person的外键维护的关系,

所以不能指定主键加载person,而要根据person的外键加载,所以采用如下映射方式:

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

 

session flush测试:

 

session flush方法主要做了两件事:

         * 清理缓存

         * 执行sql

        

session在什么情况下执行flush

         * 默认在事务提交时

         * 显示的调用flush

         * 在执行查询前,如:iterate

        

hibernate按照save(insert),updatedelete顺序提交相关操作        

                  

hihernate一对多关联映射(单向Classes----->Student

 

一对多关联映射利用了多对一关联映射原理

 

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

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

 

也就是说一对多和多对一的映射策略是一样的,只是站的角度不同

 

在一一端维护关系的缺点:

         * 如果将t_student表里的classesid字段设置为非空,则无法保存

         * 因为不是在student这一端维护关系,所以student不知道是哪个班的,

           所以需要发出多余的update语句来更新关系

 

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

 

一对多双向关联映射:

         * 在一一端的集合上使用<key>,在对方表中加入一个外键指向一一端

         * 在多一端采用<many-to-one>

        

注意:<key>标签指定的外键字段必须和<many-to-one>指定的外键字段一致,否则引用字段的错误

        

如果在”一“一端维护一对多关联关系,hibernate会发出多余的udpate语句,所以我们一般在多

的一端来维护关联关系

 

关于inverse属性:

         inverse主要用在一对多和多对多双向关联上,inverse可以被设置到集合标签<set>上,

         默认inversefalse,所以我们可以从”一“一端和”多“一端维护关联关系,

         如果设置成inversetrue,则我们只能从多一端来维护关联关系

        

         注意:inverse属性,只影响数据的存储,也就是持久化

                  

inversecascade

         * inverse是关联关系的控制方向

         * cascade操作上的连锁反应

 

 

hibernate多对多关联映射(单向User---->Role)

 

具体映射方式:

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

                   <key column="userid"/>

                   <many-to-many class="com.bjsxt.hibernate.Role" column="roleid"/>

         </set>

        

 

hibernate多对多关联映射(双向User<---->Role)

 

映射方法:

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

                            <key column="userid"/>

                            <many-to-many class="com.bjsxt.hibernate.Role" column="roleid"/>

                   </set>

table属性值必须和单向关联中的table属性值一致

<key>column属性值要与单向关联中的<many-to-many>标签中的column属性值一致

<many-to-many>中的column属性值要与单向关联中<key>标签的column属性值一致

 

 

hibernate lazy策略可以使用在:

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

         * <property>标签上,可以取值:true/false需要类增强工具

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

         * <one-to-one><many-to-one>单端关联上,可以取值:false/proxy/noproxy

        

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

 

hibernate支持lazy策略只有在session打开状态下有效

 

<class>标签上的lazy特性只对普通属性起作用

 

hibernate在集合上的lazy策略,可以取值:true/false/extra

<class>标签上的lazy不会影响到集合上的lazy特性

 

hibernate在单端关联上的lazy策略,可以取值:false/proxy/noproxy

<class>标签上的lazy不会影响到单端关联上的lazy特性

        

每棵继承树映射成一张表

 

1、理解如何映射

                   因为类继承树肯定是对应多个类,要把多个类的信息存放在一张表中,必须有某种机制来区分哪些记录是属于哪个类的。

         这种机制就是,在表中添加一个字段,用这个字段的值来进行区分。用hibernate实现这种策略的时候,有如下步骤:

         父类用普通的<class>标签定义

         在父类中定义一个discriminator,即指定这个区分的字段的名称和类型

         如:<discriminator column=XXX type=string/>

         子类使用<subclass>标签定义,在定义subclass的时候,需要注意如下几点:

         Subclass标签的name属性是子类的全路径名

         Subclass标签中,用discriminator-value属性来标明本子类的discriminator字段(用来区分不同类的字段)

         的值Subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class

         签平行。 subclass标签的定义与class标签平行的时候,需要在subclass标签中,添加extends属性,里面的值

         是父类的全路径名称。子类的其它属性,像普通类一样,定义在subclass标签的内部。

 

2、理解如何存储

   

你可能感兴趣的:(sql,Hibernate,xml,单元测试,配置管理)