Hibernate 注解使用

Hibernate 注解使用

在Hibernate中一般配置对象关系映射关系有两种,一种是基于xml的方式,另外一种是基于Hibernate Annotation库的注解方式。在Hibernate 3.2版本和Java 5 环境下开始支持使用注解配置对象关系映射,使用Hibernate注解以后,可不用定义持久化类所对应的*.hbm.xml文件,直接用注解的方式写入持久化类中实现html

两种方法要注意的两个不一样处:
(1):hibernate.hbm.xml 文件中把引用:xxx.hbm.xml改成引用实体类:java

即把<mapping resource="com/wsw/hibernate/model/Person.hbm.xml"/>
改成:<mapping class="com.wsw.hibernate.model.Teacher" />数据库

(2):获取SessionFactory方式发生了变化:数组

即把SessionFactorysf=newConfiguration().configure().buildSessionFactory()
改成SessionFactory sf=new AnnotationConfiguration().configure().buildSessionFactory()app

经常使用的注解标签

在属性注解使用上,您既能够保持字段的持久性(注解写在成员变量之上),也能够保持属性(注解写在getter方法之上)的持久性,但建议不要在属性上引入注解,由于属性是private的,若是引入注解会破坏其封装特性,因此建议在getter方法上加入注解框架

@Entityfetch

将一个Javabean类声明为一个实体的数据库表映射类,最好实现序列化。默认状况下,全部的类属性都为映射到数据表的持久性字段。若在类中有属性不映射到数据库中的,要用下面的@Transient来注解。ui

*属性:*
`name` - 可选,对应数据库中的一个表。若表名与实体类名相同,则能够省略。

@Table
在@Entity下使用,表示实体对应数据库中的表的信息this

属性:
name - 可选,表示表的名称,默认表名和实体名称一致,不一致的状况下需指定表名。
catalog - 可选,表示Catalog名称,默认为 Catalog("")
schema - 可选 , 表示 Schema 名称 , 默认为Schema("").net

@Entity()
@Table(name="Student")
public class Student implements Serializable{
}

@Id

必须,定义了映射到数据库表的主键的属性,一个实体只能有一个属性被映射为主键

@GeneratedValue

定义自动增加的主键的生成策略.
属性:
strategy - 表示主键生成策略,取值有如下

GenerationType.AUTO 根据底层数据库自动选择(默认),若数据库支持自动增加>类型,则为自动增加。
GenerationType.INDENTITY 根据数据库的Identity字段生成,支持DB二、MySQL、MS、SQL Server、SyBase与HyperanoicSQL数据库的Identity
GenerationType.SEQUENCE 使用Sequence来决定主键的取值,适合Oracle、DB2等支持Sequence的数据库,通常结合@SequenceGenerator使用。(Oracle没有自动增加类型,只能用Sequence)
GenerationType.TABLE 使用指定表来决定主键取值,结合@TableGenerator使用。
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY) 
private int sid;

GenerationType.TABLE的使用

@Id  
@GeneratedValue(strategy=GenerationType.TABLE,generator="strategyName")   
@TableGenerator(
    name = "strategyName",   // 主键生成策略的名称,它被引用在@GeneratedValue中设置的“generator”值中
    table="",   //表示表生成策略所持久化的表名   
    catalog="",   //表所在的目录名
    schema="",   //数据库名
    pkColumnName="",   //在持久化表中,该主键生成策略所对应键值的名称
    valueColumnName="",   //表示在持久化表中,该主键当前所生成的值,它的值将会随着每次建立累加  
    pkColumnValue="",   //表示在持久化表中,该生成策略所对应的主键  
    allocationSize=1   //表示每次主键值增长的大小,例如设置成1,则表示每次建立新记录后自动加1,默认为50
)

GenerationType.SEQUENCE的使用

@Id  
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator="strategyName")   
@SequenceGenerator(
    name="strategyName", //name属性表示该表主键生成策略的名称,它被引用在@GeneratedValue中设置的“generator”值中
    sequenceName=""  //表示生成策略用到的数据库序列名称
)

更多基于注解的Hibernate主键生成策略介绍

@Transient

将忽略这些字段和属性,不用持久化到数据库。

@Column

可将属性映射到列,使用该注解来覆盖默认值
属性:
name- 可选,表示数据库表中该字段的名称,默认情形属性名称一致

length - 可选,表示该字段的大小,仅对 String 类型的字段有效,默认值255.
insertable - 可选,表示在ORM框架执行插入操做时,该字段是否应出现INSETRT 语句中,默认为 true
updateable - 可选,表示在ORM 框架执行更新操做时,该字段是否应该出如今 UPDATE 语句中,默认为 true. 对于一经建立就不能够更改的字段,该属性很是有用,如对于 birthday 字段。
columnDefinition - 可选,表示该字段在数据库中的实际类型。一般ORM 框架能够根 据属性类型自动判断数据库中字段的类型,可是对于Date 类型仍没法肯定数据库中字段类型到底是 DATE,TIME 仍是 TIMESTAMP. 此外 ,String 的默认映射类型为 VARCHAR, 若是要将 String 类型映射到特定数据库的 BLOB或 TEXT 字段类型,该属性很是有用。

@Version

声明添加对乐观锁定的支持

一些属性

fetch

关联关系获取方式,便是否采用延时加载
Fetch.EAGER - 及时加载,是在查询数据时,也直接一块儿获取关联对象的数据。多对一默认是Fetch.EAGER
Fetch.LAZY -延迟加载,查询数据时,不一块儿查询关联对象的数据。而是当访问关联对象时才触发相应的查询操做,获取关联对象数据。一对多默认是Fetch.LAZY

cascade

