JPA注解
@Entity
@Table(name="?")
@Id @GeneratedValue(strategy=?)默认值:strategy=GenerationType.AUTO
@Temporal(TemporalType.DATE|TIME|TIMESTAMP) 指定时间格式类型
@Enumerated(EnumType.ORDINAL|STRING) 指定枚举类型,ORDINAL代表索引,STRING代表字符串
@Lob 指定大数据字段(大文本和大二进制数据字段) 大文本对应属性类型String,大二进制数据对应属性Byte[]
@Column(name="?",length=?,nullable=false|true)
@Transient 属性不被映射
@Basic(fetch=FetchType.EAGER|LAZY) 延迟加载设置
JPA API
EntityManager.persist();
EntityManager.find();
EntityManager.getReference();
EntityManager.clear(); 把实体管理器中的所有实体变为游离(脱管)状态
EntityManager.merge(); 对游离的实体对象进行更新
EntityManager.remove();
实体更新请注意:1.与事务进行关联 2.实体对象处于托管(受管)状态;这时对实体对象属性的修改在事务提交时就会同步到数据库中,而不需要再调用实体更新的方法(EntityManager.merge())
find()与getReference()对应于Hibernate中的get()方法和load()方法
Hibernate中get()方法和load()方法的区别:
get()方法: User user=(User)session.get(User.class,userId);
load()方法:User user=(User)session.load(User.class,userId);
1. 如果数据库中没有userId对象,若调用get()方法会返回null,若调用load()方法会返回一个代理对象,如果接着调用user 对象的某个方法(除了其getId()方法)(而非仅仅其get操作)会抛出org.hibernate.ObjectNotFoundException
2. 调用get() 方法之后,Hibernate会立即执行数据库查询;而调用load()方法之后,Hibernate不会立即执行数据库查询,只有访问user 对象的方法(除了其getId()方法)(而非仅仅其get()操作)时才会去执行SQL。
3.User user=(User)session.load(User.class,userId);
System.out.println(user.getId());
上面这2句代码,不会去执行数据库操作。因为load后会在hibernate的一级缓存里存放一 个map对象,该map的key就是userId的值,但是当你getId()时,它会去一级缓存里拿map的key 值,而不去执行数据库查询。所以不会报任何错(当不存在userId对象时),不会执行任何数 据库操作。
JPQL两种传参方式
select p from Personp where o.id=?1
select p from Person p where o.id=:id
关联关系
一对多双向关联:
多的一方为关系维护端,关系维护端负责外键字段的更新,关系被维护端是没有权力更新外键字段的。
级联操作:cascade=CascadeType.? 用于设置级联操作,每一种级联方式都分别对应一个JPA方法(如CascadeType.PERSIST对应于persist方法,CascadeType.REFRESH对应于refresh方法),共四种级联操作。
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY|EAGER,mappedBy="?")
对于集合默认为采用延迟加载,mappedBy 指定"Many"方类引用"One"方类的属性名,设置了mappedBy属性的实体为关联被维护端,别一端为维护端。
@ManyToOne(cascade={?,?...},optional=false|true)
@JoinColumn(name="?")
@JoinColumn用于指定关联实体所对应表的外键字段
一对一双向关联:
关联被维护端:@OneToOne(mappedBy = "?", cascade = ?, optional = false)
关联维护端 :@OneToOne(cascade=?,optional=false)
@JoinColumn(name="?")
在一对多双向关联中,当关联维护端设置了optional = false时,关联被维护端可以不用设置optional = false,当然设置了也没什么不对
多对多双向关联:
一个简单的例子
关联被维护端:@ManyToMany(cascade=CascadeType.REFRESH,mappedBy="teachers")
关联维护端 :@ManyToMany(cascade = CascadeType.REFRESH)
@JoinTable(name = "student_teacher", inverseJoinColumns=@JoinColumn(name="teatcher_id"),joinColumns=@JoinColumn(name="student_id"))
inverseJoinColumns 被维护端外键的定义
joinColumns 维护端外键的定义
要注意的一个地方是在删除被维护端实体时要先删除中间表中的关系,而删除维护端实体时却不需要这样做,原因是维护端负责关系的维护,外键的更新
联合主键