hibernate主键生成策略

持久化类的概述

什么是持久化类
持久化:将内存中的一个对象持久化到数据库中的过程。 Hibernate框架就是用来进行持久化的框架
持久化的类:一个java对象与数据库的表建立了映射关系, 那么这个类在Hibernate中就称之为持久化类。
持久化类 = java 类+ 映射文件

持久化类的编写规则:

对持久化类提供一个无参数的构造器。 Hibernate当中底层要通过反射生成实例。

属性私有,对私有的属性提供publci的set/get方法 Hibernate中获得, 设置对象的值。
对持久化类提供一个唯一的标识OID 和 数据库表主键对应。 java当中通过对象的地址区分是否是同一个对象, 数据库中通过主键确定是否是同一个记录。 在Hibernate当中通过持久化类的OID的属性区分是否是同一个对象。

持久化类当中的属性尽量使用包装类的类型。 因为基本数据类型默认值是0,会产生很多的歧义。 包装类的默认类型是NULL。

持久化的类不要使用final进行修饰 Hibernate当中的延迟加载, 是Hibernate当中的一个优化手段, 返回的是一个代理对象(CGLIB-使用了字节码的增强技术,继承了这个类进行代理)如果不能被继承, 就不能产生代理对象,*延迟加载就会失效 *,get方法和load方法就会产生一样的效果(演示)。

1.3.主键的生成策略

1.3.1:主键的分类
自然主键
(一般不推荐使用)
主键的本身就是表中的一个字段。(可以是实体当中的一个具体的属性)
创建一个人员表,人员表当中都会一个身份证号(唯一不可重复),使用了身份证号作为主键,这样的主键就是自然主键。
代理主键
主键的本身不是表当中必须的一个字段, (不是实体当中的具体的某个属性)
创建一个人员表,没有使用人员中的身份证号, 使用了和这个表当中不相关的字段,ID。这样的主键就是代理主键 。

总结:

**在实际开发当中, 尽量使用代理主键。

1:一旦自然主键参与到了业务逻辑当中, 后期可能需要需要源代码。
2:好的程序设计满足的原则是ocp原则, 对程序的扩展open的, 对修改源代码是close的。

1.3.2:主键的主键生成策略

Hibernate当中的主键生成策略

在实际的开发过程当中一般不允许用户手动设置主键, 一般将主键交给数据库, 手动编写进行配置, 在Hibernate当中为了程序的编写, 提供了很多的主键的生成策略。
Increment
Hibernate当中提供的自动增长机制, 使用short , int , long类型的主键, 在单线程当中使用。
首先会发送一条sql 语句: select max(id) from tableName ,然后id+1, 作为下一条记录的主键。 (*)
identity :
使用short int long 类型的主键, 使用的是数据库底层的自动增长机制。有自动增长的的数据库。 Mysql MSSQL ,但是Oracle 没有自动增长。
squence :
使用short int long 类型的主键, 采用序列的方式。 oracle 就支持序列。 Mysql 就不能使用序列。
uuid :
使用于字符串类型的主键。 会使用Hibernate当中的随机方式生成字符串。
native用的最多的) :
本地策略, 可以是indentify 和 Sequence 之间自动切换。
assigned
Hibernate放弃主键的管理, 通过手动现写程序或者用户自己设置。
foreign
外部的, 在一对一的关联映射的情况下会使用。 (主键对应)一个表的主键在另外一个表当中还充当主键字段。 很少使用。

1.3.2.2代码的测试:

/*

  • 测试主键的生成策略:

*/
在hibernate.hbm.xml中配置:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
        
<hibernate-mapping>
   <!-- class : 标签:
        name : 实体bean的全路径名称: 
        table: 实体类对应的底层数据库表:  当实体类的名称和表的名称一致的情况下, 可以省略的。 
        catalog: 对应数据库的名称: 可以省略 
     -->
	<class name="com.yidongxueyuan.domain.Customer" table="cst_customer" >
		<!-- 配置主键字段: 
		   单独的标签: id :  
		   name: 实体当中的属性: 
		   column: 对应表当中的字段。 
		       制定主键的生成策略:  
		 -->
		<id name="cust_id" column="cust_id"  >
		    <!-- 主键的生成策略 
		     genderator: 明确主键字段是来维护: 维护的具体的方式: 
		     主键字段: 可以有底层具体的数据库来维护: 还可以通过程序员编写代码维护, 可以交给Hibernate来维护。 
		   increment:    short  int  long : Hibernate以自增的方式维护。   只能在单线程使用: 
		                   原理:  select max(id) from table;  
		             insert into table (id) vlaues(id+1); 
		             
				        不能应用在集群环境或者是多线程环境当中: 
				            多线程:     select max(id) from table;  
				            两个线程: 获得了同一个  max(id) 值: 
				            当第一个线程获得了cpu的执行权: 执行插入, 能够将数据正常的插入: 
				            第二个线程, 获得cpu的执行权, 不能插入, 主键重复。  
				            
            identity : 适应于short int long类型的主键字段:  底层是使用数据库的主键自增机制: 
		            前提: 数据库必须支持主键自增: Mysql DB2  Sybase 
		          Oracle: 不支持主键自增:  
		          
		    
		     Sequence :适应于short int long类型的主键字段  适合数据库支持序列:  
		          Mysql: 不支持序列: 
		          ORACLE: 可以使用Sequence: 
		          
		          
		     uuid: 主键字段是varchar 或者是varchar2类型:   Hibernate能够自动生成uuid 值 做主键。 
		    
		    native:      本地策略: 能够根据配置的方言自动选择主键的类型:
		          Mysql: identity: 
		          Oracle: Sequence: 
		     Assigned    : Hibernate放弃维护主键: 此时必须由程序员自己管理:  
		                  
		    -->
			<generator class="native"/>
		</id>
		<!-- 普通的字段: 
		property:表示这是普通的字段: 
		name: 实体bean的属性。 
		column: 表的字段;
		 -->
		<property name="cust_name" column="cust_name" length="21" type="string" not-null="true" unique="false"/>
		<property name="cust_source" column="cust_source"/>
		<property name="cust_industry" column="cust_industry"/>
		<property name="cust_level" column="cust_level"/>
		<property name="cust_phone" column="cust_phone"/>
		<property name="cust_mobile" column="cust_mobile"/>
		
	</class>
	
</hibernate-mapping>        

public class TestDemo {
/*测试increment : 多条线程会发生问题:
* 当第一条线程: 发生一个sql 语句: select max(id) from tableName;查询到一个值。
* 再次启动一天线程: 发送一个sql 语句。 select max(id) from tableName; 和上次查询到相同的值。
* 当一条sql 语句执行操作的时候, 添加成功。
* 当另外一条sql 执行添加操作的时候, 添加失败。
*
* 测试: identity :
* 创建的Mysql 数据库当中的表: 主键具备自增的功能:
*
* Sequence: 应用于oracle数据库。
* native: 在Sequence和native之间进行切换。 根据不同的数据库进行选择:
*
* uuid: 适用于主键字段是String类, 需要修改表主键的类型, 然后的主键字段是uuid的值。
* assigned: 放弃维护主键字段, 把主键字段交给了用户自己设定。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东方-教育技术博主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值