JPA进阶-持久化状态

JPA进阶

主键生成策略

主键:数据的唯一标识,必须是非空唯一的

JPA主键生成的标准策略有4种:

auto:默认,根据方言自动选择生成策略

identity:mysql的主键自增长策略

sequence:主键的创建效率最高,Oracle的序列对象

table:其他的数据库使用,创建一个表,专门用来存储主键

一般使用默认的生成策略就行了

JPA持久对象的状态

临时状态

在刚用new语句创建,没有和entityManager发生关系

持久化状态(托管状态)

事务开始,和JPA发生关系了,被加入到了一级缓存当中

游离状态(脱管状态)

事务提交之后,但是已经和JPA脱离关系了

删除状态:从JPA开始才有

调用了remove()方法,删除对象后,变味了删除状态

脏数据更新

一个持久状态对象在事务管理内,如果改变原来的数据(非主键),此时出现脏数据,在事务提交的时候自动发出update语句去修改

Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.ifueen.sm;

import com.ifueen.util.JPAUtil;
import org.junit.Test;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

/**
*
* 测试持久化状态
*
*/
public class StateTest {
@Test
public void test(){
EntityManager jpa = JPAUtil.getJpa();
Student student = new Student();
student.setName("希区柯克"); //临时状态
EntityTransaction transaction = jpa.getTransaction();
transaction.begin(); //事务开启
jpa.persist(student); //脱管状态,与JPA发生关系
transaction.commit(); //事务提交,对象处于游离状态
jpa.close();

}

@Test
public void test1(){
EntityManager jpa = JPAUtil.getJpa();

EntityTransaction transaction = jpa.getTransaction();
transaction.begin(); //事务开启
Student student = jpa.find(Student.class, 12L);//脱管状态,与JPA发生关系
jpa.remove(student); //删除状态
transaction.commit(); //事务提交,对象处于游离状态
jpa.close();

}

@Test
public void test2(){
EntityManager jpa = JPAUtil.getJpa();

EntityTransaction transaction = jpa.getTransaction();
transaction.begin(); //事务开启
Student student = jpa.find(Student.class, 13L);//脱管状态,与JPA发生关系
System.out.println(student);
student.setName("库布里克"); //脏数据更新
transaction.commit(); //事务提交,对象处于游离状态
jpa.close();

}


}

域对象之间关系

域对象之间的关系分为一对一,一对多(多对一),多对多,现主要讲一下多对一的关系

单向多对一关系

说直白点,就是多个学生类可以对应一个老师类

从表Student类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package com.ifueen.sm;

import javax.persistence.*;

@Entity
@Table(name = "t_student")
public class Student {

@Id
@GeneratedValue
private Long id;
private String name;

@ManyToOne(fetch = FetchType.LAZY) //懒加载
private Tearcher tearcher;

public Student() {
}

@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", tearcher=" + tearcher +
'}';
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Tearcher getTearcher() {
return tearcher;
}

public void setTearcher(Tearcher tearcher) {
this.tearcher = tearcher;
}
}

主表Tearch类设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.ifueen.sm;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "t_tearch")
public class Tearcher {
@Id
@GeneratedValue
private Long id;
private String name;

public Tearcher() {
}

@Override
public String toString() {
return "Tearcher{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package com.ifueen.sm;

import com.ifueen.util.JPAUtil;
import org.junit.Test;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

public class StudentTest {


@Test
public void create(){

EntityManager jpa = JPAUtil.getJpa();

}

@Test
public void test1(){
//一方
Tearcher tearcher = new Tearcher();
tearcher.setName("高级算法");
//多方
Student student = new Student();
student.setName("山泥若");
student.setTearcher(tearcher);



EntityManager jpa = JPAUtil.getJpa();
EntityTransaction transaction = jpa.getTransaction();
transaction.begin();
jpa.persist(student);
jpa.persist(tearcher);
transaction.commit();
jpa.close();
}

@Test
public void test2(){
//一方
Tearcher tearcher = new Tearcher();
tearcher.setName("物理大牛");
//多方
Student student = new Student();
student.setName("牛顿");
student.setTearcher(tearcher);

Student student1 = new Student();
student1.setName("爱因斯坦");
student1.setTearcher(tearcher);

Student student2 = new Student();
student2.setName("霍金");
student2.setTearcher(tearcher);

Student student3 = new Student();
student3.setName("杨振宁");
student3.setTearcher(tearcher);

EntityManager jpa = JPAUtil.getJpa();
EntityTransaction transaction = jpa.getTransaction();
transaction.begin();
jpa.persist(tearcher);
jpa.persist(student);
jpa.persist(student1);
jpa.persist(student2);
jpa.persist(student3);
transaction.commit();
jpa.close();
}

@Test
public void test3(){

EntityManager jpa = JPAUtil.getJpa();
Student student = jpa.find(Student.class, 3L);
System.out.println(student.hashCode());
//懒加载之后
Tearcher tearcher = student.getTearcher();
System.out.println(tearcher);
jpa.close();
}

}

fetch抓取策略

FetchType.EAGER:fetch的默认值,立即加载

默认情况下,JPA持续性提供程序使用获取类型EAGER:这将要求持续性提供程序运行时必须迫切左外连接获取数据。

FetchType.LAZY:延迟加载

FetchType.LAZY:这将提示持续性提供程序在首次访问数据时并不急于获取数据。

❤赏点钱让我买杯快乐水8❤