现在的位置: 首页 > 综合 > 正文

映射对象标识符(OID,对应数据库主键)

2014年06月28日 ⁄ 综合 ⁄ 共 4696字 ⁄ 字号 评论关闭

一、OID,唯一性的标志:

Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系。对象的OID和数据库的表的主键对应。为保证OID的唯一性,应该让Hibernate来为OID赋值。

主键必备条件:

1,不能为null

2,唯一,不能重复。

3,永远不会改变。

二、
自然主键和代理主键

1、自然主键:

表示:采用具有业务逻辑含义的字段作为表的主键。比如在用户信息表中,采用用户的身份证号码作为主键。但是这样一来,随着业务逻辑的变化,主键就有可能要更改。比如,假设哪天身份证号码升级成19,2位,那。。。。。。。

比较常用:assigned 
表示在新增数据时由应用程序指定主键的值。主要针对主键是采用自然主键的形式。这种方式,适用于主键列不是自动增长列。 
其缺点为在执行新增操作时,需查询数据库判断生成的主键是否已经存在。

java程序负责生成标识符。不能把setID()方法声明为private的。尽量避免使用自然主键。

例:

封装JavaBean:Student.java

package www.csdn.net.blank.bean;

import java.io.Serializable;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

public class Student implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String numberNo;
	private String name;
	private Integer age;

	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Student(String numberNo, String name, Integer age) {
		super();
		this.numberNo = numberNo;
		this.name = name;
		this.age = age;
	}

	public String getNumberNo() {
		return numberNo;
	}

	public void setNumberNo(String numberNo) {
		this.numberNo = numberNo;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [numberNo=" + numberNo + ", name=" + name + ", age="
				+ age + "]";
	}

}

Student.hbm.xml


<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="www.csdn.net.blank.bean">

	<class name="Student" table="student">
		<!-- 单一的自然主键 -->
		<id name="numberNo" column="numberNo" type="string">
			<generator class="assigned" />
		</id>
		<property name="name" column="name" length="40" />
		<property name="age" column="age" type="integer"></property>
	</class>

</hibernate-mapping>

hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
	<!-- 数据库的驱动 -->
	<property name="connection.driver_class">
		com.mysql.jdbc.Driver
	</property>
	<!-- 数据库的URL -->
	<property name="connection.url">
		jdbc:mysql://localhost:3306/jds?useUincode=true&characterEncoding=UTF-8
	</property>
	<!-- 数据库的用户名 -->
	<property name="connection.username">root</property>
	<!-- 数据库的密码 -->
	<property name="connection.password">root</property>
	<!-- 数据库的方言 -->
	<property name="hibernate.dialect">
		org.hibernate.dialect.MySQLDialect
	</property>

	<!-- Enable Hibernate's automatic session context management -->
	<property name="current_session_context_class">thread</property>

	<!-- 显示操作的sql语句 -->
	<property name="hibernate.show_sql">true</property>
	<!-- 格式sql语句 -->
	<property name="hibernate.format_sql">false</property>
	<!-- 自动创建和更新表结构 -->
	<property name="hibernate.hbm2ddl.auto">update</property>



	<!-- 映射文件引入 -->
	<mapping resource="www/csdn/net/blank/bean/Student.hbm.xml" />
</session-factory>

</hibernate-configuration>



2、代理主键:

在表中人为的增加一个字段,该字段并没有表示任何的业务逻辑,仅仅用来标识一行数据。比如说在用户信息表中,增加一个用户ID的字段。用来表示该条用户信息的记录。

比较常用:

increment :
表示新增数据操作时由hibernate自动生成主键值。其生成的值为:先查询该主键列的最大值,然后在最大值的基础上加上1.适用于采用代理主键形式的主键列。同样不能用于主键列是自动增长的表。但是,该主键生成策略也有些缺点。
(1)新增数据前先查询一遍,影响了性能。 

(2)主键的类型只能为数值型的int或者long

(3)并发操作时的冲突问题


identity:

 标识符生成器由底层数据库来负责生成标识符它要求底层数据库把主键定义为自动增长字段类型。

适用范围:

1, 由于 identity 生成标识符的机制依赖于底层数据库系统,因此,要求底层数据库系统必须支持自动增长字段类型。支持自动增长字段类型的数据库包括:DB2、 MysqlMSSQLServerSybase等。

2, OID 必须为 long, int 或 short 类型如果把 OID 定义为 byte 类型在运行时会抛出异常。

强调:如果为byte  会执行sql 

但是 数据库中没有东西.

sequence :

标识符生成器利用底层数据库提供的序列来生成标识符

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

l 适用范围:

1, 由于 sequence 生成标识符的机制依赖于底层数据库系统的序列,因此,要求底层数据库系统必须支持序列。支持序列的数据库包括:DB2 Oracle 等。

2, OID 必须为 long, int 或 short 类型如果把 OID 定义为 byte 类型在运行时会抛出异常。

 hilo:

标识符生成器由 Hibernate 按照一种 high/low 算法*生成标识符它从数据库的特定表的字段中获取 high .

 Hibernate 在持久化一个 News 对象时由 Hibernate 负责生成主键值. hilo 标识符生成器在生成标识符时需要读取并修改 HI_TABLE 表中的 NEXT_VALUE .

 适用范围:

1, 由于 hilo 生存标识符机制不依赖于底层数据库系统因此它适合所有的数据库系统

2, OID 必须为 long, int 或 short 类型如果把 OID 定义为 byte 类型, 在运行时会抛出异常

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="www.csdn.net.blank.bean">

    <class name="Admin" table="admins">
       <id name="id" column="admins_id">
           <!-- 主键的生成策略 -->
           <generator class="hilo"/> 
       </id>  
       <property name="name" column="admins_name" length="40" unique="true"/>
       <property name="pass" column="admins_pass" length="12"/>
       <property name="role" column="admins_role" length="20"/>
    </class>
</hibernate-mapping>

生成两种表

 native :

标识符生成器依据底层数据库对自动生成标识符的支持能力来选择使用 identity, sequence 或 hilo 标识符生成器

适用范围:

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

2, OID 必须为 long, int 或 short 类型如果把 OID 定义为 byte 类型在运行时会抛出异常

 

【上篇】
【下篇】

抱歉!评论已关闭.