什么是持久化类?
Hibernate是持久层的ORM映射框架,专注于数据的持久化工作。所谓的持久化,就是将内存中的数据永久的存储到关系型数据库中。那么知道了什么是持久化,什么又是持久化类呢?其实持久化类就是一个Java类与数据库表建立了映射关系,那么这个类称为是持久化类。其实你可以简单的理解为持久化类就是一个Java类有了一个映射文件与数据库的表建立了关系。
持久化类的编写规则
持久化类需要提供无参构造。
因为在Hibernate底层需要使用反射生成类的实例。持久化类的属性需要私有,并提供get & set方法。
因为在Hibernate底层会将查询到的数据进行封装。持久化类的属性要尽量使用包装类的类型。
因为包装类和基本数据类型的默认值不同,包装类的类型予以描述更清晰而基本数据类型不容易描述。举个例子:
假设表中有一列员工工资,如果使用double类型,如果这个员工工资忘记录入到系统中,系统会将默认值0存入到数据库,如果这个员工工资被扣完了,也会向系统中存入0。那么这个0就有了多重含义,而如果使用包装类类型就会避免以上情况,如果使用Double类型,忘记录入工资就会存入null,而这个员工工资被扣完了,就会存入0,不会产生歧义。
持久化类要有一个唯一标识OID与表的主键对应。
因为Hibernate需要通过这个唯一标识OID区分在内存中是否是同一个持久化类。在Java中通过地址区分是否是同一个对象,在关系型数据库的表中是通过主键区分是否是同一条记录。Hibernate就是通过这个OID来进行区分的。Hibernate是不允许内存中出现两个OID相同的持久化对象的。持久化类尽量不要使用final进行修饰。
Hibernate中有延迟加载的机制。这个机制中会产生代理对象,Hibernate产生代理对象使用的是字节码的增强技术完成的,其实就是产生了当前类的一个子类对象实现的。如果使用了final修饰持久化类,就不能产生子类,从而不会产生代理对象,那么Hibernate的延迟加载策略(一种优化手段)就会失效。
Hibernate的主键的类型
-
自然主键
把具有业务含义的字段作为主键,称之为自然主键。比如在一个goods表中,如果把商品名name作为主键,其前提条件必须是:每一个商品的名字不允许为null,不允许重名,并且不允许修改商品名。尽管这也是可行的,但是不能满足不断变化的业务需求,一旦出现了允许客户重名的业务需求,就必须修改数据模型,重新定义表的主键,这给数据库的维护增加了难度。 -
代理主键
把不具备业务含义的字段作为主键,称之为代理主键。该字段一般取名为“ID”,通常为整数类型,因为整数类型比字符串类型要节省更多的数据库空间。
Hibernate的主键生成策略
Hibernate中提供了几个内置的主键生成策略,其常用主键生成策略的名称和描述如下:
名称 | 描述 |
---|---|
increment | 用于long、short、int类型,由Hibernate自动以递增方式生成唯一标识,每次增量为1。只有当没有其他进程向同一张表中插入数据时才可以使用,不能在集群环境下使用。适用于代理主键。 |
identity | 采用底层数据库本身提供的主键生成标识符,条件是数据库支持自动增长数据类型。在DB2、MySQL、MS SQL Server、Sybase和HypersonicSQL数据库中可以使用该生成器,该生成器要求在数据库中把主键定义为自增长类型。适用于代理主键 |
sequence | Hibernate根据底层数据库序列生成标识符。条件是数据库支持序列。适用于代理主键。 |
native | 根据底层数据库对自动生成标识符的能力来选择identity、sequence、hilo三种生成器的一种,适合跨数据库平台开发。适用于代理主键。 |
uuid | Hibernate采用128位的UUID算法来生成标识符。该算法能够在网络环境中生成唯一的字符串标识符,其UUID被编码为一个长度为32位的十六进制字符串。这种策略并不流行,因为字符串类型的主键比证书类型的主键占用更多的数据库空间。适用于代理主键。 |
assigned | 由Java程序负责生成标识符,如果不指定id元素的generator属性,则默认使用该主键生成策略。适用于自然主键。 |