Hibernate之对象关系映射文件

本文深入探讨了对象关系映射(ORM)的概念,详细解析了Hibernate映射文件的结构和配置,包括类与表的映射、主键生成策略、属性映射以及Java类型与SQL类型间的转换。

一、对象关系映射文件

  • POJO类和关系数据库之间的映射可以用一个XML文档来定义

  • 在运行时Hibernate将根据这个映射文件来生成各种SQL语句

  • 映射文件的拓展名为 .hbm.xml

1.映射文件说明

<hibernate-mapping>
​
    <class name="com.yfy.hibernate.entity.NewsEntity" table="news" schema="hibernate" dynamic-insert="true" dynamic-update="true" >
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="native" />
        </id>
        <property name="title" column="title"/>
        <property name="author" column="author"/>
        <property name="data" column="data"/>
    </class>
</hibernate-mapping>
  • hibernate-mapping

    • 类层次:class

      • 主键:id

      • 基本类型:property

      • 实体引用类:many-to-one | one-to-one

      • 集合:set | list | map | array

        • one-to-many | many-to-many

      • 子类:subclass | joined-subclass

      • 其它:component | any等

    • 查询语句:query

  • 每个hibernate-mapping可以同时定义多个类,但推荐为每个类都创建一个单独的映射文件

(1)hibernate-mapping

Hibernate-mapping是hibernate映射文件的根元素

  • schema:指定所映射的数据库schema的名称。若指定该属性,则表明会自动添加该schema前缀

    select * from 数据库名.表名
  • catalog:指定所映射的数据库catalog的名称

  • default-cascade(默认:none):设置Hibernate默认的级联分格

  • default-access(默认:property):指定Hibernate的默认属性访问策略。property会使用getter、setter方法访问属性,若指定access,则会通过反射访问成员变量

  • default-lazy(默认:true):默认启用延迟加载策略

  • auto-import(默认:true):指定是否可以在查询语句中使用非全限定的类名

  • package:指定一个包前缀,如果在映射文档中没有指定全限定的类名,就使用这个作为包名

(2)class属性

class元素用于指定类和表的映射

  • name:指定该持久化类的类名

  • table:指定该持久化类映射的表名

  • dynamic-insert(默认:false):若设置为true,表示当保存一个对象时,会动态生成insert语句,insert语句中仅包含所有取值不为null的字段

    NewsEntity newsEntity = new NewsEntity();
            newsEntity.setTitle("hibernate入门");
            newsEntity.setData(new Date());
            session.save(newsEntity);
    //title为null,不会插入title        
    sql语句:
        Hibernate: 
        insert 
        into
            hibernate.news
            (title, data) 
        values
            (?, ?)

     

  • dynamic-update(默认:false):若设置为true,表示当更新一个对象时,会动态生成update语句,update语句中仅包含所有取值需要更新的字段

            NewsEntity newsEntity = (NewsEntity)session.get(NewsEntity.class, 20);
            newsEntity.setAuthor("java23");
            newsEntity.setData(new Date());
            session.update(newsEntity);
    ​
    //title没有改变,author和之前一样
        update
            hibernate.news 
        set
            data=? 
        where
            id=?

     

  • batch-size:指定根据OID来抓取实例时每批抓取的例数

  • lazy:指定是否使用延迟加载

  • multable(默认:true):若设置为false,等价于所有的property元素的update属性为false,表示整个实例不能被更新,默认为true

(3)映射对象标识符

  • Hibernate使用对象标识符(OID)来建立内存中的对象和数据表中记录的对应关系。对象的OID和数据表的主键对应,Hibernate通过标识符生成器来为主键赋值

  • Hibernate推荐在数据表中使用代理主键,即不具备业务含义的字段,代理主键通常为整数类型,因为整数类型要比字符串类型节省更多的数据库空间

  • 在映射文件中,<id>元素用来设置对象标识符,<generator>子元素用来设定标识符生成器

  • Hibernate提供了标识符生成器接口:IdentifierGenerator,并提供了各种内置实现

(4)id

设定持久化类的OID和表的主键的映射

  • name:标识持久化类OID的属性名

  • column:设置标识属性所映射的数据表的列名

  • unsaved- value:若设定了该属性,Hibernate会通过比较持久化类的OID值和该属性值来区分当前持久化类的对象是否为临时对象

  • type:指定Hibernate映射类型

注意:Hibernate映射类型,基本数据类型无法表达null,所以对于持久化类的OID推荐使用包装类型

        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="native" />
        </id>

(5)generator

设定持久化类设定标识符生成器

  • 主键生成策略

标识符生成器描述
increment由Hibernate以递增方式生成
identity由底层数据库生成标识符
sequence底层数据库的序列生成标识符,要求数据库支持序列
hiloHibernate分局high/low算法生成标识符
sequilo使用高/低位算法高效的生成long,short,int类型标识符
native根据底层数据库对自动生成标识符的方式,自动选择identity,sequence或hilo
uuid.hex采用128位的UUID算法生成标识符
uuid.stringUUID被编码成一个16字符长的字符串
assigned由java应用程序负责生成标识符
foreign使用另外一个相关联的对象的标识符

