一、Table注解
源代码: @Target({TYPE}) @Retention(RUNTIME)
public @interface Table {
String name() default ""; ---> 实体所对应表的名称,默认表名为实体的名称。
String catalog() default ""; ---> 实体指定的目录名,这根据不同的数据库类型有所不同。
String schema() default ""; ---> 实体指定的数据库名,
UniqueConstraint[] uniqueConstraints() default {}; ---> 该实体所关联的唯一约束条件,
}
1、此标记需要标注在类名前,不能标注在方法或属性前。
2、用注释时,属性值是不区分大小写的,这是因为许多不同的数据库都不区分大小写,
3、uniqueConstraints的使用
一个实体可以有多个唯一约束条件
若使用uniqueConstraints标记时,需要配合标记UniqueConstraint标记来使用。
@Table(name = "contact", uniqueConstraints = {
@UniqueConstraint(
columnNames = { "name", "email" }
)}
public class ContactEO {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
)
SQL:CREATE TABLE contact (
id int(20) NOT NULL,
name varchar(255) default NULL,
email varchar(255) default NULL,
UNIQUE KEY name_email (name,email)
)
规则是字段name和字段email的值不能同时相同。
二、Column注解
源代码: @Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface Column {
String name() default "";
boolean unique() default false; ---> 表示该字段是否为唯一标识
boolean nullable() default true; ---> 表示该字段是否可以为null值
boolean insertable() default true; ---> 表示在使用“INSERT”脚本插入数据时,是否需要插入该字段的值
boolean updatable() default true; ---> 表示在使用“UPDATE”脚本插入数据时,是否需要更新该字段的值
String columnDefinition() default ""; ---> 表示创建表时,该字段创建的SQL语句,(自定义该字段的生成语句)
String table() default ""; ---> 表示当映射多个表时,指定表的表中的字段。默认值为主表的表名
int length() default 255; ---> 表示字段的长度,当字段的类型为varchar时,该属性才有效,默认为255个字符
int precision() default 0; ---> 当字段类型为double时,precision表示数值的总长度
int scale() default 0; ---> 当字段类型为double时,scale表示小数点所占的位数
}
1、此标记可以标注在getter方法或属性前,例如以下的两种标注方法都是正确的:
标注在属性前:
@Column(name=" contact_name ")
private String name;
标注在getter方法前:
@Column(name=" contact_name ")
public String getName() {
return name;
}
2、insertable与updatable
insertable和updatable属性一般多用于只读的属性,
例如主键和外键等。这些字段的值通常是自动生成的。
3、columnDefinition
一般用于通过Entity生成表定义时使用。
@Column(name=" contact_name ",columnDefinition="number(10,2) not null")
public String getName() {
return name;
}
SQL:CREATE TABLE contact (
id integer not null,
contact_name number(10,2) not null,
primary key (id)
)
4、默认值的设置
@Column(columnDefinition="number(10,2) default 200.00") number 对应数据库类型
@Column(columnDefinition ="varchar2(2) default '11'") varchar2对应数据库类型
三、可持久化的基本数据类型
1、 分类 类型
Java的基本数据类型 byte, int, short, long, boolean, char, float, double
Java基本数据类型对应的封装类 Byte, Integer, Short, Long, Boolean, Character, Float, Double
字节和字符型数组 byte[], Byte[], char[], Character[]
大数值型类 java.math.BigInteger, java.math.BigDecimal
字符串类型 String
时间日期型 java.util.Date, java.util.Calendar,java.sql.Date,java.sql.Time,java.sql.Timestamp
枚举类型 用户定义的枚举类型
Entity类型 标注为@Entity的类
包含Entity类型的集合Collction类 java.util.Collction,java.util.Set,java.util.List,java.util.map
嵌入式(embeddable)类
2、转化原理
Java数据类型与数据库中的类型转换是JPA实现框架自动转换的,所以不同的JPA实现框架转换的规则也不太一样。
例如MySQL中,varchar和char类型都转化为String类型。Blob和Clob类型可以转化成Byte[]型。
由于类型的转化是JPA底层来实现的,很有可能在将表中的数据转换成Java的数据类型时出现异常
比如int等基本数据类型 转化时候 是不能设置为null和空的 所以当数据库该列无数据时就会 转化失败
建议标注实体的属性使用Java基本类型的包装类,虽然会牺牲转化效率,但可以避免持久化数据时产生某些异常
四、其他注解
1、@Id ---> 标识主键
2、@GeneratedValue ---> 标识主键的生成方式
不指定属性时为自增(数据库自增和Hibernate自增)
属性:strategy ---> 生成方式
属性值为:GenerationType枚举的值
常用值:GenerationType.indentity
注:主键不设置@GeneratedValue时,生成方式为程序手动指定
设置@GeneratedValue时,最好不要使用默认自增,因为Hibernate自增不是线程安全的
ps:@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
3、@Transient ---> 标识为非持久属性 ---> 即非数据库列
4、@OneToMany ---> 标识一对多映射
属性:a、mappedBy ---> 对应多的一方的对象属性
b、cascade ---> 级联
属性值为:CascadeType枚举
CascadeType.MERGE ---> 只级联marge方法
c、targetEntity ---> 指定映射的类
ps: @OneToMany(mappedBy = "parent", cascade = CascadeType.MERGE,targetEntity=Dept.class)
5、@ManyToOne ---> 标识多对一的映射
属性:a、cascade ---> 级联
属性值为:CascadeType枚举
b、targetEntity ---> 指定映射的类
6、@JoinColumn ---> 标识映射的列
属性:a、name ---> 映射的数据库外键列名
b、referencedColumnName ---> 引用的列名
ps:
@OneToMany(cascade = CascadeType.MERGE,targetEntity=Dept.class)
@JoinColumn(name="自身表的外键列名",referencedColumnName="引用表的主键列名")
7、@ManyToMany ---> 标识多对多映射
属性:a、mappedBy ---> 映射的列 ---> 主体中对应的从体的对象属性
b、cascade ---> 级联
属性值为:CascadeType枚举
CascadeType.MERGE ---> 只级联marge方法
c、targetEntity ---> 指定映射的类
8、@JoinTable ---> 标识连接的数据库表
属性:a、name ---> 连接的数据库关系表名
b、joinColumns ---> 映射列名 ---> 即关系表对应的主表的外键
c、inverseJoinColumns ---> 从表的映射列名 ---> 即关系表中从表的外键
ps: @ManyToMany
@JoinTable(name="user_role",
joinColumns=@JoinColumn(name="userid"),
inverseJoinColumns=@JoinColumn(name="roleid")
)
public List<Role> getRoles() {...}
源代码: @Target({TYPE}) @Retention(RUNTIME)
public @interface Table {
String name() default ""; ---> 实体所对应表的名称,默认表名为实体的名称。
String catalog() default ""; ---> 实体指定的目录名,这根据不同的数据库类型有所不同。
String schema() default ""; ---> 实体指定的数据库名,
UniqueConstraint[] uniqueConstraints() default {}; ---> 该实体所关联的唯一约束条件,
}
1、此标记需要标注在类名前,不能标注在方法或属性前。
2、用注释时,属性值是不区分大小写的,这是因为许多不同的数据库都不区分大小写,
3、uniqueConstraints的使用
一个实体可以有多个唯一约束条件
若使用uniqueConstraints标记时,需要配合标记UniqueConstraint标记来使用。
@Table(name = "contact", uniqueConstraints = {
@UniqueConstraint(
columnNames = { "name", "email" }
)}
public class ContactEO {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
)
SQL:CREATE TABLE contact (
id int(20) NOT NULL,
name varchar(255) default NULL,
email varchar(255) default NULL,
UNIQUE KEY name_email (name,email)
)
规则是字段name和字段email的值不能同时相同。
二、Column注解
源代码: @Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface Column {
String name() default "";
boolean unique() default false; ---> 表示该字段是否为唯一标识
boolean nullable() default true; ---> 表示该字段是否可以为null值
boolean insertable() default true; ---> 表示在使用“INSERT”脚本插入数据时,是否需要插入该字段的值
boolean updatable() default true; ---> 表示在使用“UPDATE”脚本插入数据时,是否需要更新该字段的值
String columnDefinition() default ""; ---> 表示创建表时,该字段创建的SQL语句,(自定义该字段的生成语句)
String table() default ""; ---> 表示当映射多个表时,指定表的表中的字段。默认值为主表的表名
int length() default 255; ---> 表示字段的长度,当字段的类型为varchar时,该属性才有效,默认为255个字符
int precision() default 0; ---> 当字段类型为double时,precision表示数值的总长度
int scale() default 0; ---> 当字段类型为double时,scale表示小数点所占的位数
}
1、此标记可以标注在getter方法或属性前,例如以下的两种标注方法都是正确的:
标注在属性前:
@Column(name=" contact_name ")
private String name;
标注在getter方法前:
@Column(name=" contact_name ")
public String getName() {
return name;
}
2、insertable与updatable
insertable和updatable属性一般多用于只读的属性,
例如主键和外键等。这些字段的值通常是自动生成的。
3、columnDefinition
一般用于通过Entity生成表定义时使用。
@Column(name=" contact_name ",columnDefinition="number(10,2) not null")
public String getName() {
return name;
}
SQL:CREATE TABLE contact (
id integer not null,
contact_name number(10,2) not null,
primary key (id)
)
4、默认值的设置
@Column(columnDefinition="number(10,2) default 200.00") number 对应数据库类型
@Column(columnDefinition ="varchar2(2) default '11'") varchar2对应数据库类型
三、可持久化的基本数据类型
1、 分类 类型
Java的基本数据类型 byte, int, short, long, boolean, char, float, double
Java基本数据类型对应的封装类 Byte, Integer, Short, Long, Boolean, Character, Float, Double
字节和字符型数组 byte[], Byte[], char[], Character[]
大数值型类 java.math.BigInteger, java.math.BigDecimal
字符串类型 String
时间日期型 java.util.Date, java.util.Calendar,java.sql.Date,java.sql.Time,java.sql.Timestamp
枚举类型 用户定义的枚举类型
Entity类型 标注为@Entity的类
包含Entity类型的集合Collction类 java.util.Collction,java.util.Set,java.util.List,java.util.map
嵌入式(embeddable)类
2、转化原理
Java数据类型与数据库中的类型转换是JPA实现框架自动转换的,所以不同的JPA实现框架转换的规则也不太一样。
例如MySQL中,varchar和char类型都转化为String类型。Blob和Clob类型可以转化成Byte[]型。
由于类型的转化是JPA底层来实现的,很有可能在将表中的数据转换成Java的数据类型时出现异常
比如int等基本数据类型 转化时候 是不能设置为null和空的 所以当数据库该列无数据时就会 转化失败
建议标注实体的属性使用Java基本类型的包装类,虽然会牺牲转化效率,但可以避免持久化数据时产生某些异常
四、其他注解
1、@Id ---> 标识主键
2、@GeneratedValue ---> 标识主键的生成方式
不指定属性时为自增(数据库自增和Hibernate自增)
属性:strategy ---> 生成方式
属性值为:GenerationType枚举的值
常用值:GenerationType.indentity
注:主键不设置@GeneratedValue时,生成方式为程序手动指定
设置@GeneratedValue时,最好不要使用默认自增,因为Hibernate自增不是线程安全的
ps:@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
3、@Transient ---> 标识为非持久属性 ---> 即非数据库列
4、@OneToMany ---> 标识一对多映射
属性:a、mappedBy ---> 对应多的一方的对象属性
b、cascade ---> 级联
属性值为:CascadeType枚举
CascadeType.MERGE ---> 只级联marge方法
c、targetEntity ---> 指定映射的类
ps: @OneToMany(mappedBy = "parent", cascade = CascadeType.MERGE,targetEntity=Dept.class)
5、@ManyToOne ---> 标识多对一的映射
属性:a、cascade ---> 级联
属性值为:CascadeType枚举
b、targetEntity ---> 指定映射的类
6、@JoinColumn ---> 标识映射的列
属性:a、name ---> 映射的数据库外键列名
b、referencedColumnName ---> 引用的列名
ps:
@OneToMany(cascade = CascadeType.MERGE,targetEntity=Dept.class)
@JoinColumn(name="自身表的外键列名",referencedColumnName="引用表的主键列名")
7、@ManyToMany ---> 标识多对多映射
属性:a、mappedBy ---> 映射的列 ---> 主体中对应的从体的对象属性
b、cascade ---> 级联
属性值为:CascadeType枚举
CascadeType.MERGE ---> 只级联marge方法
c、targetEntity ---> 指定映射的类
8、@JoinTable ---> 标识连接的数据库表
属性:a、name ---> 连接的数据库关系表名
b、joinColumns ---> 映射列名 ---> 即关系表对应的主表的外键
c、inverseJoinColumns ---> 从表的映射列名 ---> 即关系表中从表的外键
ps: @ManyToMany
@JoinTable(name="user_role",
joinColumns=@JoinColumn(name="userid"),
inverseJoinColumns=@JoinColumn(name="roleid")
)
public List<Role> getRoles() {...}