溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

理解java持久化API

發(fā)布時間:2021-10-13 11:36:25 來源:億速云 閱讀:106 作者:iii 欄目:編程語言

這篇文章主要講解了“理解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

理解java持久化API

  需求:假設(shè)現(xiàn)在的產(chǎn)品的1.0版本的DAO的實(shí)現(xiàn)使用的是Hibernate、現(xiàn)在老板要求將DAO層換成TopLink

理解java持久化API

  按照現(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)注!

向AI問一下細(xì)節(jié)

免責(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)容。

AI