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