但是我偶然发现了另一个问题。 如何链接对象和数据库。 对象中的数据与关系数据库中的数据存储方式不同。 关系数据库不支持许多对我们的对象模型至关重要的OOP概念。 因此,我想到了酿造自己的类,以将数据从数据库传输到对象,然后再传输回来。 但是我面临很多困难和绊脚石。 然后休息了! 我遇到了Java Persistence的东西,这些东西使我可以在程序的生命周期之外保留或保存对象的数据。 这意味着,您现在可以将对象存储到关系数据库或XML文件等数据存储中,而无需编写复杂的代码来转换格式和管理CRUD操作。
这篇小文章将向您介绍这个很棒的功能,并且您将可以开始在项目中实现Persistence。 我不想在本文中涉及复杂的主题。 因此,我决定使用ObjectDB数据库。 使用ObjectDB的优点是,它不需要JPA通常需要的复杂配置和映射文件。 我们将使用流行的Eclipse IDE 。 我将提供一个简单的示例程序,该程序将存储和处理Employee详细信息(名称和薪水)。 好吧,让我们开始吧…………!
持久性服务由许多提供程序提供,我们将使用ObjectDB的实现。 因此,请下载其DB和API文件 。 现在让我们通过一些基础知识。 然后,我们将看到如何实现这些以创建程序……
一,实体类:
要使用持久性,您需要将其对象存储在数据库中的类。 这些类称为实体类,除了一些额外的注释外,它们与POJO(普通的旧Java对象)相同。 您需要定义此类中必须保留的字段(保存在db中)。 实体类必须在类上方具有“ @Entity ”注释。 现在定义该类的所有字段和方法。 瞧,我们为自己准备了实体课! 现在,您可以向实体类添加其他功能。 例如,您可以使用该字段上方的“ @Id ”注释来指示哪个字段用作主键。 您还可以使用“ @GeneratedValue(strategy = GenerationType.AUTO) ”批注使ObjectDB为持久存入数据库的对象生成主键值。 还有更多注释,功能和构造。 但是我们现在不需要了解它们。 这是我们将用作实体类的类。
package employeeDB;import javax.persistence.*;@Entity
publicclass Employee {@Id String name;Double salary;public Employee(){}public Employee (String name, Double Salary){this.name=name;this.salary=Salary;}publicvoid setSalary(Double Salary){this.salary=Salary;}publicString toString(){return"Name: "+name+"\nSalary: "+salary ;}}
如您所见,我们通过@Entity注释标识了Entity类。 然后,将员工姓名作为主键。 并且您需要在实体类中有一个不带参数的默认构造函数。
在其他JPA实现中,您可能必须在单独的XML文件中提供有关实体类的详细信息。 但是ObjectDB不需要这样做。
二。 连接到数据库
在JPA中,数据库连接由EntityManager接口表示。 为了访问和使用ObjectDB数据库,我们需要一个EntityManager实例。 我们可以使用EntityManagerFactory实例获得EntityManager的实例,该实例是使用EntityManagerFactory类的静态createEntityManagerFactory方法创建的。 您需要指定数据库文件的存储位置,作为createEntityManagerFactory方法的参数。 例:
EntityManagerFactory emf=Persistence.createEntityManagerFactory("empDB.odb");
EntityManager em=emf.createEntityManager();
现在我们有了一个EntityManager,它将我们的应用程序连接到数据库。 通常,在一个程序中创建几个EntityManager,但是仅创建一个EntityManagerfactory实例。 大多数JPA实现都需要称为“持久性单元”的XML映射文件作为创建EntityManagerFactory实例的参数。 但是ObjectDB具有仅接受数据库位置的规定。 如果数据库已经存在,它将被打开,否则将为我们创建一个新的数据库。
可以如下关闭EntityManagerFactory和EntityManager,
em.close();
emf.close();
对于每个类(负责某些数据库活动)或在多线程应用程序的情况下,每个线程都有一个单独的EntityManager是一个好习惯。 现在让我们看看如何使用数据库进行交易…。
三, 执行交易
为了对数据库执行任何操作或对数据库执行任何操作,我们必须首先启动事务。 只有使用EntityManager启动事务后,才能执行任何操作。 我们可以使用以下电话开始交易。
em.getTransaction().begin();
现在,我们可以执行各种事务,例如创建新的Record(对象),从数据库中删除,更新和检索数据。 在执行任何CRUD操作之前,我们需要将数据添加到数据库中。 在JPA中,将对象插入数据库称为“持久”对象。 可以使用em.persist(Object)方法执行此操作。 现在,此对象变为“托管”对象,但变为EntityManager(em)。 这意味着对该对象所做的任何更改都将反映在数据库文件的副本中。 要从数据库中删除任何对象,我们可以使用em.remove(Object)方法。 我们可以使用em.find(Class,primaryKeyValue)方法使用对象的主键从数据库中检索对象。 您需要将Entity类的Class实例和主键传递给此方法,它将返回一个“ Object”,该对象必须转换为Entity Class。 最后,执行交易后,我们必须使用结束交易,
em.getTransaction().commit();
只有在提交事务后,对内存中对象的更改才会反映在数据库文件中的对象上。 以下代码将持久存储一个Employee对象,然后搜索一个Employee对象并对其进行修改。
Employee emp1=new Employee ("Gugan",50000);em.getTransaction().begin();//Persist (store) emp1 object into Database
em.persist(emp1);//Search for Gugan
Employee gugan=(Employee) em.find(Employee.class,"Gugan");
gugan.setSalary(100000);em.getTransaction().commit();
我们还可以使用SQL之类的查询(称为JPQL)来执行CRUD操作。
JPA中有两种查询类型。 普通查询和TypedQueries。 普通查询是非类型安全查询。 (即)查询不知道将要检索或使用的对象的类型。 但是TypedQuery是类型安全的查询。 为了创建类型化查询,您需要指定将要使用的类的类型,并将类的Class实例作为参数以及查询字符串传递。 TypedQueries是使用数据库的标准方法,因此我们将仅使用它们。 可以使用以下语法创建它们,
TypedQuery q=em.createQuery(queryString,EntityClass.class);
如果查询仅返回一个对象或结果,例如查找条目数(计数),则可以使用q.getSingleResult()方法。 另一方面,如果您的查询将返回对象的集合,例如从数据库中检索雇员列表,则可以使用q.getResultList()方法,它将返回创建时指定类型的List对象。 TypedQuery。 下面的代码首先将找到那里有多少雇员,然后将从数据库中检索所有雇员对象。
em.getTransaction().begin();//find number of Employees
TypedQuery count=em.createQuery("Select count(emp) from Employee emp",Employee.class);
System.out.println("\n"+count.getSingleResult()+" employee record(s) Available in Database!\n");//Retrieve All Employee Objects in the database
TypedQuery e=em.createQuery("Select emp from Employee emp", Employee.class);
List employees=e.getResultList();em.getTransaction().commit();
JPQL与SQL查询非常相似。 唯一的区别是您使用类名和对象名而不是表名。 JPQL还支持查询中的参数。 例如。 如果要查找名称为“ Steve”的Employee,并且仅在运行时知道名称“ Steve”,则可以使用以下查询样式。
String name=scannerObj.nextLine();
TypedQuery<employee> query = em.createQuery("SELECT e FROM Employee e WHERE e.name = :name", Employee.class);
query.setParameter("name", name);
Employee emp=query.getSingleResult();
这用给定的“ name”变量替换“:name”参数。 除了这些查询外,还有许多其他查询。 有关JPQL的完整教程,您可以阅读有关JPQL的ObjectDB手册 。
IV。 使用Eclipse进行ObjectDB JPA实现
Eclipse是Java AFAIK的最佳IDE。 因此,我建议使用Eclipse开发应用程序。 从此处下载最新的Eclipse Indigo。 如果您已经拥有Eclipse Indigo或更旧的版本,那么它就很好了。 使用文件菜单创建一个新的Java项目。 然后在新的项目对话框中,为您的项目输入一个项目名称,然后选择要在其中存储项目的目录,然后选择下一步。 按下一步后,将为您提供几个选项,现在在此窗口中选择库选项卡。 然后选择“添加外部罐子”按钮,这将打开一个新对话框。 现在浏览到您提取ObjectDB API文件的位置,然后转到其中的bin文件夹并选择“ objectdb.jar”文件。 按打开,将添加库。 现在按完成以创建您的项目。
现在我们已经创建了项目,我们需要向其添加类。 现在,在Eclipse IDE窗口左侧的Project Explorer窗格中,右键单击您的项目名称,然后选择New-> Class。 现在将打开“新类”对话框。 在其中,输入要创建的类名称,然后也输入包名称。 所有其他选项都不必干预……! 在示例程序中,我们将使用两个类。 一个用于雇员实体,另一个用于容纳应用程序的主要方法和关键功能。 确保两个类都在同一个程序包中。 要查看创建的类,请在“项目资源管理器”窗格中展开您的“项目”,然后从节点列表中展开src,然后您将在其中看到您的包。 展开它,您将看到这些类。
五,范例程序
既然您已经掌握了JPA的基本概念,那么我将介绍一个示例控制台应用程序,该应用程序将从数据库中存储,修改和删除员工。如果您已阅读上述内容,则可以轻松地遵循以下程序。 我在需要使程序更清晰的地方提供了注释。
使用上一节中告诉您的方法创建一个名为Employee的类,并使用employeeDB作为包名,并粘贴本教程第一节中给出的Employee Entity类的代码。
现在,在同一软件包employeeDB下创建另一个名为Main的类,并将以下代码放入其中。
package employeeDB;import javax.persistence.*;
import java.util.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;public class Main {/*** Displays all Employees in the Database*/private static void displayAll(){em.getTransaction().begin();TypedQuery e=em.createQuery(displayAllQuery, Employee.class);List <Employee> employees=e.getResultList();if(employees.size()>0){for(Employee temp:employees){System.out.println(temp);System.out.println();}System.out.println(employees.size()+" Employee Records Available...!");}elseSystem.out.println("Database is Empty!");em.getTransaction().commit();}/*** Insets an Employee into the Database.*/private static void insert(){System.out.print("Enter the number of Employees to be inserted: ");n=input.nextInt();em.getTransaction().begin();for(int i=0;i<n;i++){ System.out.println("Enter the details of Employee "+(i+1)+": ");System.out.print("Name: ");//I use BufferedReader to read String and hence I need to // Catch the IOException that it may throwtry{name=bufferedReader.readLine();}catch (IOException e){e.printStackTrace();}System.out.print("Salary: ");Salary=input.nextDouble();Employee emp=new Employee(name,Salary);em.persist(emp); //Store emp into Database}em.getTransaction().commit();System.out.println("\n"+n+" employee record(s) Created!\n");TypedQuery count=em.createQuery(countQuery,Employee.class);System.out.println("\n"+count.getSingleResult()+" employee record(s) Available in Database!\n");}/*** Deletes the specified Employee from the database*@param name*/private static void delete(String name){em.getTransaction().begin();Employee e=(Employee) em.find(Employee.class, name); //Find Object to be deletedem.remove(e); //Delete the Employee from databaseSystem.out.printf("Employee %s removed from Database....",e.name);em.getTransaction().commit();//Display Number of Employees leftTypedQuery count=em.createQuery(countQuery,Employee.class);System.out.println("\n"+count.getSingleResult()+" employee record(s) Available in Database!\n");}/*** Changes salary of the specified employee to passed salary*@param name*@param Salary*/private static void modify(String name,Double Salary){em.getTransaction().begin();Employee e=(Employee) em.find(Employee.class, name); //Find Employee to be modifiede.setSalary(Salary); //Modify the salaryem.getTransaction().commit();System.out.println("Modification Successful!\n");}public static void main(String arg[]){System.out.println("Welcome to the Employee Database System!\n\n");do{ System.out.print("Menu: \n 1. View DB\n2. Insert \n3. Delete \n4. Modify\n5. Exit\nEnter Choice...");int ch=input.nextInt();try{switch(ch){case 1:displayAll();break;case 2:insert();break;case 3:System.out.print("Name of Employee to be Deleted2: ");name=bufferedReader.readLine();delete(name);break;case 4:System.out.print("Name of Employee to be Modified: ");name=bufferedReader.readLine();System.out.print("New Salary: ");Salary=input.nextDouble();modify(name,Salary);break;case 5:if(em!=null) em.close(); //Close EntityManagerif(emf!=null) emf.close(); //Close EntityManagerFactoryexit=true;break;}}catch (IOException e){e.printStackTrace();}}while(!exit);}static EntityManagerFactory emf=Persistence.createEntityManagerFactory("empDB.odb");static EntityManager em=emf.createEntityManager();static Scanner input=new Scanner(System.in);static BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));static int n;static String name;static Double Salary;static boolean exit=false;//Query Repositorystatic String countQuery="Select count(emp) from Employee emp";static String displayAllQuery="Select emp from Employee emp";}
现在保存您的项目,然后按运行按钮或按Ctrl + F11。 现在该程序应该运行了,您可以在底部窗格的“控制台”部分中看到输出。 这只是一个控制台应用程序。 我鼓励您为此开发一个GUI!
VI。 ObjectDB资源管理器工具
在结束之前,我想向您介绍ObjectDB提供的一个非常有用的工具。 它称为ObjectDB Explorer,可用于查看数据库文件包含的内容。 (即)您可以浏览数据库而无需编写代码来访问它。 这对于了解您的应用程序和进行调试非常有用。 您可以在Object DB的bin目录(您在其中提取ObjectDB文件)中找到资源管理器。 运行explorer.exe。 现在,您可以使用File-> Open Local选项打开数据库。 当您访问服务器中存储的数据库时,将完成“打开远程”。 现在浏览并选择数据库并打开它。 现在,双击左侧“持久性支持的类”窗格中显示的数据库。 现在,对象浏览器将显示您的数据库。 您可以展开数据库中的每个对象以查看其内容。 相当整洁吧?
以下是插入后我的数据库的样子……
该资源管理器还提供了许多其他选项。 随意探索它们!
我想您会对JPA有一个生动的想法。 我已经解释了使用ObjectDB实现的JPA的基本知识。 为了了解更多信息并增加知识,您可以参考ObjectDB手册 ,该手册提供了有关带有ObjectDB的JPA的详尽详尽的文本。 这是Java真正有用的功能,将对您有很大帮助。 对我有很大帮助! 因此,尝试更多地了解它。
您可以从此处下载源代码
参考: Java持久性API:一个快速的介绍......从我们JCG伙伴史蒂夫·罗宾逊在褴褛“N”科技博客。
- GWT 2 Spring 3 JPA 2 Hibernate 3.5教程
- JBoss 4.2.x Spring 3 JPA Hibernate教程
- DataNucleus 3.0与Hibernate 3.5
- Spring和AspectJ的领域驱动设计
- 提升您的休眠引擎
- 依赖注入–手动方式
翻译自: https://www.javacodegeeks.com/2011/08/java-persistence-api-quick-intro.html