实体和数据库之间存在某种映射关系,hibernate根据这种映射关系完成数据的存取。在程序中这种映射关系由映射文件(*.hbm.xml)或者java注解(@)定义。

本文以java注解的形式总结映射关系配置。

一、导入依赖包。

hibernate-distribution-3.6.5.Final-dist\hibernate-distribution-3.6.5.Final\lib\jpa 目录下的 hibernate-jpa-2.0-api-1.0.0.Final.jar

二、新建实体类

package com.souvc.domain.user;

import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType; import org.springframework.format.annotation.DateTimeFormat;
/**
* 类名: UserLoginLog
* 描述: 用户登录记录表类
* 开发人员: souvc
* 创建时间: 2015-9-7
* @version V3.0
*/
@Entity
@Table(name = "user_login_log")
public class UserLoginLog implements java.io.Serializable { private static final long serialVersionUID = 8686390190132322570L; private Integer loginId;
private String ip;
private String address;
private Integer type;
private Integer status;
@DateTimeFormat( pattern = "yyyy-MM-dd HH:mm:ss" )
private Date loginTime; //private UserBaseInfo userBaseInfo; @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "login_id", unique = true, nullable = false)
public Integer getLoginId() {
return loginId;
} public void setLoginId(Integer loginId) {
this.loginId = loginId;
} @Column(name = "ip", nullable = true)
public String getIp() {
return ip;
} public void setIp(String ip) {
this.ip = ip;
} @Column(name = "address", nullable = true)
public String getAddress() {
return address;
} public void setAddress(String address) {
this.address = address;
} @Column(name = "type", nullable = false)
public Integer getType() {
return type;
} public void setType(Integer type) {
this.type = type;
} @Column(name = "status", nullable = false)
public Integer getStatus() {
return status;
} public void setStatus(Integer status) {
this.status = status;
} @Column(name = "login_time", nullable = true)
@Temporal(TemporalType.TIMESTAMP)
public Date getLoginTime() {
return loginTime;
} public void setLoginTime(Date loginTime) {
this.loginTime = loginTime;
} // @ManyToOne(cascade = CascadeType.REFRESH, optional = false)
// @JoinColumn(name = "user_id", unique = true)
// public UserBaseInfo getUserBaseInfo() {
// return userBaseInfo;
// }
//
// public void setUserBaseInfo(UserBaseInfo userBaseInfo) {
// this.userBaseInfo = userBaseInfo;
// }
}

三、具体注解解释

实体类组件以及注解标签映射关系

实体类-----------@Entity/@Table----------数据表

Id--------------@Id----------主键

普通属性---------@Column----------普通键

集合属性---------@OneToMany/@ManyToOne/@ManyToMany/@OneToOne----------外键

A.写在类声明之前的有:

a.@Entity,以表明此Bean为EntityBean。每一个持久化POJO类都是一个实体bean,这可以通过在类的定义中使用@Entity注解来进行声明。name 为可选 , 对应数据库中一的个表

b.@Table (name=”TableName”),表示此实体Bean对应的数据库表名。

          @Table是类一级的注解, 通过@Table注解可以为实体bean映射指定表(table),目录(catalog)和schema的名字.

如果没有定义@Table,那么系统自动使用默认值:实体的短类名(不附带包名).@Table元素包括了一个schema 和一个 catalog属性,如果需要可以指定相应的值. 结合使用@UniqueConstraint注解可以定义表的唯一约束(unique constraint)

B.写在getXxx()方法声明之前的有:

a.@Column注释定义了映射到列的所有属性,如列名是否唯一,是否允许为空,是否允许更新等,他的属性介绍如下:

(1)    name 可选,列名(默认值是属性名)
(2) unique 可选,是否在该列上设置唯一约束(默认值false)
(3) nullable 可选,是否设置该列的值可以为空(默认值false)
(4) insertable 可选,该列是否作为生成的insert语句中的一个列(默认值true)
(5) updatable 可选,该列是否作为生成的update语句中的一个列(默认值true)
(6) columnDefinition 可选: 为这个特定列覆盖SQL DDL片段 (这可能导致无法在不同数据库间移植)
(7) table 可选,定义对应的表(默认为主表)
(8) length 可选,列长度(默认值255)
(8) precision 可选,列十进制精度(decimal precision)(默认值0)
(10) scale 可选,如果列十进制数值范围(decimal scale)可用,在此设置(默认值0)

b.@Id 注释指定personid属性为表的主键,它可以有多种生成方式:

@id 定义了映射到数据库表的主键的属性 , 一个实体只能有一个属性被映射为主键 . 置于 getXxxx() 前 .

