文章目录
一.JPA优势:
标准化;简单易用,集成方便;可以媲美JDBC的查询能力;支持面向对象的高级特性
二.JPA三方面的技术:
ORM映射元数据;JPA的API;查询语句(JPQL)
三.注解
1.基本注解
@Entity
@Entity 表明该类 (UserEntity) 为一个被JPA管理的实体类,它默认对应数据库中的表名是user_entity。
这里也可以写成
@Entity(name = “xwj_user”)
或者
@Entity
@Table(name = “xwj_user”, schema = “test”)
查看@Entity注解,发现其只有一个属性name,表示其所对应的数据库中的表名
@Table
@Table: 当实体类与其映射的数据库表名不同名时需要使用 @Table注解说明,该标注与 @Entity 注解并列使用,置于实体类声明语句之前,可写于单独语句行,也可与声明语句同行。
@Table注解的常用选项是 name,用于指明数据库的表名
@Table注解还有两个选项 catalog 和 schema 用于设置表所属的数据库目录或模式,通常为数据库名
常用的两个属性:
1、name 用来命名 当前实体类 对应的数据库 表的名字
@Table(name = "tab_user")
2、uniqueConstraints 用来批量命名唯一键
其作用等同于多个:@Column(unique = true)
@Table(name = "tab_user",uniqueConstraints = {@UniqueConstraint(columnNames={"uid","email"})})
@Column
@Column:当实体的属性与其映射的数据库表的列不同名时需要使用@Column 标注说明,该属性通常置于实体的属性声明语句之前(置于属性的getter方法之前),还可与 @Id 标注一起使用。
@Column(insertable = false,updatable = false)
@Column 标注的常用属性是 name,用于设置映射数据库表的列名。此外,该标注还包含其它多个属性,如:unique 、nullable、length 等。
-
unique表示该字段是否为唯一标识,默认为false。如果表中有一个字段需要唯一标识,则既可以使用该标记,也可以使用@Table标记中的@UniqueConstraint。
-
nullable表示该字段是否可以为null值,默认为true。
-
insertable 表示在使用“INSERT”脚本插入数据时,是否需要插入该字段的值。
-
updatable表示在使用“UPDATE”脚本插入数据时,是否需要更新该字段的值。insertable和updatable属性一般多用于只读的属性,例如主键和外键等。这些字段的值通常是自动生成的。
-
columnDefinition(大多数情况,几乎不用)表示创建表时,该字段创建的SQL语句,一般用于通过Entity生成表定义时使用。(也就是说,如果DB中表已经建好,该属性没有必要使用。)
-
table表示当映射多个表时,指定表的表中的字段。默认值为主表的表名。
-
length表示字段的长度,当字段的类型为varchar时,该属性才有效,默认为255个字符。
-
precision和scale precision属性和scale属性表示精度,当字段类型为double时,precision表示数值的总长度,scale表示小数点所占的位数。
-name 定义了被标注字段在数据库表中所对应字段的名称;
@Id
@Id: 标注用于声明一个实体类的属性映射为数据库的主键列。该属性通常置于属性声明语句之前,可与声明语句同行,也可写在单独行上,但一个实体类里面必须有一个。 @Id标注也可置于属性的getter方法之前。
@IdClass
@IdClass: 实体类定义联合主键@IdClass注解的使用
@GeneratedValue
@GeneratedValue:主要就是为一个实体生成一个唯一标识的主键、@GeneratedValue提供了主键的生成策略。@GeneratedValue注解有两个属性,分别是strategy和generator
generator属性的值是一个字符串,默认为"",其声明了主键生成器的名称
(对应于同名的主键生成器@SequenceGenerator和@TableGenerator)。
默认情况下,JPA 自动选择一个最适合底层数据库的主键生成策略:
strategy属性:提供四种值:
IDENTITY:采用数据库 ID自增长的方式来自增主键字段,Oracle 不支持这种方式;(SqlServer 对应 )
AUTO: JPA自动选择合适的策略,是默认选项;(MySQL 对应)
SEQUENCE:通过序列产生主键,通过 @SequenceGenerator 注解指定序列名,MySql 不支持这种方式
TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植。
注意:默认SpringBoot的@GeneratedValue 是不需要加参数的,但是如果数据库控制主键自增(auto_increment), 不加参数就会报错
@Basic
@Basic表示一个简单的属性到数据库表的字段的映射,对于没有任何标注的 getXxxx() 方法,默认即为
@Basic fetch: 表示该属性的读取策略,有 EAGER 和 LAZY 两种,分别表示主支抓取和延迟加载,默认为 EAGER.
optional:表示该属性是否允许为null, 默认为true
@Transient
@Transient并非一个到数据库表的字段的映射,表示非持久化属性
@Enumerated
@Enumerated直接映射enum 枚举类型的字段点击查看详情
2.关联关系注解
*如何确定单向与双向关联?
在实际开发中,是采用单向关联还是双向关联,要看具体的业务需求,如果业务只需要在获取一方的实体时获取另一方的实体,而不是两边都能获取,那就采用单向关联。反之,如果需要在两边的实体中都能获取到对方,就使用双向关联。
(1)@OneToOne一对一
双向关联,每一方都能获取到对方的实体
// CREATE TABLE `person` (
// `id` varchar(255) NOT NULL,
// `pname` varchar(255) DEFAULT NULL,
// `idcard` varchar(255),(外键)
// PRIMARY KEY (`id`)
// ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
// CREATE TABLE `idcard` (
// `id` varchar(255) NOT NULL,
// `cardnum` varchar(255) DEFAULT NULL,
// PRIMARY KEY (`id`)
// ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@Entity
@Table(name="person")
public class Person {
@Id
@GenericGenerator(name="uuidGenerator", strategy="uuid")
@GeneratedValue(generator="uuidGenerator")
private String id;
@Column(name="pname")
private String pname;
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name="idcard")
private IdCard card;
}
@Entity
@Table(name="idcard")
public class IdCard {
@Id
@GenericGenerator(name="uuidGenerator", strategy="uuid")
@GeneratedValue(generator="uuidGenerator")
private String id;
@Column(name="cardNum")
private String cardNum;
@OneToOne
@mappedBy(name="card")
private Person person;
}
(2)@OneToMany一对多单向关联
@JoinColumn指明该属性所关联的外键。
targetEntity:指明该属性所关联的类。
cascade:指定级联类型。其为数组,使用多种级联,则可使用{ }赋值。其值为Cascade常量:
对于一对多单向关联关系的多方,由于其不具备维护关联关系的能力,即没有一方对象作为属性,所以这里是不用设置关联相关的注解的。
关系的维护分为两类:
- 级联Cascade,在操作一方时,是否对另一方也执行同样的操作。
- 外键的维护inverse,在操作一方时,是否自动维护外键关系。比如如果将 多方的对象添加给以一的一方,因为外键由多方维护,hibernate为了保证添加的这个多方对象的外键是正确的,会自动给这个多方的外键设置值(也就是一的一方的主键)
外键维护,在xml配置中使用inverse属性,在注解中使用mappedBy注解来声明。
cascade与inverse
1.cascade,指把对当前对象的操作 级联到 关联对象上。
一般在one to one ,one to many设置级联。
配置了这个属性后,当对当前对象执行如save等更新数据库的操作时,当前实体所关联的实体也会执行相应的操作。
2.inverse
默认值为true, 表示让对方来维护关系。设为false,自己维护关系。
inverse主要有两个作用:
1)维护外键
主控方保存时,是否自动update被控方的外键字段。外键字段指向的就是当前保存的实体。
2)维护级联
决定当前设置的级联是否有用,自己维护关系时,对方设置的级联就不会生效,对方保存时不会让本方也保存。而对方维护关系,则与此相反。
(3)一对多双向关联
这其中增加了mappedBy属性。
mappedBy属性用法:
- 该属性与关联关系的维护权相关。
- 该属性应放在放弃维护权一方。
- 该属性值为对方的关联属性,表明以后的关联关系将由它来负责。
- 使用该属性的注解,无需也不能再设置cascade属性。
- 该属性只可能在双向关联中使用。
- 使用了该属性,将不能再使用@JoinColumn注解。因为@JoinColumn注解表示其所注解的属性将来通过set方法设值后,会与DB中哪个字段相关联。
mappedBy属性表示当前注解的关联属性放弃了维护权,即使执行了set方法将值设置入,其也不会写入到DB中。
也正因为放弃了维护权,与DB无关了,所以设置了mappedBy属性的注解,再设置cascade也就无意义了。
一个是使被注解者与DB相关,一个是使被注解者放弃与DB的关系,它们是相互矛盾的
@mappedBy注解
1)mappedBy(name="对方标准代表当前实体的属性“)
2)只存在于OneToOne,OneToMany,ManyToMany, 不能在ManyToOne中
3)与joincolumn或jointable互斥。因为joincolumn在拥有方声明了被拥有方,而mappedby定义在被拥有方,指向拥有方。
4)一般拥有方为拥有外键的那一方,在一对多中是在多方。
有什么用:
让拥有方来自动维护与当前实体的关系。与inverse对应。inverse=true
在注解中没有设置mappedBy时,默认双方都维护关系,就如inverse。
(4)自关联
(5)@ManyToOne多对一单向关联
(6)@ManyToMany多对多单向关联
多对多关联使用@ManyToMany注解。其会自动生成一个中间表,表名为两个关联对象的映射表名的联合:表1_表2。该表包含两个字段,字段名也与表名相关。字段名分别为:表1_id与表2_id。当然,默认的表名与字段名均可通过@JoinTable进行修改(不研究)。
(7)多对多双向关联
tip:这种情况仅是个人遇到,对于别人的见解可以可以参考,在这不做任何评论。如有其他情况可以相互交流!!!!