一、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、 Mysql、MSSQLServer、Sybase等。
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 类型, 在运行时会抛出异常