·TABLE:容器指定用底层的数据表确保唯一。

      ·SEQUENCE:使用数据库的SEQUENCE 列来保证唯一

      ·IDENTITY:使用数据库的INDENTIT列来保证唯一

     ·AUTO:由容器挑选一个合适的方式来保证唯一

     ·NONE:容器不负责主键的生成,由调用程序来完成。

c.@GeneratedValue注释定义标识字段的生成方式。

@GeneratedValue(strategy=GenerationType,generator="")

strategy: 表示主键生成策略 , 有 AUTO,INDENTITY,SEQUENCE 和 TABLE 4 种 , 分别表示让 ORM 框架自动选择,

根据数据库的 Identity 字段生成 , 
根据数据库表的 Sequence 字段生成 ,
以有根据一个额外的表生成主键 , 默认为AUTO generator: 表示主键生成器的名称 , 这个属性通常和 ORM 框架相关 , 例如 ,Hibernate 可以指定 uuid 等主键生成方式 . 示例 : @Id @GeneratedValues(strategy=StrategyType.SEQUENCE) public int getPk() { return pk; }

d. @Version 映射版本号属性

e.  @Column 指定属性对应的列的信息

可选

@Column 描述了数据库表中该字段的详细定义 , 这对于根据 JPA 注解生成数据库表结构的工具非常有作用 .

name: 表示数据库表中该字段的名称 , 默认情形属性名称一致

nullable: 表示该字段是否允许为 null, 默认为 true

unique: 表示该字段是否是唯一标识 , 默认为 false

length: 表示该字段的大小 , 仅对 String 类型的字段有效

insertable: 表示在 ORM 框架执行插入操作时 , 该字段是否应出现 INSETRT 语句中 , 默认为 true

updateable: 表示在 ORM 框架执行更新操作时 , 该字段是否应该出现在 UPDATE 语句中 , 默认为 true. 对于一经创建就不可以更改的字段 , 该属性非常有用 , 如对于 birthday 字段 .

columnDefinition: 表示该字段在数据库中的实际类型 . 通常 ORM 框架可以根据属性类型自动判断数据库中字段的类型 , 但是对于 Date 类型仍无法确定数据库中字段类型究竟是 DATE,TIME 还是 TIMESTAMP. 此外 ,String 的默认映射类型为 VARCHAR, 如果要将 String 类型映射到特定数据库的 BLOB 或 TEXT 字段类型 , 该属性非常有用 .

示例 :

@Column(name="BIRTH",nullable="false",columnDefinition="DATE")

public String getBithday() {

return birthday;

}

f . @Temporal 指定日期时间的类型(TIMESTAMP,DATE,TIME)

g. 简单属性可以不用注解。默认就是@Basic

h. @Transient 指定属性不需要映射

可选

@Transient 表示该属性并非一个到数据库表的字段的映射 ,ORM 框架将忽略该属性 .

如果一个属性并非数据库表的字段映射 , 就务必将其标示为 @Transient, 否则 ,ORM 框架默认其注解为 @Basic

示例 :

// 根据 birth 计算出 age 属性

@Transient

public int getAge() {

return getYear(new Date()) - getYear(birth);

}

i.  复杂属性:关联,继承,组件,联合主键,集合

C.关系/对象映射

A.一对多:

@OneToMany指明关联关系为一对多关系,下面是@OneToMany 注释的属性:

1>targetEntity

Class 类型的属性。定义关系类的类型,默认是该成员属性对应的类类型,所以通常不需要提供定义。

2>mappedBy

String 类型的属性。定义类之间的双向关系。如果类之间是单向关系,不需要提供定义,如果类和类之间形成双向关系,我们就需要使用这个属性进行定义,否则可能引起数据一致性的问题。

3>cascade

CascadeType[]类型。

该属性定义类和类之间的级联关系。定义的级联关系将被容器视为对当前类对象及其关联类对象采取相同的操作,而且这种关系是递归调用的。

举个例 子:Order 和OrderItem 有级联关系,那么删除Order 时将同时删除它所对应的OrderItem对象。而如果OrderItem还和其他的对象之间有级联关系,那么这样的操作会一直递归执行下去。

cascade 的值只能从:

CascadeType.PERSIST(级联新建);

CascadeType.REMOVE(级联删除);

CascadeType.REFRESH(级联刷新);

CascadeType.MERGE(级联更新)中选择一个或多个。

还有一个选择是使用CascadeType.ALL,表示选择全部四项。

4>fatch

FetchType 类型的属性。

