您好,登錄后才能下訂單哦!
這篇文章主要講解了“理解java持久化API”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“理解java持久化API”吧!
PA,Java Persistence API是Sun官方提出的Java持久化規(guī)范。它為Java開發(fā)人員提供了一種對象/關(guān)聯(lián)映射工具來管理Java應(yīng)用中的關(guān)系數(shù)據(jù)。它的出現(xiàn)主要是為了簡化現(xiàn)有的持久化開發(fā)工作和整合ORM技術(shù)
ORM:通過使用描述對象和數(shù)據(jù)庫之間映射的元數(shù)據(jù),將程序中的對象自動持久化到關(guān)系數(shù)據(jù)庫中。本質(zhì)就是將數(shù)據(jù)從一種形式轉(zhuǎn)換到另外一種形式。
同時也結(jié)束了Hibernate、TopLink等ORM框架各自為營的局面。JPA充分吸收了Hibernate、TopLink等ORM框架的基礎(chǔ)上發(fā)展起來的,使用方便,伸縮性強(qiáng)
注意: JPA不是一種新的ORM框架,它的出現(xiàn)只是用于規(guī)范現(xiàn)有的ORM技術(shù),它不能取代現(xiàn)有的Hibernate等ORM框架,相反,采用JPA開發(fā)時,我們?nèi)詫⑹褂眠@些ORM框架,只是此時開發(fā)出來的應(yīng)用不在依賴于某個持久化提供商。應(yīng)用可以在不修改代碼的情況下載任何JPA環(huán)境下運(yùn)行,真正做到低耦合,可擴(kuò)展的程序設(shè)計。類似于JDBC,在JDBC出現(xiàn)以前,我們的程序針對特性的數(shù)據(jù)庫API進(jìn)行編程,但是現(xiàn)在我們只需要針對JDBC API編程,這樣能夠在不改變代碼的情況下就能換成其他的數(shù)據(jù)庫。
JPA是一套規(guī)范,不是一套產(chǎn)品。Hibernate是一套產(chǎn)品,如果這些產(chǎn)品實(shí)現(xiàn)了JPA規(guī)范,那么我們可以叫它們?yōu)镴PA的實(shí)現(xiàn)產(chǎn)品。使用JPA,就可以把我們的應(yīng)用從Hibernate中解脫出來,那么現(xiàn)在問題來了::如何使用JPA來開發(fā)呢?
準(zhǔn)備好了嗎,進(jìn)入正題,起飛!
首先,先帶大家看一下本篇文章的大致介紹。
沒目錄怎么知道這篇到底有多少干貨呢?
以前的開發(fā)模式
JPA是什么
JPA解決了什么問題
JPA的第一個HelloWord程序
詳解配置文件
常用的注解
一對一的問題
一對多的問題
多對多的問題
JPA中常見的方法
JPA中對象的狀態(tài)
注意事項
是不是很清晰呢,什么?還不進(jìn)入正文,來了,安排上,一個一個來:
回顧以前的開發(fā)模式
以前開發(fā)的時候我們的DAO層,要么使用Hibernate、要么使用iBatis、dbutils、toplink
需求:假設(shè)現(xiàn)在的產(chǎn)品的1.0版本的DAO的實(shí)現(xiàn)使用的是Hibernate、現(xiàn)在老板要求將DAO層換成TopLink
按照現(xiàn)在的解決方案整個DAO層都是需要重寫的,很耗費(fèi)人力和物力,增加了成本
有沒有一種方案?這種方案就是如果我們需要換ORM框架,我們的整個DAO層都不需要改變只是需要改變配置文件就可以了呢?
JPA技術(shù)技術(shù)因此而生
JPA是什么
JPA實(shí)際上是sun公司出的一套規(guī)范、這套規(guī)范的作用是為了解決市場上ORM框架一家獨(dú)大的問題
JPA是一套規(guī)范,只要我們的ORM框架實(shí)現(xiàn)了這套規(guī)范,那么在使用這個ORM框架的時候,就不需要面對于某一種ORM產(chǎn)品的API來進(jìn)行編程,而是統(tǒng)一的面向于JPA來進(jìn)行編程,這個時候即使你的ORM產(chǎn)品改變了,那么你的DAO層面向于JPA編程的代碼是不用變的
JPA解決了什么問題
JPA統(tǒng)一了ORM框架訪問數(shù)據(jù)庫的API
JPA解決了ORM框架一家獨(dú)大的問題
JPA的第一個HelloWorld程序
導(dǎo)包
編寫配置文件
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
復(fù)制編寫Java實(shí)體和注解
@Table(name="t_user") //設(shè)置當(dāng)前的類的對象對應(yīng)的表名字
@Entity //表示當(dāng)前的這個類是一個持久化的實(shí)體
public class User {
@Id //這個表示的是當(dāng)前的字段是主鍵
@GeneratedValue(strategy=GenerationType.IDENTITY) //這個表示的是主鍵的生成策略(自增長)
@Column(name="uId")
private int uId;
@Column(name="userName") //列的名字
private String userName;
@Column(name="password")
private String password;
}
復(fù)制測試
@Test
public void testHelloWorld() throws Exception {
//第一步:創(chuàng)建實(shí)體管理的工廠
EntityManagerFactory ef=Persistence.createEntityManagerFactory("hibernateJPA");
//通過工廠創(chuàng)建實(shí)體的管理器
EntityManager em=ef.createEntityManager();
//第三步:開啟事務(wù)
em.getTransaction().begin();
//操作業(yè)務(wù)邏輯
User user=new User();
user.setUserName("淺羽");
user.setPassword("123");
//保存用戶實(shí)體到數(shù)據(jù)庫
em.persist(user);
//提交事務(wù)
em.getTransaction().commit();
//關(guān)閉管理器
em.close();
ef.close();
}
復(fù)制詳解配置文件
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
復(fù)制常用的注解線程池技術(shù)
@Table:表示的是當(dāng)前的實(shí)體對應(yīng)的數(shù)據(jù)庫中的表名字
@Entity:表示的是當(dāng)前的實(shí)體是一個持久化的實(shí)體
@Id:這個表示當(dāng)前的屬性是一個主鍵
@GeneratedValue:主鍵的生成策略
strategy=GenerationType.IDENTITY:這個表示的是主鍵自增長
strategy=GenerationType.AUTO:使用表來生成目標(biāo)表的主鍵
strategy=GenerationType.SEQUENCE:使用序列來生成主鍵
@Column:jAVA的屬性對應(yīng)的數(shù)據(jù)庫表的列的名字
Name:名字
Length:表示的是字段的長度
nullable=false:這個表示的是不能為null
unique=true:是否是唯一的
@Transient :當(dāng)前字段在數(shù)據(jù)庫中不對應(yīng)列
@Enumerated:表示的是枚舉在數(shù)據(jù)庫中的映射使用下標(biāo)還是字符串
EnumType.STRING:表示的是以字符串的形式顯示
EnumType.ORDINAL:表示枚舉在數(shù)據(jù)中以下標(biāo)的形式顯示
@Lob:修飾String類型的時候 表示的大文本
修飾byte[]的時候表示存儲的是二進(jìn)制
復(fù)制一對一的問題
需求:一個人對應(yīng)了一個身份證、一個身份證也唯一對應(yīng)了一個人
身份證----->人
一對一的關(guān)系
代碼演示:
聲明IdCard類:
@Entity
@Table
public class IdCard {
@Id
private String cardNum;
private Date startTime;
private Date endTime;
//一個身份證唯一的對應(yīng)了一個人
@OneToOne(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
@JoinColumn(name="pId") //這個表示的是添加一個列 這個列映射下面對象中的這個Id
private People people;
}
復(fù)制聲明People類:
@Entity
@Table
public class People {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int pId;
private String pName;
private String pTel;
//一個人對應(yīng)了一個身份證
//在關(guān)聯(lián)關(guān)系中 配置了mappedBy的哪一方?jīng)]有權(quán)限維護(hù)另外一方
//mappedBy的值就是當(dāng)前的類在下面對象中聲明的這個名字
@OneToOne(mappedBy="people",cascade=CascadeType.ALL)
private IdCard idCard;
}
復(fù)制測試:
@Test
public void testHelloWorld() throws Exception {
EntityManager entityManager=JPAUtils.getEntityManager();
IdCard idCard=new IdCard();
idCard.setCardNum("510...x");
idCard.setStartTime(new Date());
idCard.setEndTime(new Date());
People people=new People();
people.setpName("小羽");
people.setpTel("1234566");
idCard.setPeople(people);
entityManager.persist(idCard);
JPAUtils.close();
}
復(fù)制一對多的問題
需求:部門和員工的對應(yīng)
部門----->員工
一對多的關(guān)聯(lián)關(guān)系
代碼演示:
聲明部門對象:
@Entity
@Table
public class Dept {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int dId;
private String dName;
private String dDes;
//一個部門有多個員工
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY,mappedBy="dept")
private Set emps;
}
復(fù)制聲明員工對象:
@Entity
@Table
public class Employee {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int empId;
private String empName;
@ManyToOne(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
@JoinColumn(name="dId")
private Dept dept;
}
復(fù)制測試:
@Test
public void testOne2Many() throws Exception {
EntityManager entityManager=JPAUtils.getEntityManager();
Employee emp=new Employee();
emp.setEmpName("小娜");
Dept dept=new Dept();
dept.setdName("研發(fā)部");
dept.setdDes("專門搞開發(fā)的");
emp.setDept(dept);
entityManager.persist(emp);
JPAUtils.close();
}
復(fù)制多對多的問題
需求:一個學(xué)生可以被多個老師教,一個老師也可以教多個學(xué)生
學(xué)生----->老師 一對多
老師----->學(xué)生 一對多
老師和學(xué)生的最終關(guān)系 多對多的關(guān)聯(lián)關(guān)系
代碼演示:
編寫老師實(shí)體:
@Entity
@Table
public class Teacher {
@Id
private String tNum;
private String tName;
@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
@JoinTable(name="t_teacher_student",
joinColumns=@JoinColumn(name="tNum"), //映射的是當(dāng)前這個類的主鍵
inverseJoinColumns={@JoinColumn(name="stuNum")}) //映射的是對方表的主鍵
private Set students;
}
復(fù)制編寫學(xué)生實(shí)體:
@Entity
@Table
public class Student {
@Id
private int stuNum;
private String stuName;
private int age;
@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY,mappedBy="students")
private Set teachers;
}
復(fù)制測試:
@Test
public void testMany2Many() throws Exception {
EntityManager em=JPAUtils.getEntityManager();
Teacher teacher=new Teacher();
teacher.settName("小羽");
teacher.settNum("007");
Set students=new HashSet();
Student student=new Student();
student.setAge(18);
student.setStuName("小白");
student.setStuNum(100);
Student student1=new Student();
student1.setAge(19);
student1.setStuName("小娜");
student1.setStuNum(1000);
Student student2=new Student();
student2.setAge(20);
student2.setStuName("小黑");
student2.setStuNum(10000);
students.add(student);
students.add(student1);
students.add(student2);
teacher.setStudents(students);
em.persist(teacher);
JPAUtils.close();
}
復(fù)制JPA中常見的方法
代碼演示:
常見方法:
public void testMethod() throws Exception {
EntityManager entityManager=JPAUtils.getEntityManager();
User user= new User();
user.setUserName("小灰");
user.setuId(1);
//添加數(shù)據(jù)的方法
// entityManager.persist(user);
//查詢數(shù)據(jù)
//User user2=entityManager.find(User.class,1);
//這個寫的是HQL語句
// Query query=entityManager.createQuery("from User");
// List list=query.getResultList();
//下面這個方法有主鍵值 那么就修改 沒有主鍵值 就插入
//entityManager.merge(user);
/*創(chuàng)建的是本地SQL的查詢
Query query=entityManager.createNativeQuery("select * from user");
List list=query.getResultList();*/
//一般用在查詢中 獲取最新的這個數(shù)據(jù)
// entityManager.refresh(user);
User user2=entityManager.find(User.class,1);
entityManager.remove(user2);
//System.out.println(list);
JPAUtils.close();
}
復(fù)制JPA中對象的狀態(tài)
對象的狀態(tài):
新建狀態(tài): User user = new User();和數(shù)據(jù)庫以及內(nèi)存沒有任何關(guān)聯(lián),對象僅僅是被new出來之后的這種狀態(tài)
托管狀態(tài): 對象調(diào)用了find persist refresh merge或者查詢之后的這個對象狀態(tài)就叫做托管狀態(tài),托管狀態(tài)的數(shù)據(jù)是被entityManager管理的,并且內(nèi)存和數(shù)據(jù)庫的數(shù)據(jù)是對應(yīng)了,這個時候如果你改變了內(nèi)存的這個數(shù)據(jù)的話,并且進(jìn)行提交的話,那么這個數(shù)據(jù)會和數(shù)據(jù)庫進(jìn)行同步
游離狀態(tài): 當(dāng)前的對象調(diào)用了clear方法之后在close方法之前的這段時間,這個對象處于游離狀態(tài)。clear:表示的是清楚內(nèi)存和數(shù)據(jù)庫數(shù)據(jù)的對應(yīng)的關(guān)系
刪除狀態(tài): 當(dāng)前對象close之后的對象的這種狀態(tài),就稱為刪除狀態(tài)
注意事項
表名不寫默認(rèn)就是類作為表名
column不寫,表的列名就是類的屬性名
@GeneratedValue后面值不寫默認(rèn)是auto
感謝各位的閱讀,以上就是“理解java持久化API”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對理解java持久化API這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。