[读书笔记]第5章 映射对象标识符

[读书笔记]第5章 映射对象标识符

5.1 关系数据库按主键区分不同的记录

主键的特点:
   1、不允许为null;
   2、每条记录具有唯一的主键值,不允许主键值重复;
   3、每条记录的主键值永远不会改变。

设置主键的方式:

5.1.1 把主键定义为自动增长标识符类型

   在MySQL中,如果把表的主键设为 auto_increment 类型,数据库就会自动为主键赋值。
   例如:
   
CREATE   TABLE  CUSTOMERS(
ID 
int  auto_increment  primary   key   not   null ,
NAME 
varchar ( 15 ));

INSERT   INTO  CUSTOMERS(NAME)  VALUES ("name1");
INSERT   INTO  CUSTOMERS(NAME)  VALUES ("name2");

SELECT  ID  FROM  CUSTOMERS;

查询结果:
ID
1
2

在MS SQL Server中,如果把表的主键设为 identity 类型,数据库就会自动为主键赋值:

CREATE   TABLE  CUSTOMERS(
ID 
int  identity(1,1)  primary   key   not   null ,
NAME 
varchar ( 15 ));

INSERT   INTO  CUSTOMERS(NAME)  VALUES ("name1");
INSERT   INTO  CUSTOMERS(NAME)  VALUES ("name2");

SELECT  ID  FROM  CUSTOMERS;

查询结果:

ID
1
2

5.1.2 从序列(Sequence)中获取自动增长的 标识符


在Oracle中,可以为每张表的主键创建一个单独的序列,然后从这个序列中获得自动增加的标识符,把它赋值给主键。

例如以下语句创建了一个名为 CUSTOMERS_ID_SEQ的序列,这个序列的起始值为1,增量为2:

CREATE  SEQUENCE CUSTOMERS_ID_SEQ INCREMENT  BY   2  START  WITH   1 ;

一旦定义了 CUSTOMERS_ID_SEQ 序列,就可以访问序列的 curval 和 nextval 属性。

curval:返回序列的当前值。
nextval:先增加序列的值,然后返回序列值。

以下SQL语句先创建了CUSTOMERS表,然后插入两条记录,在插入时设定了ID和NAME字段的值,其中ID字段的值来自于CUSTOMERS_ID_SEQ序列。最后查询CUSTOMERS表中的ID字段。

CREATE   TABLE  CUSTOMERS(
ID 
int   primary   key   not   null ,
NAME 
varchar ( 15 ));

INSERT   INTO  CUSTOMERS VALUES (CUSTOMERS_ID_SEQ.curval, 'Tom');
INSERT   INTO  CUSTOMERS VALUES (CUSTOMERS_ID_SEQ.nextval, 'Mike');

SELECT  ID  FROM  CUSTOMERS;

如果在Oracle中执行以上SQL语句,查询结果:

ID
1
3

5.2 Java语言按内存地址区分不同的对象

在Java语言中,判断两个对象引用变量是否相等,有以下两种比较方式:
(1)比较两个变量所引用的对象的内存地址是否相同,“==”运算符就是比较的内存地址。此外,在Object类中定义的equals(Object o)方法,也是按内存地址来比较的。如果用户自定义的类没有覆盖Object类的equals(Object o)方法,也按内存地址比较。

例如,以下代码用new语句共创建了两个Customer对象,并定义了三个Customer类型的引用变量c1、c2和c3:

Customer c1  =   new  Customer( " Tom " ); // line1
Customer c2  =   new  Customer( " Tom " ); // line2
Customer c3  =  c1; // line3
c3.setName( " Mike " ); // line4


   图5-1和图5-2显示了程序执行到第3行及第4行的对象图。
[读书笔记]第5章 映射对象标识符_第1张图片

   从图5-1和图5-2看出,c1和c3变量引用同一个Customer对象而c2变量引用了而c2变量引用另一个Customer对象。因此,表达式"c1==c3"以及c1.equals(c3)的值都是true,而表达式"c1==c2"以及c1.equals(c2)的值是false。

(2)比较两个变量所引用的对象的值是否相同,Java API中的一些类覆盖了Object类的equals(Object o)方法,实现按对象值比较。
String类和Date类
Java包装类,包括:Byte、Integer、Short、Character、Long、Float、Doubl和Boolean。
例如:

String s1  =   new  String( " hello " );
String s2 
=   new  String( " hello " );


尽管s1和s2引用不同的String对象,但是它们的字符串值都是“hello”,因此表达式“s1==s2的值是false,而表达式s1.equals(s2)的值是true。

用户自定义的类也可以覆盖Object类的equals(Object o)方法,从而实现按对象值比较。例如,在Customer类中添加如下equals(Object o)方法,使它按客户的姓名来比较两个Customer对象是否相等:

public   boolean  equals(Object o) {
 
if ( this == o){
  
return   true ;
 }

 
if ( ! instanceof  Customer) {
  
return   false ;
 }

 
final  Customer other  =  (Customer)o;

 
if ( this .getName().equals(other.getName())){
  
return   true ;
 }
else {
  
return   false ;
 }
}


以下代码用new语句共创建了两个Customer对象,并定义了两个Customer类型的引用变量c1和c2:

Customer c1  =   new  Customer( " Tom " );
Customer c2 
=   new  Customer( " Tom " );


尽管c1和c2引用不同的Customer对象,但是它们的name值都是“Tom”,因此表达式“c1==c2的值是false,而表达式c1.equals(c2)的值是true。
   

你可能感兴趣的:([读书笔记]第5章 映射对象标识符)