increment:

  • Hibernate会先读取对应表中主键的最大值,接下来向表中插入记录时,就在max(id)的基础上递增,增量为1

  • 适用范围:

    • 适合所有的数据库系统

    • 适用于只有单个Hibernate应用进程访问同一个数据库的场合,在集群环境下不推荐使用

    • OID必须为long,int或short类型

identity:

  • 要求底层数据库把主键定义为自动增长类型

  • 适用范围:

    • 支持自动增长字段类型的数据库:DB2,Mysql,MSSQLServer,Sybase等

    • OID必须为long,int或short类型

sequence:

  • 在持久化一个对象时,先从底层数据库的序列中获得一个唯一的标识号,再把它作为主键值

  • 适用范围:

    • 支持序列的数据库:DB2,Oracle等

    • OID必须为long,int或short类型

hilo:

  • 按照一种high/low算法生成标识符,它从数据库的特定表的字段中获取high值

<id name="id">
    <generator class="hilo">
        <param name="table">hl_table</param>
        <param name="column">next_value</param>
        <!-- 每次增加的id(默认为0)   1/12/23 -->
        <param name="max_lo">10</param>
    </generator>
</id>

native:

  • 适用范围:

    • 能根据底层数据库系统的类型,自动选择合适的标识符生成器,因此很适合与跨数据库平台开发

    • OID必须为long,int或short类型

(6)Property

property元素用于指定类的属性和表的字段的映射

  • name:指定该持久化类的属性的名字

  • column:指定与类的属性映射的表的字段名,如果没有设置该属性,将直接使用类的属性名作为字段名

  • type:指定Hibernate映射类型

  • not-null:若该属性为true,表名不允许为null,默认为false

  • access:指定Hibernate的默认的属性访问策略。默认为property,若指定filed,则通过反射访问成员变量

  • unique:设置是否为该属性所映射的数据列添加唯一约束

  • index:指定一个字符串的索引名称

        <property name="author" type="java.lang.String" index="news_index">
            <column name="AUTHOR" />
        </property>
  • length:指定该属性所映射数据列的字段的长度

  • scale:指定该属性锁映射数据列的小树数位

  • formula:设置一个SQL表达式,Hibernate将根据它来计算出派生属性的值

    • formula="sql"

    • sql表达式中的列名和表名都应该和数据库对应,而不是和持久化对象的属性对应

    • 如果需要在formula属性中使用参数,直接使用 where cur.id=id形式,其中id就是参数,和当前持久化对象的id属性对应的列的id值将被作为参数传入

        <!-- 映射派生属性 -->
        <property name="desc" formula="(SELECT concat(author, ': ', title) FROM NEWS n WHERE n.id = id)"></property>

(7)java类型与SQL类型之间的对应关系

Hibernate映射类型Java类型SQL类型大小
integer/intjava.lang.Integer/intinteger4字节
longjava.lang.Long/longbigint8字节
shortjava.lang.Short/shortsmallint2字节
bytejava.lang.Byte/bytetinyint1字节
floatjava.lang.Float/floatfloat4字节
doublejava.lang.Double/doubledouble6字节
big_decimaljava.math.BigDecimalmumeric 
characterjava.lang.Character/charchar(1)定长字符
stringjava.lang.Stringvarchar变长字符
booleanjava.lang.Boolean/booleanbit布尔类型
datejava.util.Date/java.sql.Datedate日期
timestampjava.util.Date/java.sql.Timestamptimestamp日期
calandarjava.util.Calendartimestamp日期
calandar_datejava.util.Calendardate日期
binarybyte[]blobblob
textjava.lang.Stringtextclob
serializable实现java.io.Serializable接口的类blobblob
clobjava.sql.Clobclobclob
blobjava.sql.Blobblobblob
classjava.lang.Classvarchar定长字符
localejava.util.Localevarchar定长字符
timezonejava.util.TimeZonevarchar定长字符
currencyjava.util.Currencyvarchar定长字符
  • 以下情况下必须显示指定Hibernate映射类型

    • 一个Java类型可能对应多个Hibernate映射类型。例如:如果持久化类的属性为java.util.Date类型,对应的Hibernate映射类型可以是date,time或timestamp。此时必须根据对应的数据表的字段的SQL类型,来确定Hibernate映射类型

  • java大对象的Hibernate映射

    • java中,提供了Clob和Blob类型,对应SQL中的CLOB和BLOB类型。CLOB表示字符串大对象,BLOB表示二进制对象

    • Mysql不支持标准SQL的CLOB类型,在Mysql中,用text,mediumtext及longtext类型表示长文本数据

    • 实际上在Java中处理长度超过255的字符串,使用String更方便

            <!-- 映射大对象 -->
            <!-- 若希望精确映射 SQL 类型, 可以使用 sql-type 属性. -->
            <property name="content">
                <column name="CONTENT" sql-type="mediumtext"></column>
            </property>
            
            <property name="image">
                <column name="IMAGE" sql-type="mediumblob"></column>

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值