设置级联方式
CascadeType.PERSIST 保存
CascadeType.REMOVE - 删除
CascadeType.MERGE 修改
CascadeType.REFRESH 刷新
CascadeType.ALL - 所有

mappedBy

mappedBy指的是多方对一方的依赖的属性,(注意:若是没有指定由谁来维护关联关系,则系统会给咱们建立一张中间表)。
若是这个一对多的关系不是经过第三张表来维持,而是多方保存一方的id(多方外键引用一方),则必需要有mappedBy来指明多方中哪一个变量来保存一方(外键),值是多方里面保存一方的属性名字
在判断究竟是谁维护关联关系时,能够经过查看外键,哪一个实体类定义了外键,哪一个类就负责维护关联关系
mappedBy至关于xml配置中的inverse="true"

一对多关联

@OneToMany

描述一个一对多的关联,该属性应该为集合类型 @OneToMany 默认会使用链接表作一对多关联
若是这个一对多的关系不是经过第三张表来维持,而是多方保存一方的id(多方外键引用一方),则必需要有mappedBy来指明多方中哪一个变量来保存一方(外键),值是多方里面保存一方的属性名字

@OneToMany(cascade={CascadeType.ALL},mappedBy="grade")
    public Set<Student> getStudents() {
        return students;
    }

多对一关联

@ManyToOne

表示一个多对一的映射,该注解标注的属性一般是数据库表的外键。 单向多对一关联在多方:
@ManyToOne(targetEntity=XXXX.class) //指定关联对象
@JoinColumn(name="") //指定产生的外键字段名

双向一对多同双向多对一

在多方
@ManyToOne
@JoinColumn(name="本身的数据库外键列名")
在一方
@OneToMany(mappedBy="多端的关联属性名")

/*
 * 学生类负责关联关系
 */
@Entity
@Table(name="Student")
public class Student implements Serializable{
    private int sid;
    private String sex;
    private String name;
    private Grade grade;
    public Student() {
        
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Id
    @GenericGenerator(name="generator",strategy="native")
    @GeneratedValue(generator="generator")
    public int getId() {
        return sid;
    }
    public void setId(int id) {
        this.sid = id;
    }
    @Column(name="sex")
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    @ManyToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="gid")
    public Grade getGrade() {
        return grade;
    }
    public void setGrade(Grade grade) {
        this.grade = grade;
    }
}
/*
 * 班级类
 */
@Entity
@Table(name="Grade")
public class Grade implements Serializable{
    private int gid;
    private String name;
    private Set<Student> students=new HashSet<Student>();
    public Grade() {
    }
    @Id
    @GenericGenerator(name="generator",strategy="native")
    @GeneratedValue(generator="generator")
    public int getGid() {
        return gid;
    }
    public void setGid(int gid) {
        this.gid = gid;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @OneToMany(cascade={CascadeType.ALL},mappedBy="grade")
    public Set<Student> getStudents() {
        return students;
    }
    public void setStudents(Set<Student> students) {
        this.students = students;
    }
}

多对多关联

在多对多关联中,双方都采用@ManyToMany. 其中被维护方mappedBy表示由另外一多方维护
经过中间表由任一多方来维护关联关系
其中主控方,不像一对多注解那样,采用@joinColumn,而是采用@joinTable

@JoinTable(
     name="student_course",
     joinColumns={@JoinColumn(name="")},
     inverseJoinColumns={@JoinColumn(name="")}
)

由于多对多之间会经过一张中间表来维护两表直接的关系,因此经过JoinTable 这个注解来声明。
name就是指定了中间表的名字。
JoinColumns是一个@JoinColumn类型的数组,表示的是我这方在对方中的外键名称,就是当前类的主键。
inverseJoinColumns也是一个@JoinColumn类型的数组,表示的是对方在我这方中的外键名称,也能够这样想:上面提到mappedBy,至关于inverse="true".因此,在@joinTable中的inverseJoinColumns中定义的字段为mappedBy所在类的主键。

在前面的基础上增长课程类并补充学生类

/*
 * 学生类负责关联关系
 */
@Entity
@Table(name="Student")
public class Student implements Serializable{
    private int sid;
    private String name;
    private String sex;
    private Grade grade;
    private Set<Course> courses=new HashSet<Course>();
    public Student() {
        
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Id
    @GenericGenerator(name="generator",strategy="native")
    @GeneratedValue(generator="generator")
    public int getId() {
        return sid;
    }
    public void setId(int id) {
        this.sid = id;
    }
    @Column(name="sex")
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    @ManyToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="gid")
    public Grade getGrade() {
        return grade;
    }
    public void setGrade(Grade grade) {
        this.grade = grade;
    }
    @ManyToMany(cascade={CascadeType.ALL},fetch=FetchType.EAGER)
    @JoinTable(name="student_course",joinColumns={@JoinColumn(name="sid")},inverseJoinColumns={@JoinColumn(name="cid")})
    public Set<Course> getCourses() {
        return courses;
    }
    public void setCourses(Set<Course> courses) {
        this.courses = courses;
    }
}
@Entity
@Table(name="Course")
public class Course implements Serializable{

    private int cid;
    private String cName;
    private Set<Student> students=new HashSet<Student>();
    public Course() {
    }
    @Id
    @GenericGenerator(name="generator",strategy="native")
    @GeneratedValue(generator="generator")
    public int getCid() {
        return cid;
    }
    public void setStudents(Set<Student> students) {
        this.students = students;
    }
    public void setCid(int cid) {
        this.cid = cid;
    }
    public String getcName() {
        return cName;
    }
    public void setcName(String cName) {
        this.cName = cName;
    }
    @ManyToMany(cascade={CascadeType.ALL},fetch=FetchType.LAZY ,mappedBy="courses") 
    public Set<Student> getStudents() {
        return students;
    }
}
相关文章
相关标签/搜索