一、OID,唯一性的标志:
Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系。对象的OID和数据库的表的主键对应。为保证OID的唯一性,应该让Hibernate来为OID赋值。
主键必备条件:
1,不能为null。
2,唯一,不能重复。
3,永远不会改变。
二、 自然主键和代理主键
1、自然主键:
表示:采用具有业务逻辑含义的字段作为表的主键。比如在用户信息表中,采用用户的身份证号码作为主键。但是这样一来,随着业务逻辑的变化,主键就有可能要更改。比如,假设哪天身份证号码升级成19,2位,那。。。。。。。
比较常用:assigned
表示在新增数据时由应用程序指定主键的值。主要针对主键是采用自然主键的形式。这种方式,适用于主键列不是自动增长列。
其缺点为在执行新增操作时,需查询数据库判断生成的主键是否已经存在。
由java程序负责生成标识符。不能把setID()方法声明为private的。尽量避免使用自然主键。
例:
封装JavaBean:Student.java
package www.youkuaiyun.com.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.youkuaiyun.com.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/youkuaiyun.com/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.youkuaiyun.com.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 类型, 在运行时会抛出异常