可选择项包括:FetchType.EAGER和FetchType.LAZY。

前者表示关系类(本例是OrderItem类)在主类(本例是Order类)加载的时候同时加载;

后者表示关系类在被访问时才加载。默认值是FetchType. LAZY。

@OrderBy(value = "id ASC")注释指明加载OrderItem 时按id 的升序排序。

B.多对一:

@ManyToOne注释,有四个属性:targetEntity、cascade、fetch 和optional。

前三个属性的具体含义和@OneToMany注释的同名属性相同,但@ManyToOne 注释的fetch 属性默认值是FetchType.EAGER。

optional 属性是定义该关联类对是否必须存在,值为false 时,关联类双方都必须存在,如果关系被维护端不存在,查询的结果为null。值为true 时, 关系被维护端可以不存在,查询的结果仍然会返回关系维护端,在关系维护端中指向关系被维护端的属性为null。

optional属性的默认值是true。

举个例:某项订单(Order)中没有订单项(OrderItem),如果optional 属性设置为false,获取该项订单(Order)时,得到的结果为null,如果optional属性设置为true,仍然可以获取该项订单,但订单中 指向订单项的属性为null。

实际上在解释Order 与OrderItem的关系成SQL时,optional属性指定了他们的联接关系

optional=false 联接关系为inner join,

optional=true 联接关系为left join。

@JoinColumn(name = "order_id")注释指定OrderItem 映射表的order_id 列作为外键与Order 映射表的主键列关联。

可选

@ManyToOne 表示一个多对一的映射 , 该注解标注的属性通常是数据库表的外键

optional: 是否允许该字段为 null, 该属性应该根据数据库表的外键约束来确定 , 默认为 true

fetch: 表示抓取策略 , 默认为 FetchType.EAGER

cascade: 表示默认的级联操作策略 , 可以指定为 ALL,PERSIST,MERGE,REFRESH 和 REMOVE 中的若干组合 , 默认为无级联操作

targetEntity: 表示该属性关联的实体类型 . 该属性通常不必指定 ,ORM 框架根据属性类型自动判断targetEntity.

示例 :

// 订单 Order 和用户 User 是一个 ManyToOne 的关系

// 在 Order 类中定义

@ManyToOne()

@JoinColumn(name="USER")

public User getUser() {

return user;

}

C.一对一:

@OneToOne 注释,有五个属性:targetEntity、cascade、fetch、optional 和mappedBy 。

前四个属性的具体含义与@ManyToOne 注释的同名属性一一对应, fetch 属性默认值是FetchType.EAGER。

mappedBy属性的具体含义与@OneToMany 注释的同名属性相同。

如果optional = true 设置表明此属性可以为null。

例如在身份证的处理时可以这样设置,因为未成年人就是没有身份证的。

D.多对多:

@ManyToMany 注释:表示此类是多对多关系的一边,mappedBy 属性定义了此类为双向关系的维护端,注意:mappedBy 属性的值为此关系的另一端的属性名。

例如,在Student类中有如下方法:

@ManyToMany(mappedBy = "students")

   public Set<Teacher> getTeachers() {

   return teachers;

}

那么这里的“students”就是Teachers的一个属性,通常应该是这样的:

Set<Student> students;

另一端的getStudents方法如下所示:

@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)

@JoinTable(name = "Teacher_Student",joinColumns = {@JoinColumn(name = "Teacher_ID", referencedColumnName = "teacherid")},inverseJoinColumns = {@JoinColumn(name = "Student_ID", referencedColumnName ="studentid")})

public Set<Student> getStudents() {

     return students;

}

@ManyToMany 注释表示Teacher 是多对多关系的一端。

@JoinTable 描述了多对多关系的数据表关系。

name 属性指定中间表名称,joinColumns 定义中间表与Teacher 表的外键关系。

上面的代码中,中间表Teacher_Student的Teacher_ID 列是Teacher 表的主键列对应的外键列,inverseJoinColumns 属性定义了中间表与另外一端(Student)的外键关系。

可以参照中文官方文档: http://docs.jboss.org/hibernate/annotations/3.4/reference/zh_cn/html_single/

