最近刚学的hibernate,用来写东西,出现挺多问题的,下面说的都是比较简单实用的。
这篇对hibernate的注解的一些参数的介绍的不是很不全(通常只是介绍例子中给出的注解解析),要更完整的了解其中一个注解可以再继续查询这个注解。
这篇更多的是我自己学hibernate的总结,然后把注解列举一下,方便查找。
@MappedSuperclass
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class DefaultFile
{
// Fields
@Id
@Column(name = "id", insertable = false, updatable = false)
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@Column(name = "name")
private String name;
@Column(name = "path")
private String path;
@Column(name = "note")
private String note;
@Column(name = "uploadDate", insertable = false, updatable = false)
private Timestamp uploadDate;
/**
* 文件内容,不被映射成column
*/
@Transient
File file;
...
}
@Entity
@Table(name = "imageFile")
public class ImageFile extends DefaultFile
{
@OneToMany(cascade = CascadeType.ALL,mappedBy="imagefile",fetch = FetchType.LAZY)
private Set accounts = new HashSet();
...
}
@Entity
@Table(name="account")
public class Account {
// Fields
@Id
@Column(insertable=false,updatable=false)
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@ManyToOne(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
@JoinColumn(name="imageID")
//头像
private ImageFile imagefile;
@Column
private String name;
@Column
private String password;
@Column(insertable=false,updatable=false)
private Timestamp createdDate;
...
}
标记为实体类,标记后都会被映射到数据表中
一般实体类都要加上这个注释
表明该类作为父类被其他实体类继承后,其它实体类可以继承该类的属性,并且结合各子类各自映射对应的表,然后改父类不映射到数据库表
这个和上面的@Entity可以说二者只能选其一,如果选择@MappedSuperclass则不映射表,如果用@Entity则会映射到表
例子中DefaultFile被注解为@MappedSuperclass,因此DefaultFile不会被映射到表,而ImageFile继承DefaultFile,因此ImageFile会继承DefaultFile的属性,加上自己的属性,映射到新表
定义继承的策略
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
上面的InheritanceType.TABLE_PER_CLASS是指每个子类都成为一个新表,还有以下的继承策略(看名字就大概知道意思了):
用来标记该实体类映射到数据库中的表的表名
可添加参数来说明表名@Table(name=”table_name”)
说明该属性为主键
表明该列为自动增长的属性
@GeneratedValue(strategy=GenerationType.IDENTITY)
其中strategy指自动增长的策略,而这个GenerationType.IDENTITY是指数据库自动增长,相当于mysql中auto_increment,还有其它属性:
指明该列的属性
@Column(name = “uploadDate”, insertable = false, updatable = false)
指明列名
插入操作时忽略该属性
更新 操作时忽略该属性
表名一对多的关系,通常用于Set
变量
@OneToMany(cascade = CascadeType.ALL = CascadeType.ALL,mappedBy=”imagefile”,fetch = FetchType.LAZY)
所有操作都进行关联,具体看下面例子:
@Entity
public class A{
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "bID")
private B b;
...
}
@Entity
public class B{
...
}
B b = new B();
A a = new A();
a.setB(b);
//这时数据库中的b表是没有b对象的信息的,但是在执行完下面a对象的保存后,也会把对象b也保存到b表中。
aDao.save(a);
例子:
@Entity
public class A{
@ManyToOne(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
@JoinColumn(name = "bID")
private B b;
...
}
@Entity
public class B{
...
}
B b = new B();
A a = new A();
a.setB(b);
//这时数据库中的b表是没有b对象的信息的,这时执行下面的保存a对象的时候就会报错,只有b对象信息在数据库b表中有对应的,下面语句才可以正常执行
aDao.save(a);
如果这个一对多的关系不是通过第三张表来维持,而是多方保存一方的id(多方外键引用一方),则必须要有mappedBy来指明多方中哪个变量来保存一方(外键),值是多方里面保存一方的属性名字,具体可看例子中的使用
加载的策略,有积极和懒惰,积极是指用查询语句获取对象时,马上加载标记为@OneToMany的变量,懒惰则是等到使用时才获取。
表名一对多的关系,通常用在对应的一方类的一个变量
@ManyToOne(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
属性和@OneToMany的基本差不多。但是如果这个多对一的关系不是通过第三张表来维持,而是保存在多方的表中(外键),必须还添加一个注解@joinColumn
作用于@ManyToOne标注后的变量,指明该变量映射到数据库中表的列名
@JoinColumn(name=”imageID”)
值是数据库中外键的表名
指明被标注的变量不需要被映射到数据库表中