• Hibernate的持久化对象配置


    定义Pojo对象和**.hbm.xml文件

    -1 对于每一个需要持久化的对象都需要创建一个Pojo类定义,Hibernate要求POJO类定义中必须有一个no-argument的构造方法,便于Hibernate通过java reflection机制创建实例:[java.lang.reflect.Constructor.newInstance()];

    -2 对于Pojo类定义中的类属性而言,不管访问符是否为public,也不管是否提供了对应的setter/getter方法,Hibernate都可以通过java reflection进行访问,类属性类型最好使用装箱类型,便于业务隔离;
    -3 Hibernate也不要求每一个POJO必须实现Serializable接口,但如果对采用RMI和J2EE分布式结构的应用,POJO在不同进程节点之间传输时,或者在HttpSession内,则一定需要实现此接口;

    1 <hibernate-mapping package="com.leo.chen.dao.hibernate">
    2     <class name="User" table="user" dynamic-insert="true" dynamic-update="true"> 
    3         <id name="id" column="id" access="property">
    4             <generator class="native"></generator>
    5         </id>
    6         <property name="name" column="name access="field"></property>
    7         <property name="password" column="password" access="field"></property>
    8     </class>
    9  </hibernate-mapping>

    指定插入行的primary key生成策略

    设计数据库表的时候主键ID一般使用非业务相关的独立字段,从而保证主键在任何时候都不受业务变动的影响,对于<generator>而言hibernate提供了多种实现方式:
    #1 代理主键:increment
    由hibernate负责生成,每次增量为1,插入一条数据会执行两个sql语句,先从表中查找出最大的id,执行加1,然后插入当前数据;适用于所有数据库,但是如果多个SessionFactory同时连接一个DB,则increment的自增操作失效;仅适合DB被单个Hibernate App访问的场景;OID必须为Long、INT或者Short;

    #2 代理主键:identity
    由底层数据库负责生成,依赖数据库的主键自增功能;由DB设置,根据不同DB配置不同的DB dialect,从而映射成不同的类型,MySQL为auto_increment,SQL Server为identity;底层数据库必须支持自动增长字段的类型;OID必须为Long、INT或者Short;

    #3 代理主键:sequence
    由Hibernate设置,但序列来自于底层数据库;底层数据库必须支持序列,MySQL不支持序列,Oracle,DB2和PostgreSQL支持;OID必须为Long、INT或者Short;

    #4 单自然主键:assigned
    表示由应用程序为当前赋值,并且该属性为自然主键,业务相关,永远不会为null;一般而言saveOrUpdate()方法通过判断主键ID是否为null来确定对象的状态,当主键的生成属性generator为assigned的时候则不能判断;只能通过额外的属性<version>来控制;如果unsaved-value为null就表示为临时对象,非null就表示游离对象;

     1 <hibernate-mapping>
     2   <class name="org.hibernate.tutorial.domain.Cart" 
     3       table="CARTS" dynamic-update="true">
     4     <id name="name" type="string" access="field">
     5       <column name="CART_NAME" />
     6       <generator class="assigned" />
     7     </id> 
     8     <version name="version" column="VERSION" 
     9       unsaved-value="null"/>
    10   </class>
    11 </hibernate-mapping>

    #5 复合自然主键:composite-id
    Customer对象由CustomerId对象确定,CustomerId由name和company组成; 凡是由自然键担任主键的class都需要定义version属性以区分状态;<many-to-one>标签表示company与customer为多对一的关系;Insert和update属性为false表示当customer对象被保存的时候,会忽略company属性;

     1 <hibernate-mapping>
     2   <class name="mypack.Customer" table="CUSTOMERS">
     3     <composite-id name="customerId" class="mypack.CustomerId">
     4       <key-property name="name" column="NAME" type="string" />
     5       <key-property name="company" column ="COMPANY_ID" type="long" />
     6     </composite-id>
     7     <version name="version" column="VERSION" unsaved-value="null" />
     8     <many-to-one name="company" column="CLIENT_ID" 
     9       insert="false” update="false”
    10       class="org.hibernate.tutorial.domain.Company" />
    11   </class>
    12 </hibernate-mapping> 

    #6 hilo:由hibernate根据hilo算法自己生成主键。
    #7 native:根据底层数据库对自动生成主键的支持能力选择 identity|sequence|hilo
    #8 uuid :根据当前机器的mac地址和time生成UUID作为主键。
    #9 customized class:可以通过实现org.hibernate.id.IdentifierGenerator接口自定义id。

    指定Dao类属性的访问方式
    <id>和<property>的属性access可以控制类属性的访问方式,缺省为property:
    #1 access=”field”:表示让hibernate通过反射的方式直接访问field,丢失封装性;
    #2 access=”property”:表示让hibernate通过类对外暴露的getter/setter访问field,推荐;

    指定Dao类和关联对象的数据加载策略和SQL生成方式
    加载Dao对象<class>元素可以使用属性lazy控制类数据的加载时机,缺省为true;
    #1 lazy=”true”:当使用load()加载对象时会先生成一个代理对象,其中只有primary key被赋值,其他属性只有等对象实际被使用时才会生成SQL语句到DB进行查询。
    #2 lazy=”false”:立即加载,也就是使用load方法会立即生成SQL到DB进行查询。

    级联查询<set>元素使用lazy来控制关联对象的加载时机,缺省值为true;
    #1 lazy=”true”:跟<class>级别同理;
    #2 lazy=”false”:跟<class>级别同理;
    #3 lazy=”extra”:采用精细化的延迟加载,比如关联对象调用size/contains/isEmpty等非访问整个集合的元素方法时,不会加载整个集合元素,仅生成返回特定信息的SQL;

    级联查询<set>元素使用fetch来控制查询关联对象时的SQL生成策略
    #1 fetch=”select”:缺省值,额外生成一条SQL进行独立查询。
    #2 fetch=”subselect”:额外生成一条SQL查询集合数据,比如当查询多个用户,每个用户上有多个订单,这样可以通过一条独立的SQL 将所有用户的所有订单一次性查询出来,在内存中将不同的订单分配到不同用户上。
    #3 fetch=”join”:采用LEFT JOIN table的方式生成唯一SQL,减少执行SELECT的次数,同时会忽略lazy属性,立即加载所有数据,但由于关联多张表,可以造成性能下降;

    级联查询<many-to-one>/<one-to-many>也有lazy和fetch属性,功能也类似。另外<class>和<set>元素上设置batch-size=”10”可以生成批量加载数据的SQL将数据放入缓存,从而减少SQL语句的执行条数。

    通过sql语句获取复杂查询的字段值
    Hibernate将根据formula的sql语句动态为totalPrice设置值,formula可以操作各表字段,所以并不需要orders表中有total_price的字段;如果formula查询的结果为空则totalPrice的值返回null,因此Java类中totalPrice的属性需要设置为Double包装类型。

    1 <property name=”totalPrice” 
    2   formula=”SELECT SUM(o.price) FROM orders o WHERE o.customer_id=id” />

    强制动态生成insert和update的SQL语句
    缺省情况下Hibernate会预先生成并编译针对所有column的insert和update子句;但预编译好的sql语句不管待写入DB的字段是否为空,也不管待写入DB的字段是否有更新,都全部进行操作,当column比较多的时候缺省设置会耗费比较多的DB资源;因此Hibernate提供关键字用于控制<class>上各个column的插入和更新:
    #1 insert属性:缺省为true;如果为false,表示Hibernate不再为insert生成price字段,也就是该DB column不能被插入;
    <property name=”price” insert=”false” />

    #2 update属性:缺省为true;如果为false,表示Hibernate不再为update生成price字段,也就是该DB column不能被更新;
    <property name=”price” update=”false” />

    #3 mutable属性:缺省为true;如果为false,表示所有该class的property的update属性为false,该实例不能被更新;
    <class name=”org.hibernate.totorial.domain.User” table=”USER” mutable=”false” />

    #4 dynamic-insert属性:缺省为false;如果为true,表示插入一个对象时动态生成insert语句,insert的字段仅包含取值不为null的字段;
    <class name=”org.hibernate.totorial.domain.User” table=”USER” dynamic-insert=”true” />

    #5 dynamic-update属性:缺省为false;如果为true,表示更新一个对象时动态生成update语句,update的字段仅包含取值有更新的字段;
    <class name=”org.hibernate.totorial.domain.User” table=”USER” dynamic-update=”true” />

    #6 select-before-update属性:缺省为false,表示只要使用Session.update(),则不管目标对象的属性是否有更新都会执行UPDATE操作;如果为true,则会先执行一条SELECT语句查询DB的状态并对比是否有更新,表示仅当目标对象的属性被修改时才执行UPDATE操作;
    <class name=”org.hibernate.totorial.domain.User” table=”USER” select-before-update=”true” />

  • 相关阅读:
    什么叫开漏输出
    PIC16F877A TIMER1计数操作
    [转载]【Alientek STM32 实验2】按键输入
    STM32学习笔记1 IO口学习
    时间“四象限”法
    CLANNAD AFTER STORY 片头曲 「铭刻时间的歌」
    正则表达式测试工具
    War3窗口限定小工具发布
    利用ffmpeg转换mp4文件
    一个类似FlashGet的c#开源下载工具
  • 原文地址:https://www.cnblogs.com/leo-chen-2014/p/4940569.html
Copyright © 2020-2023  润新知