Hibernate基于注解方式配置来实现实体和数据库之间存在某种映射关系的更多相关文章

  1. Spring boot 基于注解方式配置datasource

    Spring boot 基于注解方式配置datasource 编辑 ​ Xml配置 我们先来回顾下,使用xml配置数据源. 步骤: 先加载数据库相关配置文件; 配置数据源; 配置sqlSessionF ...

  2. Hibernate基于注解方式的各种映射全面总结

    1. 使用Hibernate Annotation来做对象关系映射 1) 添加必须包: hibernate-jpa-2.0-api-1.0.0.Final.jar 2) 在实体类中添加JPA的标准注解 ...

  3. hibernate annotation注解方式来处理映射关系

    在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,我在试了这两种方式 ...

  4. Shiro入门之二 --------基于注解方式的权限控制与Ehcache缓存

    一  基于注解方式的权限控制 首先, 在spring配置文件applicationContext.xml中配置自动代理和切面 <!-- 8配置自动代理 -->    <bean cl ...

  5. atitit.ajax bp dwr 3.的注解方式配置使用流程总结 VO9o.....

    atitit.ajax bp dwr 3.的注解方式配置使用流程总结 VO9o..... 1. 安装配置 1 1.1. 下载  dwr.jar 1M 1 1.2. 配置注解方式..web.xml 1 ...

  6. (spring-第4回【IoC基础篇】)spring基于注解的配置

    基于XML的bean属性配置:bean的定义信息与bean的实现类是分离的. 基于注解的配置:bean的定义信息是通过在bean实现类上标注注解实现. 也就是说,加了注解,相当于在XML中配置了,一样 ...

  7. Spring IoC — 基于注解的配置

    基于XML的配置,Bean定义信息和Bean实现类本身是分离的,而采用基于注解的配置方式时,Bean定义信息即通过在Bean实现类上标注注解实现. @Component:对类进行标注,Spring容器 ...

  8. SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP

    AOP(Aspect Oriented Programming),是面向切面编程的技术.AOP基于IoC基础,是对OOP的有益补充. AOP之所以能得到广泛应用,主要是因为它将应用系统拆分分了2个部分 ...

  9. Elasticsearch-mapper 基于注解方式生成mapping(2.0以上)

    Elasticsearch生成mapping的方式上有多种方式,我们可以把mapping做成配置文件,也可以用spring-data-elasticsearch基于注解生成. 在基于注解生成这种方式上 ...

随机推荐

  1. [Architect] Abp 框架原理解析(1) Module

    本节目录 Abp介绍 Abp源码分析 代码实现 Abp介绍 学习了一段时间的Abp,领略了一下前辈的架构.总结还是SOLID,降低耦合性. 虽然从架构上说甚至不依赖于DI框架,但实际上在基础框架中还是 ...

  2. GitHub Extension for Visual Studio 2.0 is now available

    GitHub Extension for Visual Studio 2.0 is now available We're pleased to announce that version 2.0 o ...

  3. 转帖一篇sixxpack破解的文章!

    星期天闲着没事玩游戏,玩游戏不能无外挂.于是百度了半天,找到了一个,看介绍貌似不错,就下载了下来.一看,竟然是用.net写的,下意识地Reflector了一下.发现竟是一个叫actmp的程序集.如图: ...

  4. 安卓使ScrollView滚动到底部代码

    在开发中,我们经常需要更新列表,并将列表拉倒最底部,比如发表微博,聊天界面等等, 这里有两种办法,第一种,使用scrollTo(): public static void scrollToBottom ...

  5. Python入门笔记(18):Python函数(1):基础部分

    一.什么是函数.方法.过程 推荐阅读:http://www.cnblogs.com/snandy/archive/2011/08/29/2153871.html 一般程序设计语言包含两种基本的抽象:过 ...

  6. 【循序渐进学Python】11.常用标准库

    安装完Python之后,我们也同时获得了强大的Python标准库,通过使用这些标准库可以为我们节省大量的时间.这里是一些常用标准库的简单说明.更多的标准库的说明,可以参考Python文档 sys 模块 ...

  7. php学习笔记:对文件的增删查改等操作

    文件的创建: 采用touch()函数,当文件不存在会被创建 例如: <?php header("Content-type: text/html; charset=utf-8" ...

  8. Java中Scanner类和BufferReader类之间的区别

    java.util.Scanner类是一个简单的文本扫描类,它可以解析基本数据类型和字符串.它本质上是使用正则表达式去读取不同的数据类型. Java.io.BufferedReader类为了能够高效的 ...

  9. rabbitmq+ keepalived+haproxy高可用集群详细命令

    公司要用rabbitmq研究了两周,特把 rabbitmq 高可用的研究成果备下 后续会更新封装的类库 安装erlang wget http://www.gelou.me/yum/erlang-18. ...

  10. 精简CSS代码

    精简CSS代码可以帮助减小样式文件的大小,使代码清晰,方便维护. 使用简写属性及默认值 .header { margin-top: 10px; margin-right: 20px; margin-b ...