1.Hibernate调用对象的getXXX()方法,读取对象信息,把它保存到数据库。调用对象的setXXX()方法,把从数据库中读出的对象信息写入到对象中。
即Hibernate的session执行save(),update()或saveOrUpdate()方法时会调用对象的getXXX()方法。
当session执行get()或load()方法时,以及Query执行查询时会调用对象的set()方法。
在持久化类中,既可把属性定义为基本类型,也可以定义为包装类型,他们对应相同的Hibernate映射类型。
比如double和Double 都是<property name="XXX" type="double" column="xxx">
Hibernate访问持久化类属性的策略(<property>元素access属性指定Hibernate访问持久化类属性的方式)
1.property:这是默认值,表明Hibernate通过get/set方法访问类的属性。优先推荐。
2.field:表明Hibernate运用Java反射机制直接访问类的属性。e.g. <property name="name" access="field">
3.还可以自定义持久化类的属性访问方式。这需要创建一个实现org.hibernate.property.PropertyAccessor接口的类,
并将类的完整名字赋值给<property>的access属性。
2.设置派生属性
利用<property>元素的formula属性: formula属性用来设置一个sql表达式
e.g. 当表中没有对应属性字段TOTAL_PRICE时可以
<property name="totalPrice" formula="(select sum(o.PRICE) from ORDERS o where o.CUSTOMER_ID=ID)"/>
如果子查询语句查询结果为空,Hibernate会把totalPrice赋值为null,所以不能使用基本数据类型
formula指定SQL表达式中可以引用表字段,调用SQL函数或包含子查询语句
e.g. 表示客户购买单项商品信息的LineItem类中有一个unitPrice属性,取值为:商品单价(BASE_PRICE)*购买数量(QUANTITY)
<property name="unitPrice" formula="BASE_PRICE*QUANTITY"/>
3.控制insert和update语句
Hibernate在初始化阶段会根据映射文件信息,为所有的持久化类预定义insert,updatea,delete和根据OID加载数据库中持久化实例的SELECT
e.g.
insert into USER(ID,NAME) values(?,?);
update USER set NAME=? where ID=?;
delete from USER where ID=?;
select ID,NAME from USER where ID=?;
以上SQL语句中的?号代表JDBC PreparedStatement中的参数.这些SQL语句都放在SessionFactory的内置缓存中,当执行Session的
save(),update(),delete(),load()和get()方法时,将从缓存中找到相应的SQL语句,再把参数值绑定到该SQL语句中。
Tips:HQL或QBC查询对应的select语句是在执行该代码时菜动态生成的。
默认情况下,预定义的SQL语句中包含了表的所有字段,此外Hibernate还允许在映射文件中控制insert和update语句的内容
用于控制insert和update语句的映射属性
<property>元素的insert属性:如果为false,在insert语句中不包含该字段,表明该字段永远不能被插入。默认值为true
<property>元素的update属性:如果为false,在update语句中不包含该字段,表明该字段永远不能被更新。默认值为true
<class>元素的mutable属性:如果为false,等价于所有<property>元素的update属性为false,表示整个实例不能被更新,默认值为true。
<class>元素的dynamic-insert属性:如果为true,表示当保存一个对象时,会动态生成insert语句,insert语句中仅包含所有取值不为null的字段。默认为false。
<class>元素的dynamic-update属性:如果为true,表示当更新一个对象时,会动态生成update语句,update语句中仅包含所有需要更新的字段。默认为false。
Hibernate生成动态SQL语句的系统开销很小,因此不会影响应用的运行性能。如果表中包含许多字段,建议把dynamic-insert属性
和dynamic-update属性都设为true。这样,可以节省数据库执行SQL语句的时间,从而提高应用的运行性能。
4.处理SQL引用标识符
标识符:是指用于数据库表、视图、字段或索引等命名的字符串。常规标识符不包含空格也不报告特殊字符,因此无须使用引用符号。
e.g. crete table CUSTOMERS(ID bigint not null,NAME varchar(15) ... 中的CUSTOMERS,ID和NAME都是标识符。
如果数据库表名或字段名中包含空格或特殊字符,那么可以使用引用标识符。
e.g. CUSTOMERS表中有一个引用标识符字段`CUSTOMER DESCRIPTION`
映射文件中也应该使用标识符<property name="description" column="`CUSTOMER DESCRIPTION`"/>
注意:不同数据库,引用标识符有不同的形式,SQLServer中为[],MySQL中为 `` 。在设置Hibernate映射文件时一律采用``,hibernate根据方言生成正确标识符。
5.创建命名策略
表名和字段名都大写,表名以S结尾。
可以通过实现Hibernate的org.hibernate.cfg.NamingStrategy接口实现。Hibernate提供两个参考实现类
org.hibernate.cfg.DefaultNamingStraegy类:这是NamingStrategy类的接口的默认实现类。
org.hibernate.cfg.ImprovedNamingStragegy类:这是NamingStrategy接口的高级实现类。
6.设置数据库Schema
如果一个数据库系统中调用不同的Schema中存在命名相同的表。可以在<hibernate-mapping>元素中设置一个schema属性:
e.g. <hibernate-mapping schema="schema1">则会把该映射文件中的持久化类映射为表 schema1.XXX
如果个别类和schema2中的表映射,那么可以在这些个别类的<class>元素中设置一个schema属性<class name="Xxx" table="XXX" schema="schema2">
7.设置类的包名
默认情况下,在设置<class>元素的name属性时,必须提供完整的类名,即包名.类名。
如果一个映射文件下多个类属于同一个包,可以设置<hibernate-mapping>元素的package属性。 e.g. <hibernate-mapping package="mypack">
即Hibernate的session执行save(),update()或saveOrUpdate()方法时会调用对象的getXXX()方法。
当session执行get()或load()方法时,以及Query执行查询时会调用对象的set()方法。
在持久化类中,既可把属性定义为基本类型,也可以定义为包装类型,他们对应相同的Hibernate映射类型。
比如double和Double 都是<property name="XXX" type="double" column="xxx">
Hibernate访问持久化类属性的策略(<property>元素access属性指定Hibernate访问持久化类属性的方式)
1.property:这是默认值,表明Hibernate通过get/set方法访问类的属性。优先推荐。
2.field:表明Hibernate运用Java反射机制直接访问类的属性。e.g. <property name="name" access="field">
3.还可以自定义持久化类的属性访问方式。这需要创建一个实现org.hibernate.property.PropertyAccessor接口的类,
并将类的完整名字赋值给<property>的access属性。
2.设置派生属性
利用<property>元素的formula属性: formula属性用来设置一个sql表达式
e.g. 当表中没有对应属性字段TOTAL_PRICE时可以
<property name="totalPrice" formula="(select sum(o.PRICE) from ORDERS o where o.CUSTOMER_ID=ID)"/>
如果子查询语句查询结果为空,Hibernate会把totalPrice赋值为null,所以不能使用基本数据类型
formula指定SQL表达式中可以引用表字段,调用SQL函数或包含子查询语句
e.g. 表示客户购买单项商品信息的LineItem类中有一个unitPrice属性,取值为:商品单价(BASE_PRICE)*购买数量(QUANTITY)
<property name="unitPrice" formula="BASE_PRICE*QUANTITY"/>
3.控制insert和update语句
Hibernate在初始化阶段会根据映射文件信息,为所有的持久化类预定义insert,updatea,delete和根据OID加载数据库中持久化实例的SELECT
e.g.
insert into USER(ID,NAME) values(?,?);
update USER set NAME=? where ID=?;
delete from USER where ID=?;
select ID,NAME from USER where ID=?;
以上SQL语句中的?号代表JDBC PreparedStatement中的参数.这些SQL语句都放在SessionFactory的内置缓存中,当执行Session的
save(),update(),delete(),load()和get()方法时,将从缓存中找到相应的SQL语句,再把参数值绑定到该SQL语句中。
Tips:HQL或QBC查询对应的select语句是在执行该代码时菜动态生成的。
默认情况下,预定义的SQL语句中包含了表的所有字段,此外Hibernate还允许在映射文件中控制insert和update语句的内容
用于控制insert和update语句的映射属性
<property>元素的insert属性:如果为false,在insert语句中不包含该字段,表明该字段永远不能被插入。默认值为true
<property>元素的update属性:如果为false,在update语句中不包含该字段,表明该字段永远不能被更新。默认值为true
<class>元素的mutable属性:如果为false,等价于所有<property>元素的update属性为false,表示整个实例不能被更新,默认值为true。
<class>元素的dynamic-insert属性:如果为true,表示当保存一个对象时,会动态生成insert语句,insert语句中仅包含所有取值不为null的字段。默认为false。
<class>元素的dynamic-update属性:如果为true,表示当更新一个对象时,会动态生成update语句,update语句中仅包含所有需要更新的字段。默认为false。
Hibernate生成动态SQL语句的系统开销很小,因此不会影响应用的运行性能。如果表中包含许多字段,建议把dynamic-insert属性
和dynamic-update属性都设为true。这样,可以节省数据库执行SQL语句的时间,从而提高应用的运行性能。
4.处理SQL引用标识符
标识符:是指用于数据库表、视图、字段或索引等命名的字符串。常规标识符不包含空格也不报告特殊字符,因此无须使用引用符号。
e.g. crete table CUSTOMERS(ID bigint not null,NAME varchar(15) ... 中的CUSTOMERS,ID和NAME都是标识符。
如果数据库表名或字段名中包含空格或特殊字符,那么可以使用引用标识符。
e.g. CUSTOMERS表中有一个引用标识符字段`CUSTOMER DESCRIPTION`
映射文件中也应该使用标识符<property name="description" column="`CUSTOMER DESCRIPTION`"/>
注意:不同数据库,引用标识符有不同的形式,SQLServer中为[],MySQL中为 `` 。在设置Hibernate映射文件时一律采用``,hibernate根据方言生成正确标识符。
5.创建命名策略
表名和字段名都大写,表名以S结尾。
可以通过实现Hibernate的org.hibernate.cfg.NamingStrategy接口实现。Hibernate提供两个参考实现类
org.hibernate.cfg.DefaultNamingStraegy类:这是NamingStrategy类的接口的默认实现类。
org.hibernate.cfg.ImprovedNamingStragegy类:这是NamingStrategy接口的高级实现类。
6.设置数据库Schema
如果一个数据库系统中调用不同的Schema中存在命名相同的表。可以在<hibernate-mapping>元素中设置一个schema属性:
e.g. <hibernate-mapping schema="schema1">则会把该映射文件中的持久化类映射为表 schema1.XXX
如果个别类和schema2中的表映射,那么可以在这些个别类的<class>元素中设置一个schema属性<class name="Xxx" table="XXX" schema="schema2">
7.设置类的包名
默认情况下,在设置<class>元素的name属性时,必须提供完整的类名,即包名.类名。
如果一个映射文件下多个类属于同一个包,可以设置<hibernate-mapping>元素的package属性。 e.g. <hibernate-mapping package="mypack">