定义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内,则一定需要实现此接口;

 <hibernate-mapping package="com.leo.chen.dao.hibernate">
<class name="User" table="user" dynamic-insert="true" dynamic-update="true">
<id name="id" column="id" access="property">
<generator class="native"></generator>
</id>
<property name="name" column="name access="field"></property>
<property name="password" column="password" access="field"></property>
</class>
</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就表示游离对象;

 <hibernate-mapping>
<class name="org.hibernate.tutorial.domain.Cart"
table="CARTS" dynamic-update="true">
<id name="name" type="string" access="field">
<column name="CART_NAME" />
<generator class="assigned" />
</id>
<version name="version" column="VERSION"
unsaved-value="null"/>
</class>
</hibernate-mapping>

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

 <hibernate-mapping>
<class name="mypack.Customer" table="CUSTOMERS">
<composite-id name="customerId" class="mypack.CustomerId">
<key-property name="name" column="NAME" type="string" />
<key-property name="company" column ="COMPANY_ID" type="long" />
</composite-id>
<version name="version" column="VERSION" unsaved-value="null" />
<many-to-one name="company" column="CLIENT_ID"
insert="false” update="false”
class="org.hibernate.tutorial.domain.Company" />
</class>
</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包装类型。

 <property name=”totalPrice”
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” />

最新文章

  1. 《Node即学即用》—— 读后总结
  2. 路由知识之ip route 命令中的疑惑
  3. MemberCached安装
  4. 对C#对象的Shallow、Deep Cloning认识【转】
  5. Labview中局部变量和全局变量
  6. python学习小结7:变量类型
  7. 11道php面试题
  8. Best Time to Buy and Sell Stock——LeetCode
  9. 修改TabPageIndicator下划线的颜色
  10. K-means算法简介
  11. mysql在ubuntu中的操作笔记(详)
  12. Bootstrap轮播如何支持移动端左右滑动
  13. python安装模块方法汇总
  14. kafka资料收集
  15. html5 canvas 奇怪的形状垂直渐变
  16. CRC8算法DELPHI源码
  17. [Windows Azure] How to Monitor Cloud Services
  18. Android 耳机插入过程分析
  19. Vue2学习笔记:v-on
  20. virtualbox+vagrant学习-2(command cli)-25-Machine Readable Output

热门文章

  1. bzoj 2565: 最长双回文串【manacher+线段树】
  2. 第八篇 .NET高级技术之字符串暂存池(缓冲池)
  3. 温习LOGO语言
  4. sql mysql和sqlserver存在就更新,不存在就插入的写法(转)
  5. 18.3.2从Class上获取信息(属性)
  6. SPRING-BOOT系列之Spring4快速入门
  7. AJPFX关于StringBuffer,StringBuilder类 总结(一)
  8. AJPFX对选择和冒泡两种排序的理解
  9. Java开发笔记(九十四)文件通道的性能优势
  10. UVa OJ 494