JPA:Java Persistence API.
JPA通过注解或XML的形式来描述对象-关系表的映射关系(ORM),通过服务器部署运行后,将实体对象持久化到数据库中。(JPA的宗旨是为POJO提供持久化标准规范)
JPA包括以下3方面的技术:
(1)ORM映射元数据
JPA支持XML和JDK 5.0注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中;
(2)JPA 的API
用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来。
(3)查询语言
这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
JPA个标签的含义
1.基本属性标签
@Entity //标识这个pojo是一个jpa实体
@Table(name = "users") //指定表名为users
public class Users implements Serializable {
@Id //设置主键
@GeneratedValue(strategy=GenerationType.SEQUENCE)
//主键生成策略,自增。这里的策略依赖于具体的数据库,不同数据库生成策略有所不用(IDENTITY或TABLE)
sequence与identity 自动识别数据库,但是table还要设置其他属性较麻烦,要借助一个表来实现主键自增, 通过一个表来实现主键id的自增,这种方式不依赖于具体的数据库,可以解决数据迁移的问题。
此外,一些实现了JPA规范的ORM映射框架,还提供了自己支持的主键生成策略,比如使用Hibernate-Annotation来实现持久化映射,就可以使用Hibernate提供的UUID主键生成策略.
private String userCode;
@Column(nullable = false, name = "USERNAME")
private StringuserName;
/**通过@Column注解设置,包含的可设置属性如下
*name:字段名
*unique:是否唯一
*nullable:是否可以为空
*inserttable:是否可以插入
*length : 字段长度
*updateable:是否可以更新
*columnDefinition: 定义建表时创建此列的DDL
*secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字。
**/
@Temporal(TemporalTypr.DATE)//设置时间类型
private Date joinDate;
/**
* 注解时间类型要用@Temporal,通过设置@Temporal的value来设置注解时间的类型
* @Temporal的value一共有三种,分别是:
* TemporalType.DATE map as java.sql.Date
*日期型 精确到日 EG:2008-08-08
* TemporalType.TIME map as java.sql.Time
* 时间型 精确到秒 EG:20:00:00
* TemporalType.TIMESTAMP map as java.sql.Timestamp
* 时间型 精确到纳秒 EG:2008-08-08 20:00:00.000000001
* 所以根据自己不同的需求来设置TemporalType的值 */
@OrderBy(name = "group_name ASC, name DESC") //字段排序
private List books = new ArrayList();
}
2.映射关系标签
(1)一对多双向映射关系
有T_One和T_Many两个表,他们是一对多的关系,注解范例如下
(主Pojo )
@Entity
@Table(name = "T_ONE")
public class One implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ONE_ID", nullable = false)
private String oneId;
@Column(name = "DESCRIPTION")
private String description;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "oneId")//指向多的那方的pojo的关联外键字段
private Collection<Many> manyCollection;
(子Pojo)
@Entity
@Table(name = "T_MANY")
public class Many implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "MANY_ID", nullable = false)
private String manyId;
@Column(name = "DESCRIPTION")
private String description;
@JoinColumn(name = "ONE_ID", referencedColumnName = "ONE_ID")//设置对应数据表的列名和引用的数据表的列名
@ManyToOne//设置在“一方”pojo的外键字段上
private One oneId;
说明:
一对多双向关联跟多对一是一样的,在多端生成一个外键,不生成第三张表来管理对应关系,由外键来管理对应关系
(2)多对多映射关系
貌似多对多关系不需要设置级联,估计JPA的多对多也是可以转换成两个一对多的。
(一般在设计数据库关系的时候不推荐多对多关系,一般以一对多为主)
(第一个Pojo )
@Entity
@Table(name = "T_MANYA")
public class ManyA implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "MANYA_ID", nullable = false)
private String manyaId;
@Column(name = "DESCRIPTION")
private String description;
@ManyToMany
@JoinTable(name = "TMANY1_TMANY2", joinColumns = {@JoinColumn(name = "MANYA_ID", referencedColumnName = "MANYA_ID")}
private Collection<ManyB> manybIdCollection;
(第二个Pojo )
@Entity
@Table(name = "T_MANYB")
public class ManyB implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "MANYB_ID", nullable = false)
private String manybId;
@Column(name = "DESCRIPTION")
private String description;
@ManyToMany(mappedBy = "manybIdCollection")
private Collection<ManyA> manyaIdCollection;
(3).一对一外键映射关系
(主Pojo )
@Entity
@Table(name = "T_ONEA")
public class OneA implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ONEA_ID", nullable = false)
private String oneaId;
@Column(name = "DESCRIPTION")
private String description;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "oneA")//主Pojo这方的设置比较简单,只要设置好级联和映射到从Pojo的外键就可以了。
private OneB oneB;
(从Pojo)
@Entity
@Table(name = "T_ONEB")
public class OneB implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ONEA_ID", nullable = false)
private String oneaId;
@Column(name = "DESCRIPTION")
private String description;
@JoinColumn(name = "ONEA_ID", unique=ture referencedColumnName = "ONEA_ID", insertable = false)
//设置从方指向主方的关联外键,这个ONEA_ID其实是表T_ONEA的主键
@OneToOne
private OneA oneA;
/* cascade属性
默认值:空 CascadeType 数组。
默认情况下,JPA 不会将任何持续性操作层叠到关联的目标。
如果希望某些或所有持续性操作层叠到关联的目标,请将 cascade 设置为一个或多个 CascadeType 实例,其中包括:
ALL - 针对拥有实体执行的任何持续性操作均层叠到关联的目标。
MERGE - 如果合并了拥有实体,则将 merge 层叠到关联的目标。
PERSIST - 如果持久保存拥有实体,则将 persist 层叠到关联的目标。
REFRESH - 如果刷新了拥有实体,则 refresh 为关联的层叠目标。
REMOVE - 如果删除了拥有实体,则还删除关联的目标。
fetch属性
默认值: FetchType.EAGER。
默认情况下,JPA 持续性提供程序使用获取类型 EAGER:它要求持续性提供程序运行时必须急性获取数据。
如果这不适合于应用程序或特定的持久字段,请将 fetch 设置为FetchType.LAZY:它提示持续性提供程序在首次访问数据(如果可以)时应惰性获取数据。
mappedBy属性
默认值:JPA 持续性提供程序从被引用的对象类型推断出关联的目标实体
如果持续性提供程序无法推断关联的目标实体,则将关联的相反(非拥有)方上的mappedBy 元素设置为拥有此关系的字段或属性的 String 名称(如 示例 1-64)所示。
optional属性
默认值: true。
默认情况下,JPA 持续性提供程序假设所有(非基元)字段和属性的值可以为空。
如果这并不适合于您的应用程序,请将 optional 设置为 false。
targetEntity属性
默认值:JPA 持续性提供程序从被引用的对象类型推断出关联的目标实体
如果持续性提供程序无法推断出目标实体的类型,则将关联的拥有方上的targetEntity 元素设置为作为关系目标的实体的 Class。 */
大字段
@Lob //对应Blob字段类型 (图片格式)
@Lob //对应Clob字段类型 (文本格式)
瞬时字段 :不需要与数据库映射的字段,在保存的时候不需要保存倒数据库
@Transient
类的继承映射
JPA对于具有父子关系的类,对于父类必须声明继承实体的映射策略,对于继承实体,java.persistence.InheritanceType定义了3种映射策略(跟Hibernate类继承的映射原理相同):
SINGLE_TABLE:父子类都保存在同一个表中,通过字段值进行区分。此方法推荐使用
JOINED:父子类相同的部分保存在同一个表中,不同的部门分开存放,通过连接不同的表获取完整数据。
TABLE_PER_CLASS:每一个类对应自己的表,一般不推荐采用这种方式。