Hibernate(02)

作者: 71150ce14a00 | 来源:发表于2017-09-14 18:55 被阅读5次

    数据库主键分为两种:代理主键和自然主键 ----> 代理主键使用居多

    代理主键:不具有业务含义的字段作为主键,例如自增长的id, uuid
    自然主键:具有业务含义的字段作为主键,例如订单编号
    
    主键约束类型:increment, identity, sequence , native ,uuid ,assigned
    increment: 不科学,有线程问题, 原理 select max(id)+1
    identity: mysql 自动增长
    sequence: oracle 序列增长
    native:会自动判断数据库,判断使用 identity还是sequence
    uuid: string类型,生成代理主键
    assigned:唯一的一个自然主键设置方式,手动设置主键的值
    
    po:设置属性类型的时候,尽量使用包装类,因为包装类不赋值返回null,非包装类有初始值
    OID(Object identifier):对象标识,用来标识唯一对象,是实体类中与数据库主键保持一致,Hibernate框架根据OID标识,判断是否为同一个对象

    瞬态/临时态:通常new关键字创建出来的对象,未与session关联,没有OID
    持久态:在数据库存在对应的实例,拥有持久化标识OID,与session关联(受session管理)
    脱管态/游离态:当session关闭后,持久状态对象与session断开关联,称为脱管对象,此时没有与session关联,也有OID

    三种状态互相转换:
    瞬时对象:
    如何直接获取 --- new出来
    转换到持久态 --- save,saveOrUpdate 保存操作
    转换到脱管态 --- setId , 设置OID持久化标识(这个id必须是数据库中存在的)
    
    持久对象
    如何直接获得 --- 通过session查询方法从数据库获得, get,load,createQuery,creteSQLQuery,createCriteria
    转换到瞬时态 --- delete操作,数据表不能再对应的数据,其实还有id只是不叫OID
    转换到托管态 --- close关闭session,evict,clear,从session中清除对象
    
    脱管对象
    如何直接获得 --- 无法直接通过查询数据库获得,必须通过瞬时对象或者持久对象转换获得
    转换到瞬时态 --- 将id设置为null,或者手动将数据的对应数据删掉,或者将id改成数据库不存在的
    转换到持久态 --- update,saveOrUpdate, 对象重新放入session,重新与session关联
    
    session的一级缓存

    只要session的生命周期没有结束,session中的数据就不会清空
    只要是持久态对象,都会保存在一级缓存(与session关联的本质一样,只有和session关联,才会持久态)
    get和load获取数据,先去缓存中查看,如果缓存中有,从缓存中获取,如果没有去数据库中查找
    get:立即发送sql语句
    load:生成代理对象,延迟抓取,只有获取id以外的属性时,才会发送sql语句

    Query查询会比较缓存和快照,如果一致取数据库直接取数据,如果缓存中持久化对象的属性已经发生变化,则先刷出缓存执行update,然后查询Query不从缓存中读取数据,但是会比较缓存和快照数据是否一致
    flush() : 修改数据库和缓存一样(提交缓存中数据到数据库,执行update)
    refresh(): 刷新缓存根数据库一样(重新执行select语句,刷新缓存,与数据库一样)

    一对多关系映射

    <hibernate-mapping package= "cn.domin">
        <class name= "Order" table ="p_order">
              <id name= "id">
                     <generator class= "native"></generator >
              </id>
              <property name= "name"></property >
              <property name= "price"></property >
             
              <!-- 映射关系: 多对一 -->
              <many-to-one name= "customer" class ="Order" column="cid" ></many-to-one>
        </class>
    </hibernate-mapping>
    
    
    
      <hibernate-mapping package= "cn.domin">
        <class name= "Customer" table ="p_customer">
              <id name= "id">
                     <generator class= "native"></generator >
              </id>
              <property name= "name"></property >
              <!-- 映射关系: 一对多-->
              <set name= "orders">
                     <key column= "cid"></key >
                     <one-to-many class= "Customer" />
              </set>
        </class>
      </hibernate-mapping>
    

    级联操作:cascade: save-update,delete
    级联保存,删除,的对象一定要是持久态,否则没有效果,设置某个对象级联,然后只操作这个对象就会执行相连的对象操作

    级联作用:

    可以使持久态对象“关联”瞬时态对象,自动会隐式执行save操作,变为持久态
    可以使持久太对象“关联”托管态对象,自动会隐式执行update操作,变为持久态
    在实际开发中,一对多模型中,一方一般是主动的一方(多方要依赖一方),如果配置级联,通常在一方进行配置
    因为多方需要引用一方的主键作为外键使用
    一般在业务开发中,不需要两端都配置级联,(多方尽量不要配置级联,尽量在一方配置级联)
    对象导航:其实是依赖于级联
    对象导航概念:通过一个对象的保存操作,可以自动导航到另外一个关联对象的保存操作

    一对多级联保存: one-to-many 或者 many-to-one

    < set name ="orders" cascade ="save-update,delete" inverse ="true">
    

    inverse:外键维护权问题,值应用于集合,在业务开发中一般在一方放弃维权
    true: 放弃外键维护权
    false:不放弃(默认)

    多对多关系映射

            <-- 映射关系
             设置中间表 p_s_c
              sid 对应中间表student的外键名称
             class: 表示集合属性名称对应的实体类
              cid: 对应中间表中Course对应的外键名
            -->
       <set name="courses" table= "p_s_c">
              <key column= "sid"></key >
              <many-to-many class= "cn.manytomany.Course" column="cid" ></many-to-many>
       </set >
    
    1

    相关文章

      网友评论

        本文标题:Hibernate(02)

        本文链接:https://www.haomeiwen.com/subject/uaddsxtx.html