hibernate注解详解

来源:互联网 发布:船 vhf 编程 sdk 编辑:程序博客网 时间:2024/05/22 07:01

hibernate注解处了对Jpa(java persistent api)的支持外,还提供了很多扩展的注解.

今天就简单对jpa的这部分注解进行一个剖析.

在学习hibernate注解之前,我们先了解以下注解的原理是什么,这样才能更好的理解hibernate的注解.

jdk5注解原理:

自定义注解:

/** * 自定义注解类: * 通过@interface定义注解 * 所有的注解都默认实现了annotation接口 *  * 定义注解中的成员: * 定义的格式像class中的属性, 又像interface中的方法. *  * jdk5中内置的注解: * @Documented : 生成javadoc文档 * @Target: 目标地址. 决定: 该注解是该放到方法上呢? 还是该放到属性上呢... * @retention: 注解的生命周期. 决定: 该注解是在java文件有效, 还是class文件有效, 还是运行期有效 */}<pre name="code" class="java">@Documented@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface CoustemerAnnotation {String name() default "";

使用注解:

/** * 注解的使用: * 在注解@Target定义的类型上使用注解. * 并为注解成员赋值 *  * 注意: * 如果只有一个成员, 并且这个成员的名称为value, 那么可以省略掉属性名称.. * 如果成员的类型是数组, 并且只有一个元素的时候, 可以省略掉{}. */@CoustemerAnnotation(name="jingtao")public class Coustemer {public void helloWorld() {}}
利用反射调用注解:

// 获得字节码对象Class<Coustemer> cls = Coustemer.class;// 判断是否有注解if (cls.isAnnotationPresent(CoustemerAnnotation.class)) {// 获得注解CoustemerAnnotation annotation = cls.getAnnotation(CoustemerAnnotation.class);System.out.println(annotation.name());}
至此,我们对注解有一定的了解了.

下面我们看看hibernate中对jpa的支持.

这里就采用我们最属性的用户,角色, 权限来做实例把

User类

package com.hibernate.domain;import java.util.Set;import javax.persistence.Basic;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinTable;import javax.persistence.Lob;import javax.persistence.ManyToMany;import javax.persistence.OneToMany;import javax.persistence.Table;/** * 实体与表的映射:  * @Entity : 标识该类与持久化类, 又hibernate帮助我们管理 *  * @Table : 用于描述与此类对应的数据库的信息. * name : 表示表名. * catalog : 表示哪个数据库. */@Entity@Table(name = "user", catalog="test")public class User {private Long id;private String password;private Set<Role> roles; // 用户与角色的多对多关联属性private String username;/** * 主键映射: * @Id : 标识该属性映射为数据库中的主键. *  既然是主键, 那么主键的生成策略是什么呢? 他是由@GeneratedValue来指定的 *  * @GeneratedValue : * strategy : 表名该主键的生成策略. * 包含: mysql类的自增长策略, orcal的序列策略, 还有利用中间表来生成主键的策略. */@Id@GeneratedValue(strategy = GenerationType.AUTO)public Long getId() {return id;}/** * 属性与列映射 *   @Column : 用来描述, 对应的数据库中的列的信息. * name : 该列的名称为什么 * length : 该列的长度是多少 * unique : 是否唯一值 * nullable : 是否可以为空 * ... */@Column(name = "username", length = 20,unique = false, nullable = false)public String getUsername() {return username;}@Column(name = "password", length = 20)public String getPassword() {return password;}/** * 多对多关联关系与中间表的映射: * @ManyToMany * cascade : 级联操作. * 一般都是保持和更新级联, 对于删除根据情况而定. * fetch :  * 关联对象的加载策略.  * 一般为了提高效率, 以及解决N+1问题, 都是采用懒加载策略 * mappedBy :  * 由谁来维护关系. * 对于多对多关系, 随便哪个类来维护关系, 效率都是一样的. * 对于多对一关系, 一般都是有多方来维护关系 *  *  @JoinTable : 描述数据库中用来表示多对多关系的中间表信息(将多对多关系拆分为2个一对多关系) *  name : 中间表的名称 *  joinColumns : 数组类型, 用来描述该类所映射的表与中间表的一对多关系是通过哪个外键来表述的. *  name : 外键的名称. *  referencedColumnName : 引用了哪个列. *  inverseJoinColumns : 数组类型, 用来描述关联类所映射的表与中间表的一对多关系是通过哪个外键来表述的. */@ManyToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "uId", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "rId", referencedColumnName = "id"))public Set<Role> getRoles() {return roles;}public void setId(Long id) {this.id = id;}public void setPassword(String password) {this.password = password;}public void setRoles(Set<Role> roles) {this.roles = roles;}public void setUsername(String username) {this.username = username;}}


Role类

@Entity@Table(name="role")public class Role {private Long id;private String name;private Set<Privilege> privileges; // 表示角色与权限的多对多关系, 是单向关联 @Id@GeneratedValue(strategy=GenerationType.AUTO)@Column(name="id", length=20)public Long getId() {return id;}public void setId(Long id) {this.id = id;}@Column(name="name", length=50)public String getName() {return name;}public void setName(String name) {this.name = name;}@ManyToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)@JoinTable(name="role_privilege",joinColumns=@JoinColumn(name="rId", referencedColumnName="id"),inverseJoinColumns=@JoinColumn(name="pId",referencedColumnName="id"))public Set<Privilege> getPrivileges() {return privileges;}public void setPrivileges(Set<Privilege> privileges) {this.privileges = privileges;}}
Privilege类

@Entity@Table(name="privilege")public class Privilege {private Long id;private String name;private String url;@Id@GeneratedValue(strategy=GenerationType.AUTO)@Column(name="id", length=20)public Long getId() {return id;}public void setId(Long id) {this.id = id;}@Column(name="name", length=50)public String getName() {return name;}public void setName(String name) {this.name = name;}@Column(name="url", length=50)public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}}

然后在hibernate的配置文件中加入注解即可

<mapping class="com.hibernate.domain.Privilege"/><mapping class="com.hibernate.domain.Role"/><mapping class="com.hibernate.domain.User"/>








0 0
原创粉丝点击