一般.hbm.xml文件如下面:
1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 4 <!-- Generated 2014-9-29 8:46:32 by Hibernate Tools 3.4.0.CR1 --> 5 <hibernate-mapping> 6 <class name="com.jeremy.hibernate.app.News" table="NEWS"> 7 <id name="id" type="java.lang.Integer"> 8 <column name="ID" /> 9 <generator class="native" /> 10 </id> 11 <property name="title" type="java.lang.String"> 12 <column name="TITLE" /> 13 </property> 14 <property name="author" type="java.lang.String"> 15 <column name="AUTHOR" /> 16 </property> 17 <property name="date" type="java.util.Date"> 18 <column name="DATE" /> 19 </property> 20 </class> 21 </hibernate-mapping>
<Hibernate-mapping>标签的属性如下:
1)package:指定一个包前缀,如果在映射文档中(就是在class标签的那么属性里没有指定全类名)没有指定全限定的类名,就使用这个作为包名,
2)schema:数据库schema的名称
3)catalog:数据库catalog的名称
4)default-cascade:默认的级联风格,默认为none
5)default-access:Hibernate用来访问属性的策略
6)default-lazy:指定了未明确注明lazy属性的Java属性和集合类,Hibernate会采取什么样的默认加载风格,默认为true
7)auto-import:指定我们是否可以在查询语言中使用非全限定的类名,默认为true,如果项目中有两个同名的持久化类,则最好在这两个类的对应的映射文件中配置为false
Hibernate的子标签class标签:
class 元素用于指定类和表的映射
name:指定该持久化类映射的持久化类的类名
example:<class name="com.jeremy.hibernate.example.News" table="NEWS">
table:指定该持久化类映射的表名, Hibernate 默认以持久化类的类名作为表名
example:<class name="com.jeremy.hibernate.example.News" table="NEWS">
dynamic-insert: 若设置为 true, 表示当(调用Session的save()方法时)保存一个对象时, 会动态生成 insert 语句, insert 语句中仅包含所有取值不为 null 的字段. 默认值为 false
Example:这个跟dynamic-update一个意思
dynamic-update: 若设置为 true, 表示当(调用对象的set()方法)更新一个对象时, 会动态生成 update 语句, update 语句中仅包含所有取值需要更新的字段. 默认值为 false
Example:当我们调用对象的set()方法时,Hibernate会自动帮我们发送更新语句给数据库是吧,但是有没有注意到发送给数据库语句有什么不同呢?下面看一下
@Test public void TestDymainUpdate(){ News news=(News) session.get(News.class, 1); news.setAuthor("jeremyJeremy"); }
这个是我测试的代码,当我运行这代码时控制台出现了下面的代码:
Hibernate: select news0_.ID as ID1_0_0_, news0_.TITLE as TITLE2_0_0_, news0_.AUTHOR as AUTHOR3_0_0_, news0_.DATE as DATE4_0_0_ from NEWS news0_ where news0_.ID=? Hibernate: update NEWS set TITLE=?, AUTHOR=?, DATE=? where ID=?
select部分是我调用的Session的get()方法,Hibernate自动发送的,
update部分是我调用了对象的set()方法触发的是吧,但是有没有注意到,我的测试代码里只更新一个Author属性吖,Hibernate为啥会帮我把其它属性也更新吖,虽然数据没变,但是是不是有点低效率吖,我只想我更新那个属性,Hibernate就帮我更新那个属性,所以这里就要用到class标签的dynamic-update属性了:当我把这属性值改为TRUE后:
Hibernate自动发送的语句:
Hibernate: update NEWS set AUTHOR=? where ID=?
select-before-update:设置 Hibernate 在更新某个持久化对象之前是否需要先执行一次查询. 默认值为 false
这个有在我一篇文章详细介绍:http://www.cnblogs.com/jeremy-blog/p/4000419.html
batch-size:指定根据 OID 来抓取实例时每批抓取的实例数.
lazy: 指定是否使用延迟加载.
mutable: 若设置为 true, 等价于所有的 <property> 元素的 update 属性为 false, 表示整个实例不能被更新. 默认为 true.
discriminator-value: 指定区分不同子类的值. 当使用 <subclass/> 元素来定义持久化类的继承关系时需要使用该属性
class标签的子标签
<id>标签:在对象-关系映射文件中, <id> 元素用来设置对象标识符. <generator> 子元素用来设定标识符生成器.
<id name="id" type="java.lang.Integer">---指定类中的ID属性和类型
<column name="ID" />-----数据库中列名
<generator class="native" />-----指定ID的自动生成方式,(例如自增,或者随机生成)
</id>
generator的class属性:
详细解析:
increment 标识符生成器由 Hibernate 以递增的方式为代理主键赋值
Hibernate 会先读取 NEWS 表中的主键的最大值, 而接下来向 NEWS 表中插入记录时, 就在 max(id) 的基础上递增, 增量为 1.
适用范围: 由于 increment 生存标识符机制不依赖于底层数据库系统, 因此它适合所有的数据库系统
适用于只有单个 Hibernate 应用进程访问同一个数据库的场合, 在集群环境下不推荐使用它 OID 必须为 long, int 或 short 类 型, 如果把 OID 定义为 byte 类型, 在运行时会抛出异常
模拟increment生成器产生问题的过程:
@Test public void testIncrement() throws InterruptedException{ News news1=new News("AA","AAAAA",new Date()); session.save(news1); Thread.sleep(5000); }
把上面的代码连续运行两次就相当于有连续两次的客户访问我的数据库,就是说同时多人访问我数据库时,大家读取到的max值都是一样的吧,所以插入的时候ID值会并发出主键重复的问题,所以在实际开发中不能应用这种方式来生成ID
还有很多主键生成器,我忽略一下,因为实在太多了
下面介绍一下class标签的子标签property
<property>:元素用于指定类的属性和表的字段的映射(关联起来)
属性:
name:指定该持久化类的属性的名字 column:指定与类的属性映射的表的字段名. 如果没有设置该属性, Hibernate 将直接使用类的属性名作为字段名. type:指定 Hibernate 映射类型. Hibernate 映射类型是 Java 类型与 SQL 类型的桥梁. 如果没有为某个属性显式设定映射类型,Hibernate 会运用反射机制先识别出持久化类的特定属性的 Java 类型, 然后自动使用与 之对应的默认的 Hibernate 映射类型.(例如Java.lang.String->String->varchar) update:设置该列是否可以被修改,默认是TRUE,设置为FALSE时不可以修改列的值,虽然修改了,也不会报错 not-null:若该属性值为 true, 表明不允许为 null, 默认为 false access:指定 Hibernate 的默认的属性访问策略。 默认值为 property, 即使用 getter, setter 方法来访问属性. 若指定 field, 则 Hibernate 会忽略 getter/setter 方法, 而通过反射访问成员变量 unique: 设置是否为该属性所映射的数据列添加唯一约束. index: 指定一个字符串的索引名称.当系统需要 Hibernate 自动建表时, 用于为该属性所映射的数据列创建索引, 从而加快该数据列的查询 length: 指定该属性所映射数据列的字段的长度 scale: 指定该属性所映射数据列的小数位数, 对 double, float, decimal 等类型的数据列有效. formula:设置一个 SQL 表达式,Hibernate 将根据它来计算出派生属性的值.派生属性:并不是持久化类的所有属性都直接和表的字段匹配, 持久化类的有些属性的值必须在运行时通过计算才能得出来, 这种属性称为派生属性 Example:例如下面的的desc列是有author列+“:”+title列组成的,那咋们可以这样配置formula
<!-- 映射派生属性 -->
<property name="desc" formula="(SELECT concat(author, ‘: ‘, title) FROM NEWS n WHERE n.id = id)"></property>