Hibernate关联映射总结
· 1.单向many_to_one
· 1.插入时不区分one插入还是many插入顺序
· 2.若先插入one,只执行inserSQL插入语句
· 3.若先插入many,先执行many端的插入,发现无主键,直到one执行完后,才执行many插入操作变为updateSQL修改语句
· 4.若查询many-to-one端的数据,默认值查询many端的字段,不查询one端的数据,若需要one端的数据才会发送对应的SQL语句(懒加载)
· 5.查询many-one的一端时,由many的一端导航到one的一端,可能会发生懒加载异常(session在one之前关闭,一定会发生懒加载异常)
· 6.获取many端的数据时,默认情况下,one端关联的对象是代理对象
· 7.修改(Update):先查询、后修改
· 7.删除(Detele):
· 不涉及级联关系的情况下,one端的对象被多个many对象引用,不能直接删除one端的数据
· 2.one-to-many双向关联
· 1.先执行one,后执行many,执行3条insert,2条update
· 2.先执行many,后执行one,执行3条insert,4条update,因为one和many都在维护关联关系,所以多了2条update
· 3.one端用inverse="true"为true,指明one来维护关联关系,少了update语句,提高效率
· 3.one-to-many集合属性配置
· 1.inverse="true":指定哪一方来指定关联关系
· 2.cascade=-"detele-orphan":设置级联操作(删除)
· 3.order by="字段名 排列顺序" ;该值为表的列名,不是持久化层的属性名
· 4.主键映射
· 1.一端的主键根据参照另外一端的主键产生,无外键字段
· 2.插入顺序无要求
· 5.many-to-many
· 1.连接表:两表组合成新的表(表中是另外两表的约束)
· 6.继承映射
· subclass
· 优点:父类子类使用同一张表
· 缺点
· 1.子类独有的字段不能添加非空约束
· 2.使用了辨别者
· 3.若继承层次较多,则数据表的字段也会较多
· 映射文件特点
1.class中配置辨别者字段discriminator-value+"任意值区分父类子类";2?.父类字段依旧映射3.添加辨别者类?<discriminator column="TYPECLASS" type="string"/>4.子类放在class内案例如下:?<class name="Person" table="Person" discriminator-value=“person">??<discriminator column="TYPECLASS" type="string"/> ??<subclass name="子类名" discriminator-value=“Student">? <property name="school" type="string" column+"SCHOOL"></property>?? </subclass><class>??
· 特点:
· 1.插入操作:对于子类只需要把记录插入到一张数据表中
· 1.辨别者由Hibernate自动维护
· 2.查询操作
· 1.查询父类记录,只需要查询一张数据表
· 2.查询父类记录,也只需要查询一张数据表
· joined-subclass
· 定义:每一个子类一张表,子类实例由父类和子类共同存储
· 特点
· 1.插入操作:对于子类对象至少插入到两张数据表中
· 2.查询数据
· 1.查询父类记录,做一个左外连接查询
· 2.查询子类记录,做一个内外连接查询
· 优点:
1.不需要辨别者2.子类字段能加非空约束?3.?没有冗余的字段
· union-subclass
· 定义:将每一个实体对象映射到一个独立的表中,子类添加字段可以有非空约束,子类数据保存到子类表中,不需要鉴别者,也不需要key来映射共有主键,使用union-subclass映射策略时,数据库主键不能使用identity的主键生成策略
· 特点
· 插入操作:
· 查询操作:
· 1.查询父类记录,需要把字表父表汇总到一起再做查询,性能较差
· 2.查询子类记录,只需要查询一张表
· 优点
1.不需要辨别者2.子类字段能加非空约束
· 缺点:
1.?存在冗余的字段2.修改复杂,若更新父表字表?端,效率较低
· 7.检索策略
· 1.类级别的检索策略(通过class的lazy属性来设置(仅对load方法有效))
1.立即检索:立即加载检索方法指定的对象2.延迟检索?:延迟加载检索的方法的对象,使用对象的属性时才加载
· 2.)OneToMany or ManyToMany
· Set集合的特性
· set的lazy属性
· 1.默认的是懒加载检索策略
· 2.可以设置set的lazy的属性来修改默认的策略,默认为true(懒加载)不建议设为false
· 3.lazy可以设置为extra,增强延迟检索,该取值会尽可能的延迟集合初始化时机
· set的batch-size属性
1.设定集合每次初始化数据的数量
· set的fetch(抓取)
set集合的fetch属性1.?默认方式select.通过正常的方式来初始化set元素?2.可以取值subselect,通过子查询方式来初始化所有的set集合子查询作为where子句的in的条件出现,子查询查询所有one的一端的ID此时lazy有效,batch-size失效?3.子查询的select语句中查询selelct语句为查询?One端集合的seleect语句4.?取值为join,则决定集合初始化时机,One端迫切左外连接策略来检索所有关联的set集合里面的对象Query的list()方法会被映射文件中的配置迫切左外连接检索策略,检索many端集合对象中的属性,而依就采用延迟加载策略5.lazy取值为proxy和false,分别代表对应的属性采用延时加载检索和立即检索?6.fetch取值为join,表示使用迫切左外连接的方式初始化many端关联的one端?的属性lazy被忽略7.batch-size?=“10”,属性设置在one端的class元素中:一次初始化one端的对象个数(一次初始化10个one端代理对象个数)??
· 8.get和load方法检索的区别
load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常;get方法检索不到的话会返回null;2.从检索执行机制上对比:load方法的执行则比较复杂首先查找session的persistent Context(一级缓存)中是否有缓存,如果有则直接返回,如果没有则去查找二级缓存,如果有则返回,如果没有则判断是否是lazy,若不是lazy,直接访问数据库检索,查到记录返回(并且同时在二级缓存中存放查到的数据方便下次使用,若再下次使用时在二级缓存命中,就是查到数据,则有可能将数据放到一级缓存中。),查不到抛出异常。 若是lazy,则返回代理对象,而不到数据库中查找,除非使用此对象时,才到数据库中查找。get方法先到一级缓存,然后二级,最后db查找。??
· 9.检索方式
· 导航对象图检索方式:根据已加载的对象导航到其他对象
· OID检索方式:按照对象的OID来检索对象
· HQL检索方式:适用面向对象的HQL来查询语句
· 分页查询
· setFirstResult(int num);//引索位置从0开始
· setMaxResults(int maxResults)//一次最多拿出的条数
· QBC检索方式:使用QBC(Query By Criteria)API来检索对象。这种方式API封装了基于字符串形式的查询语句,提供了更加面向对象的查询接口
· 本地SQL检索方式:使用本地数据库的SQL查询语句